Always create a key when importing
[openssl.git] / crypto / evp / keymgmt_lib.c
index 9ed176410a87e07b855e3ea59ff06eaaa03e34b1..68ed74b23a2e3797a9d9df35128b739875a612fa 100644 (file)
@@ -39,6 +39,13 @@ static int try_import(const OSSL_PARAM params[], void *arg)
 {
     struct import_data_st *data = arg;
 
+    /* Just in time creation of keydata */
+    if (data->keydata == NULL
+        && (data->keydata = evp_keymgmt_newdata(data->keymgmt)) == NULL) {
+        ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
     /*
      * It's fine if there was no data to transfer, we just end up with an
      * empty destination key.
@@ -46,13 +53,6 @@ static int try_import(const OSSL_PARAM params[], void *arg)
     if (params[0].key == NULL)
         return 1;
 
-    /* Just in time creation of keydata, if needed */
-    if (data->keydata == NULL
-        && (data->keydata = evp_keymgmt_newdata(data->keymgmt)) == NULL) {
-        ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-
     return evp_keymgmt_import(data->keymgmt, data->keydata, data->selection,
                               params);
 }
@@ -236,8 +236,8 @@ int evp_keymgmt_util_has(EVP_PKEY *pk, int selection)
  * but also in the operation cache to see if there's any common keymgmt that
  * supplies OP_keymgmt_match.
  *
- * evp_keymgmt_util_match() adheres to the return values that EVP_PKEY_cmp()
- * and EVP_PKEY_cmp_parameters() return, i.e.:
+ * evp_keymgmt_util_match() adheres to the return values that EVP_PKEY_eq()
+ * and EVP_PKEY_parameters_eq() return, i.e.:
  *
  *  1   same key
  *  0   not same key
@@ -346,10 +346,19 @@ int evp_keymgmt_util_copy(EVP_PKEY *to, EVP_PKEY *from, int selection)
     if (from == NULL || from->keydata == NULL)
         return 0;
 
+    /*
+     * If |to| is unassigned, ensure it gets the same KEYMGMT as |from|,
+     * Note that the final setting of KEYMGMT is done further down, with
+     * EVP_PKEY_set_type_by_keymgmt(); we don't want to do that prematurely.
+     */
+    if (to_keymgmt == NULL)
+        to_keymgmt = from->keymgmt;
+
     if (to_keymgmt == from->keymgmt && to_keymgmt->copy != NULL) {
         /* Make sure there's somewhere to copy to */
         if (to_keydata == NULL
-            && (to_keydata = evp_keymgmt_newdata(to_keymgmt)) == NULL) {
+            && ((to_keydata = alloc_keydata = evp_keymgmt_newdata(to_keymgmt))
+                == NULL)) {
             ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
             return 0;
         }
@@ -375,10 +384,11 @@ int evp_keymgmt_util_copy(EVP_PKEY *to, EVP_PKEY *from, int selection)
         }
 
         /*
-         * In this case to_keydata was previously unallocated, try_import()
+         * In case to_keydata was previously unallocated, try_import()
          * may have created it for us.
          */
-        to_keydata = import_data.keydata;
+        if (to_keydata == NULL)
+            to_keydata = alloc_keydata = import_data.keydata;
     } else {
         ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES);
         return 0;
@@ -432,25 +442,23 @@ int evp_keymgmt_util_get_deflt_digest_name(EVP_KEYMGMT *keymgmt,
     params[0] =
         OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST,
                                          mddefault, sizeof(mddefault));
-    params[0].return_size = sizeof(mddefault) + 1;
     params[1] =
         OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST,
                                          mdmandatory,
                                          sizeof(mdmandatory));
-    params[1].return_size = sizeof(mdmandatory) + 1;
     params[2] = OSSL_PARAM_construct_end();
 
     if (!evp_keymgmt_get_params(keymgmt, keydata, params))
         return 0;
 
-    if (params[1].return_size != sizeof(mdmandatory) + 1) {
-        if (params[1].return_size == 1) /* Only a NUL byte */
+    if (OSSL_PARAM_modified(params + 1)) {
+        if (params[1].return_size <= 1) /* Only a NUL byte */
             result = SN_undef;
         else
             result = mdmandatory;
         rv = 2;
-    } else if (params[0].return_size != sizeof(mddefault) + 1) {
-        if (params[0].return_size == 1) /* Only a NUL byte */
+    } else if (OSSL_PARAM_modified(params)) {
+        if (params[0].return_size <= 1) /* Only a NUL byte */
             result = SN_undef;
         else
             result = mddefault;