evp_keymgmt_export_to_provider(): adjust OSSL_PARAM array for transfer
authorRichard Levitte <levitte@openssl.org>
Wed, 16 Oct 2019 22:32:20 +0000 (00:32 +0200)
committerRichard Levitte <levitte@openssl.org>
Thu, 17 Oct 2019 16:07:45 +0000 (18:07 +0200)
It may be that the OSSL_PARAM array we used for getting parameter
values for a key had a few too many entries.  These are detected by
their return_size == 0.  Before making second export call, we prune
away these items so we only ask for parameters that exist.

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10190)

crypto/evp/keymgmt_lib.c

index 87629157e2df0435256169ed0b1a15822436c042..a14decd2803f79809813bc092234e32571f925c0 100644 (file)
@@ -37,6 +37,28 @@ static OSSL_PARAM *paramdefs_to_params(const OSSL_PARAM *paramdefs)
     return params;
 }
 
+static OSSL_PARAM *reduce_params(OSSL_PARAM *params)
+{
+    OSSL_PARAM *curr, *next;
+    size_t cnt;
+
+    for (cnt = 0, curr = next = params; next->key != NULL; next++) {
+        if (next->return_size == 0)
+            continue;
+        if (curr != next)
+            *curr = *next;
+        curr++;
+        cnt++;
+    }
+    *curr = *next;               /* Terminating record */
+    cnt++;
+
+    curr = OPENSSL_realloc(params, cnt * sizeof(*params));
+    if (curr == NULL)
+        return params;
+    return curr;
+}
+
 typedef union align_block_un {
     OSSL_UNION_ALIGN;
 } ALIGN_BLOCK;
@@ -157,10 +179,11 @@ void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
                 exportfn(pk->pkeys[j].provdata, params);
 
                 /*
-                 * Allocate space and assign 'data' to point into the
-                 * data block.
-                 * If something goes wrong, go to the next cached key.
+                 * Reduce the params by removing any entry that got return
+                 * size zero, then allocate space and assign 'data' to point
+                 * into the data block
                  */
+                params = reduce_params(params);
                 if ((data = allocate_params_space(params)) == NULL)
                     goto cont;