[openssl] master update

tomas at openssl.org tomas at openssl.org
Thu Mar 25 14:24:10 UTC 2021


The branch master has been updated
       via  4f0831b837e97504d4cfbfecfca069c527be4a2b (commit)
      from  468d9d556409a53da2c5d16961f9531dd10a6e1b (commit)


- Log -----------------------------------------------------------------
commit 4f0831b837e97504d4cfbfecfca069c527be4a2b
Author: Tomas Mraz <tomas at openssl.org>
Date:   Tue Mar 23 16:40:53 2021 +0100

    EVP_PKCS82PKEY: Create provided keys if possible
    
    Use OSSL_DECODER to decode the PKCS8 data to create provided keys.
    
    If that fails fallback to the legacy implementation.
    
    Fixes #14302
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14659)

-----------------------------------------------------------------------

Summary of changes:
 crypto/asn1/d2i_pr.c  |  4 ++--
 crypto/evp/evp_pkey.c | 33 +++++++++++++++++++++++++++++++--
 include/crypto/evp.h  |  2 ++
 test/endecode_test.c  |  2 ++
 4 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/crypto/asn1/d2i_pr.c b/crypto/asn1/d2i_pr.c
index 5d95c9e042..fb0ae08356 100644
--- a/crypto/asn1/d2i_pr.c
+++ b/crypto/asn1/d2i_pr.c
@@ -106,7 +106,7 @@ d2i_PrivateKey_legacy(int keytype, EVP_PKEY **a, const unsigned char **pp,
                 ERR_clear_last_mark();
                 goto err;
             }
-            tmp = EVP_PKCS82PKEY_ex(p8, libctx, propq);
+            tmp = evp_pkcs82pkey_legacy(p8, libctx, propq);
             PKCS8_PRIV_KEY_INFO_free(p8);
             if (tmp == NULL) {
                 ERR_clear_last_mark();
@@ -190,7 +190,7 @@ static EVP_PKEY *d2i_AutoPrivateKey_legacy(EVP_PKEY **a,
             ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
             return NULL;
         }
-        ret = EVP_PKCS82PKEY_ex(p8, libctx, propq);
+        ret = evp_pkcs82pkey_legacy(p8, libctx, propq);
         PKCS8_PRIV_KEY_INFO_free(p8);
         if (ret == NULL)
             return NULL;
diff --git a/crypto/evp/evp_pkey.c b/crypto/evp/evp_pkey.c
index 9879392114..7aafd76822 100644
--- a/crypto/evp/evp_pkey.c
+++ b/crypto/evp/evp_pkey.c
@@ -13,6 +13,7 @@
 #include <openssl/x509.h>
 #include <openssl/rand.h>
 #include <openssl/encoder.h>
+#include <openssl/decoder.h>
 #include "internal/provider.h"
 #include "crypto/asn1.h"
 #include "crypto/evp.h"
@@ -20,8 +21,8 @@
 
 /* Extract a private key from a PKCS8 structure */
 
-EVP_PKEY *EVP_PKCS82PKEY_ex(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx,
-                            const char *propq)
+EVP_PKEY *evp_pkcs82pkey_legacy(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx,
+                                const char *propq)
 {
     EVP_PKEY *pkey = NULL;
     const ASN1_OBJECT *algoid;
@@ -62,6 +63,34 @@ EVP_PKEY *EVP_PKCS82PKEY_ex(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx,
     return NULL;
 }
 
+EVP_PKEY *EVP_PKCS82PKEY_ex(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx,
+                            const char *propq)
+{
+    EVP_PKEY *pkey = NULL;
+    const unsigned char *p8_data = NULL;
+    unsigned char *encoded_data = NULL;
+    int encoded_len;
+    size_t len;
+    OSSL_DECODER_CTX *dctx = NULL;
+
+    if ((encoded_len = i2d_PKCS8_PRIV_KEY_INFO(p8, &encoded_data)) <= 0)
+        goto end;
+
+    p8_data = encoded_data;
+    len = encoded_len;
+    dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", "pkcs8", EVP_PKEY_NONE,
+                                         0, libctx, propq);
+    if (dctx == NULL
+        || !OSSL_DECODER_from_data(dctx, &p8_data, &len))
+        /* try legacy */
+        pkey = evp_pkcs82pkey_legacy(p8, libctx, propq);
+
+ end:
+    OPENSSL_clear_free(encoded_data, encoded_len);
+    OSSL_DECODER_CTX_free(dctx);
+    return pkey;
+}
+
 EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8)
 {
     return EVP_PKCS82PKEY_ex(p8, NULL, NULL);
diff --git a/include/crypto/evp.h b/include/crypto/evp.h
index 18c50cdd33..2089b8b913 100644
--- a/include/crypto/evp.h
+++ b/include/crypto/evp.h
@@ -727,6 +727,8 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx,
 int evp_pkey_copy_downgraded(EVP_PKEY **dest, const EVP_PKEY *src);
 void *evp_pkey_get_legacy(EVP_PKEY *pk);
 void evp_pkey_free_legacy(EVP_PKEY *x);
+EVP_PKEY *evp_pkcs82pkey_legacy(const PKCS8_PRIV_KEY_INFO *p8inf,
+                                OSSL_LIB_CTX *libctx, const char *propq);
 #endif
 
 /*
diff --git a/test/endecode_test.c b/test/endecode_test.c
index 50b33ce057..ab4b631a8f 100644
--- a/test/endecode_test.c
+++ b/test/endecode_test.c
@@ -21,6 +21,7 @@
 
 #include "internal/cryptlib.h"   /* ossl_assert */
 #include "crypto/pem.h"          /* For PVK and "blob" PEM headers */
+#include "crypto/evp.h"          /* For evp_pkey_is_provided() */
 
 #include "helpers/predefined_dhparams.h"
 #include "testutil.h"
@@ -498,6 +499,7 @@ static int check_unprotected_PKCS8_DER(const char *file, const int line,
                     TEST_note("%s isn't any of %s", type, namelist);
                 OPENSSL_free(namelist);
             }
+            ok = ok && TEST_FL_true(evp_pkey_is_provided(pkey));
             EVP_PKEY_free(pkey);
         }
     }


More information about the openssl-commits mailing list