Move all code using EVP_PKEY_assign and EVP_PKEY_get0 into legacy-only modules
Summary
Extract all functions using deprecated EVP_PKEY internal accessors (EVP_PKEY_assign, EVP_PKEY_get0) into separate legacy-only modules (gost_ameth_legacy.c, gost_pmeth_legacy.c) that are compiled only when GOST_ENABLE_LEGACY is enabled.
Problem Description
The current implementation uses deprecated OpenSSL EVP_PKEY internal accessors scattered throughout multiple files:
EVP_PKEY_assign(pkey, nid, key_data) - Directly assigns algorithm-specific key data to an EVP_PKEY without going through proper OpenSSL provider interfaces
EVP_PKEY_get0(pkey) - Directly retrieves raw algorithm-specific key data from EVP_PKEY, bypassing encapsulation
These functions are deprecated because they:
- Break encapsulation by exposing internal EVP_PKEY structure layout
- Are not available in OpenSSL builds with
OPENSSL_NO_DEPRECATED flag
- Prevent migration to provider-based EVP_PKEY implementations
- Create tight coupling to OpenSSL internal APIs
Current usage
These deprecated accessors are used in:
- gost_ameth.c - ASN1 method implementations
- gost_pmeth.c - PKEYmethod implementations for key generation, signing, MAC operations
Required Changes
1. Create gost_ameth_legacy.c
Move all functions from gost_ameth.c that call EVP_PKEY_assign or EVP_PKEY_get0:
Functions to extract:
- All ASN1 key encoding/decoding functions that use
EVP_PKEY_get0 to access EC_KEY
- All functions that use
EVP_PKEY_assign to set EC_KEY in pkey
File structure:
/*
* gost_ameth_legacy.c - Legacy ENGINE-based ASN1 methods
* Contains all ASN1 method implementations that depend on
* EVP_PKEY_assign and EVP_PKEY_get0.
* Only compiled when GOST_ENABLE_LEGACY is enabled.
*/
#include "gost_lcl.h"
#include "e_gost_err.h"
/* Legacy ASN1 implementations using EVP_PKEY internals */
static int gost_ameth_keybuf_to_priv_key(...)
{
EVP_PKEY *pkey = EVP_PKEY_new();
if (!pkey)
return 0;
/* Use EVP_PKEY_get0 / EVP_PKEY_assign here */
EC_KEY *ec = ECP_KEY_new();
/* ... */
if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec)) {
EC_KEY_free(ec);
EVP_PKEY_free(pkey);
return 0;
}
return 1;
}
/* ... other extracted functions ... */
2. Create gost_pmeth_legacy.c
Move all functions from gost_pmeth.c that call EVP_PKEY_assign or EVP_PKEY_get0:
Functions to extract:
pkey_gost2001_paramgen()
pkey_gost2012_paramgen()
pkey_gost2001cp_keygen()
pkey_gost2012cp_keygen()
pkey_gost_mac_keygen_base()
pkey_gost_mac_keygen_12()
pkey_gost_mac_keygen()
pkey_gost_magma_mac_keygen()
pkey_gost_grasshopper_mac_keygen()
pkey_gost_ec_cp_sign() and related
pkey_gost_ec_cp_verify() and related
File structure:
/*
* gost_pmeth_legacy.c - Legacy ENGINE-based PKEY methods
* Contains all EVP_PKEY_METHOD implementations that depend on
* EVP_PKEY_assign and EVP_PKEY_get0.
* Only compiled when GOST_ENABLE_LEGACY is enabled.
*/
#include "gost_lcl.h"
#include "e_gost_err.h"
/* Legacy paramgen implementations using EVP_PKEY internals */
static int pkey_gost2001_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
{
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
EC_KEY *ec = NULL;
if (!data || data->sign_param_nid == NID_undef) {
GOSTerr(GOST_F_PKEY_GOST2001_PARAMGEN, GOST_R_NO_PARAMETERS_SET);
return 0;
}
ec = internal_ec_paramgen(data->sign_param_nid);
if (!ec)
return 0;
if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec)) {
EC_KEY_free(ec);
return 0;
}
return 1;
}
/* ... other extracted functions ... */
/* Registration function called from main register_pmeth_gost */
int register_pmeth_gost_legacy(int id, EVP_PKEY_METHOD **pmeth, int flags)
{
/* Set up methods for legacy-only cases */
switch (id) {
case NID_id_GostR3410_2001:
EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost2001cp_keygen);
break;
case NID_id_GostR3410_2012_256:
EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost2012cp_keygen);
break;
/* ... */
}
return 1;
}
3. Update gost_ameth.c
Remove all functions that use EVP_PKEY_assign or EVP_PKEY_get0. Keep only the common infrastructure:
/* gost_ameth.c - ASN1 method implementations (provider-compatible) */
#include "gost_lcl.h"
#include "e_gost_err.h"
/* Common ASN1 infrastructure that doesn't depend on EVP_PKEY internals */
static int gost_ameth_foo() { ... }
/* Conditional inclusion of legacy implementations */
#ifdef GOST_ENABLE_LEGACY
#include "gost_ameth_legacy.c"
#endif
/* For provider-only builds, these return error */
#ifndef GOST_ENABLE_LEGACY
static int gost_ameth_keybuf_to_priv_key_stub(...)
{
GOSTerr(GOST_F_AMETH, GOST_R_LEGACY_DISABLED);
return 0;
}
/* ... other stubs ... */
#endif
4. Update gost_pmeth.c
Remove all functions that use EVP_PKEY_assign or EVP_PKEY_get0.
5. Update CMakeLists.txt or build system
Add conditional compilation:
# Legacy support (default: ON for backward compatibility)
option(GOST_ENABLE_LEGACY "Enable legacy ENGINE-based implementations" ON)
if(GOST_ENABLE_LEGACY)
target_sources(gost_engine PRIVATE
gost_ameth_legacy.c
gost_pmeth_legacy.c
)
target_compile_definitions(gost_engine PRIVATE GOST_ENABLE_LEGACY)
endif()
target_sources(gost_engine PRIVATE
gost_ameth.c
gost_pmeth.c
# ... other sources ...
)
Files to Create
gost_ameth_legacy.c - Legacy ASN1 method implementations
gost_pmeth_legacy.c - Legacy PKEY method implementations
Files to Modify
- gost_ameth.c - Remove legacy functions, keep common code
- gost_pmeth.c - Remove legacy functions, update registration to delegate to legacy module
- CMakeLists.txt or build system - Add conditional compilation
Compilation behavior
When GOST_ENABLE_LEGACY=ON (default):
- gost_ameth_legacy.c and gost_pmeth_legacy.c are compiled
- Full backward compatibility with existing ENGINE-based code
- Uses
EVP_PKEY_assign and EVP_PKEY_get0
When GOST_ENABLE_LEGACY is not set:
- gost_ameth_legacy.c and gost_pmeth_legacy.c are NOT compiled
- Legacy paramgen/keygen operations return error
- Compatible with OpenSSL builds with
OPENSSL_NO_DEPRECATED
- Provider-only mode (future work will implement provider interfaces)
Acceptance Criteria
- All
EVP_PKEY_assign calls moved to legacy modules
- All
EVP_PKEY_get0 calls moved to legacy modules
- Code compiles with
GOST_ENABLE_LEGACY=ON (default) - all tests pass
- Code compiles with
GOST_ENABLE_LEGACY=OFF - legacy operations fail gracefully with clear error
Testing
- Compile with
-DGOST_ENABLE_LEGACY=ON (default) - all tests pass
- Compile with
-DGOST_ENABLE_LEGACY=OFF - legacy operations fail with GOST_R_LEGACY_DISABLED
- Test with OpenSSL compiled with
OPENSSL_NO_DEPRECATED and GOST_ENABLE_LEGACY=OFF
Move all code using
EVP_PKEY_assignandEVP_PKEY_get0into legacy-only modulesSummary
Extract all functions using deprecated
EVP_PKEYinternal accessors (EVP_PKEY_assign,EVP_PKEY_get0) into separate legacy-only modules (gost_ameth_legacy.c,gost_pmeth_legacy.c) that are compiled only whenGOST_ENABLE_LEGACYis enabled.Problem Description
The current implementation uses deprecated OpenSSL EVP_PKEY internal accessors scattered throughout multiple files:
EVP_PKEY_assign(pkey, nid, key_data)- Directly assigns algorithm-specific key data to an EVP_PKEY without going through proper OpenSSL provider interfacesEVP_PKEY_get0(pkey)- Directly retrieves raw algorithm-specific key data from EVP_PKEY, bypassing encapsulationThese functions are deprecated because they:
OPENSSL_NO_DEPRECATEDflagCurrent usage
These deprecated accessors are used in:
Required Changes
1. Create gost_ameth_legacy.c
Move all functions from gost_ameth.c that call
EVP_PKEY_assignorEVP_PKEY_get0:Functions to extract:
EVP_PKEY_get0to access EC_KEYEVP_PKEY_assignto set EC_KEY in pkeyFile structure:
2. Create gost_pmeth_legacy.c
Move all functions from gost_pmeth.c that call
EVP_PKEY_assignorEVP_PKEY_get0:Functions to extract:
pkey_gost2001_paramgen()pkey_gost2012_paramgen()pkey_gost2001cp_keygen()pkey_gost2012cp_keygen()pkey_gost_mac_keygen_base()pkey_gost_mac_keygen_12()pkey_gost_mac_keygen()pkey_gost_magma_mac_keygen()pkey_gost_grasshopper_mac_keygen()pkey_gost_ec_cp_sign()and relatedpkey_gost_ec_cp_verify()and relatedFile structure:
3. Update gost_ameth.c
Remove all functions that use
EVP_PKEY_assignorEVP_PKEY_get0. Keep only the common infrastructure:4. Update gost_pmeth.c
Remove all functions that use
EVP_PKEY_assignorEVP_PKEY_get0.5. Update CMakeLists.txt or build system
Add conditional compilation:
Files to Create
gost_ameth_legacy.c- Legacy ASN1 method implementationsgost_pmeth_legacy.c- Legacy PKEY method implementationsFiles to Modify
Compilation behavior
When
GOST_ENABLE_LEGACY=ON(default):EVP_PKEY_assignandEVP_PKEY_get0When
GOST_ENABLE_LEGACYis not set:OPENSSL_NO_DEPRECATEDAcceptance Criteria
EVP_PKEY_assigncalls moved to legacy modulesEVP_PKEY_get0calls moved to legacy modulesGOST_ENABLE_LEGACY=ON(default) - all tests passGOST_ENABLE_LEGACY=OFF- legacy operations fail gracefully with clear errorTesting
-DGOST_ENABLE_LEGACY=ON(default) - all tests pass-DGOST_ENABLE_LEGACY=OFF- legacy operations fail with GOST_R_LEGACY_DISABLEDOPENSSL_NO_DEPRECATEDandGOST_ENABLE_LEGACY=OFF