When calling the import_to function pass the libctx too

Previously import_to just took an EVP_PKEY as the argument. However we
need to some additional context data as well - specifically the libctx.
Therefore we pass an EVP_PKEY_CTX instead to hold the combination of
both of these things.

Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/11536)
This commit is contained in:
Matt Caswell 2020-04-10 18:28:24 +01:00
parent 7da7b27eec
commit 629c72db5f
6 changed files with 55 additions and 36 deletions

View File

@ -548,10 +548,11 @@ err:
return rv;
}
static int dh_pkey_import_from(const OSSL_PARAM params[], void *key)
static int dh_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
{
EVP_PKEY *pkey = key;
DH *dh = DH_new();
EVP_PKEY_CTX *pctx = vpctx;
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
DH *dh = dh_new_with_libctx(pctx->libctx);
if (dh == NULL) {
ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);

View File

@ -576,10 +576,11 @@ err:
return rv;
}
static int dsa_pkey_import_from(const OSSL_PARAM params[], void *key)
static int dsa_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
{
EVP_PKEY *pkey = key;
DSA *dsa = DSA_new();
EVP_PKEY_CTX *pctx = vpctx;
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
DSA *dsa = dsa_new_with_ctx(pctx->libctx);
if (dsa == NULL) {
ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE);

View File

@ -758,10 +758,11 @@ int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
return rv;
}
static int ec_pkey_import_from(const OSSL_PARAM params[], void *key)
static int ec_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
{
EVP_PKEY *pkey = key;
EC_KEY *ec = EC_KEY_new();
EVP_PKEY_CTX *pctx = vpctx;
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
EC_KEY *ec = EC_KEY_new_ex(pctx->libctx);
if (ec == NULL) {
ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);

View File

@ -450,10 +450,11 @@ static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
return rv;
}
static int ecx_generic_import_from(const OSSL_PARAM params[], void *key,
static int ecx_generic_import_from(const OSSL_PARAM params[], void *vpctx,
int keytype)
{
EVP_PKEY *pkey = key;
EVP_PKEY_CTX *pctx = vpctx;
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
ECX_KEY *ecx = ecx_key_new(KEYNID2TYPE(keytype), 0);
if (ecx == NULL) {
@ -469,9 +470,9 @@ static int ecx_generic_import_from(const OSSL_PARAM params[], void *key,
return 1;
}
static int x25519_import_from(const OSSL_PARAM params[], void *key)
static int x25519_import_from(const OSSL_PARAM params[], void *vpctx)
{
return ecx_generic_import_from(params, key, EVP_PKEY_X25519);
return ecx_generic_import_from(params, vpctx, EVP_PKEY_X25519);
}
const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
@ -522,9 +523,9 @@ const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
ecx_priv_decode_with_libctx
};
static int x448_import_from(const OSSL_PARAM params[], void *key)
static int x448_import_from(const OSSL_PARAM params[], void *vpctx)
{
return ecx_generic_import_from(params, key, EVP_PKEY_X448);
return ecx_generic_import_from(params, vpctx, EVP_PKEY_X448);
}
const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
@ -647,9 +648,9 @@ static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
return 1;
}
static int ed25519_import_from(const OSSL_PARAM params[], void *key)
static int ed25519_import_from(const OSSL_PARAM params[], void *vpctx)
{
return ecx_generic_import_from(params, key, EVP_PKEY_ED25519);
return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED25519);
}
const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
@ -699,9 +700,9 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
ecx_priv_decode_with_libctx
};
static int ed448_import_from(const OSSL_PARAM params[], void *key)
static int ed448_import_from(const OSSL_PARAM params[], void *vpctx)
{
return ecx_generic_import_from(params, key, EVP_PKEY_ED448);
return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED448);
}
const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {

View File

@ -1568,24 +1568,38 @@ int evp_pkey_downgrade(EVP_PKEY *pk)
if (pk->ameth->import_from == NULL) {
ERR_raise_data(ERR_LIB_EVP, EVP_R_NO_IMPORT_FUNCTION,
"key type = %s", keytype);
} else if (evp_keymgmt_export(keymgmt, keydata,
OSSL_KEYMGMT_SELECT_ALL,
pk->ameth->import_from, pk)) {
} else {
/*
* Save the provider side data in the operation cache, so they'll
* find it again. evp_pkey_free_it() cleared the cache, so it's
* safe to assume slot zero is free.
* Note that evp_keymgmt_util_cache_keydata() increments keymgmt's
* reference count.
* We perform the export in the same libctx as the keymgmt that we
* are using.
*/
evp_keymgmt_util_cache_keydata(pk, 0, keymgmt, keydata);
OPENSSL_CTX *libctx = ossl_provider_library_context(keymgmt->prov);
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pk, NULL);
if (pctx == NULL)
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
/* Synchronize the dirty count */
pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);
if (pctx != NULL
&& evp_keymgmt_export(keymgmt, keydata,
OSSL_KEYMGMT_SELECT_ALL,
pk->ameth->import_from, pctx)) {
/*
* Save the provider side data in the operation cache, so they'll
* find it again. evp_pkey_free_it() cleared the cache, so it's
* safe to assume slot zero is free.
* Note that evp_keymgmt_util_cache_keydata() increments keymgmt's
* reference count.
*/
evp_keymgmt_util_cache_keydata(pk, 0, keymgmt, keydata);
EVP_PKEY_CTX_free(pctx);
/* evp_keymgmt_export() increased the refcount... */
EVP_KEYMGMT_free(keymgmt);
return 1;
/* Synchronize the dirty count */
pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);
/* evp_keymgmt_export() increased the refcount... */
EVP_KEYMGMT_free(keymgmt);
return 1;
}
EVP_PKEY_CTX_free(pctx);
}
ERR_raise_data(ERR_LIB_EVP, EVP_R_KEYMGMT_EXPORT_FAILURE,

View File

@ -1180,10 +1180,11 @@ static int rsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
return rv;
}
static int rsa_pkey_import_from(const OSSL_PARAM params[], void *key)
static int rsa_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
{
EVP_PKEY *pkey = key;
RSA *rsa = RSA_new();
EVP_PKEY_CTX *pctx = vpctx;
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
RSA *rsa = rsa_new_with_ctx(pctx->libctx);
if (rsa == NULL) {
ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);