When calling the import_to function pass the libctx too
authorMatt Caswell <matt@openssl.org>
Fri, 10 Apr 2020 17:28:24 +0000 (18:28 +0100)
committerMatt Caswell <matt@openssl.org>
Fri, 17 Apr 2020 11:26:56 +0000 (12:26 +0100)
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)

crypto/dh/dh_ameth.c
crypto/dsa/dsa_ameth.c
crypto/ec/ec_ameth.c
crypto/ec/ecx_meth.c
crypto/evp/p_lib.c
crypto/rsa/rsa_ameth.c

index 9c1fa03..ea92fc9 100644 (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);
index 81bb6d8..461186a 100644 (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);
index 3371224..545d251 100644 (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);
index ba037ff..4603902 100644 (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 = {
index b0163f5..fa16695 100644 (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);
-
-            /* 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;
+            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);
+
+            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);
+
+                /* 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,
index 720eb52..1c53437 100644 (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);