-
Notifications
You must be signed in to change notification settings - Fork 186
Description
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 interfacesEVP_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_DEPRECATEDflag - 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_get0to access EC_KEY - All functions that use
EVP_PKEY_assignto 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 relatedpkey_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 ... */
#endif4. 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 implementationsgost_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_assignandEVP_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_assigncalls moved to legacy modules - All
EVP_PKEY_get0calls 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_DEPRECATEDandGOST_ENABLE_LEGACY=OFF