DECODER & ENCODER: Make sure to pass around the original selection bits
authorRichard Levitte <levitte@openssl.org>
Mon, 28 Jun 2021 03:52:42 +0000 (05:52 +0200)
committerRichard Levitte <levitte@openssl.org>
Tue, 29 Jun 2021 11:50:51 +0000 (13:50 +0200)
When decoding a key and asking the keymgmt to import the key data, it
was told that the key data includes everything.  This may not be true,
since the user may have specified a different selection, and some
keymgmts may want to be informed.

Our key decoders' export function, on the other hand, didn't care
either, and simply export anything they could, regardless.

In both cases, the selection that was specified by the user is now
passed all the way.

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15934)

crypto/encode_decode/decoder_pkey.c
providers/implementations/encode_decode/decode_der2key.c
providers/implementations/encode_decode/decode_msblob2key.c
providers/implementations/encode_decode/decode_pvk2key.c

index 0270ba2e70b051d1023b075113d4e3260f3904ab..719bd17b2ff67321733ff30aac3153d6347f758e 100644 (file)
@@ -57,6 +57,7 @@ DEFINE_STACK_OF(EVP_KEYMGMT)
 struct decoder_pkey_data_st {
     OSSL_LIB_CTX *libctx;
     char *propq;
+    int selection;
 
     STACK_OF(EVP_KEYMGMT) *keymgmts;
     char *object_type;           /* recorded object data type, may be NULL */
@@ -150,7 +151,7 @@ static int decoder_construct_pkey(OSSL_DECODER_INSTANCE *decoder_inst,
 
             import_data.keymgmt = keymgmt;
             import_data.keydata = NULL;
-            import_data.selection = OSSL_KEYMGMT_SELECT_ALL;
+            import_data.selection = data->selection;
 
             /*
              * No need to check for errors here, the value of
@@ -375,6 +376,7 @@ int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx,
 
     process_data->object = (void **)pkey;
     process_data->libctx = libctx;
+    process_data->selection = ctx->selection;
 
     /* First, find all keymgmts to form goals */
     EVP_KEYMGMT_do_all_provided(libctx, collect_keymgmt,
index fd4a7c6e2a778bb629a65c99481056888881c8e8..356e65b403a9c243d1b325d1f9fd9e11634d3a62 100644 (file)
@@ -89,6 +89,8 @@ struct keytype_desc_st {
 struct der2key_ctx_st {
     PROV_CTX *provctx;
     const struct keytype_desc_st *desc;
+    /* The selection that is passed to der2key_decode() */
+    int selection;
     /* Flag used to signal that a failure is fatal */
     unsigned int flag_fatal : 1;
 };
@@ -180,9 +182,9 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
     const unsigned char *derp;
     long der_len = 0;
     void *key = NULL;
-    int orig_selection = selection;
     int ok = 0;
 
+    ctx->selection = selection;
     /*
      * The caller is allowed to specify 0 as a selection mark, to have the
      * structure and key type guessed.  For type-specific structures, this
@@ -213,7 +215,7 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
         } else if (ctx->desc->d2i_private_key != NULL) {
             key = ctx->desc->d2i_private_key(NULL, &derp, der_len);
         }
-        if (key == NULL && orig_selection != 0)
+        if (key == NULL && ctx->selection != 0)
             goto next;
     }
     if (key == NULL && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
@@ -222,14 +224,14 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
             key = ctx->desc->d2i_PUBKEY(NULL, &derp, der_len);
         else
             key = ctx->desc->d2i_public_key(NULL, &derp, der_len);
-        if (key == NULL && orig_selection != 0)
+        if (key == NULL && ctx->selection != 0)
             goto next;
     }
     if (key == NULL && (selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) {
         derp = der;
         if (ctx->desc->d2i_key_params != NULL)
             key = ctx->desc->d2i_key_params(NULL, &derp, der_len);
-        if (key == NULL && orig_selection != 0)
+        if (key == NULL && ctx->selection != 0)
             goto next;
     }
 
@@ -304,8 +306,7 @@ static int der2key_export_object(void *vctx,
         /* The contents of the reference is the address to our object */
         keydata = *(void **)reference;
 
-        return export(keydata, OSSL_KEYMGMT_SELECT_ALL,
-                      export_cb, export_cbarg);
+        return export(keydata, ctx->selection, export_cb, export_cbarg);
     }
     return 0;
 }
index 15dc8b05a7c77b22771692b45130ae15ecd8ea69..0508e68b3287fb81ac31859614a5a61f0fd23be2 100644 (file)
@@ -56,6 +56,8 @@ static OSSL_FUNC_decoder_export_object_fn msblob2key_export_object;
 struct msblob2key_ctx_st {
     PROV_CTX *provctx;
     const struct keytype_desc_st *desc;
+    /* The selection that is passed to msblob2key_decode() */
+    int selection;
 };
 
 static struct msblob2key_ctx_st *
@@ -102,6 +104,7 @@ static int msblob2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
     if (!ok)
         goto next;
 
+    ctx->selection = selection;
     ok = 0;                      /* Assume that we fail */
 
     if ((isdss && ctx->desc->type != EVP_PKEY_DSA)
@@ -208,8 +211,7 @@ msblob2key_export_object(void *vctx,
         /* The contents of the reference is the address to our object */
         keydata = *(void **)reference;
 
-        return export(keydata, OSSL_KEYMGMT_SELECT_ALL,
-                      export_cb, export_cbarg);
+        return export(keydata, ctx->selection, export_cb, export_cbarg);
     }
     return 0;
 }
index 5c26bfb908224b300a38f756d5b8e9eb27118e0f..30b42d2097b3ae23de2bed9c27e107398f0ed293 100644 (file)
@@ -56,6 +56,8 @@ static OSSL_FUNC_decoder_export_object_fn pvk2key_export_object;
 struct pvk2key_ctx_st {
     PROV_CTX *provctx;
     const struct keytype_desc_st *desc;
+    /* The selection that is passed to der2key_decode() */
+    int selection;
 };
 
 static struct pvk2key_ctx_st *
@@ -86,6 +88,8 @@ static int pvk2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
     void *key = NULL;
     int ok = 0;
 
+    ctx->selection = selection;
+
     if ((selection == 0
          || (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
         && ctx->desc->read_private_key != NULL) {
@@ -175,8 +179,7 @@ static int pvk2key_export_object(void *vctx,
         /* The contents of the reference is the address to our object */
         keydata = *(void **)reference;
 
-        return export(keydata, OSSL_KEYMGMT_SELECT_ALL,
-                      export_cb, export_cbarg);
+        return export(keydata, ctx->selection, export_cb, export_cbarg);
     }
     return 0;
 }