[openssl] master update

Richard Levitte levitte at openssl.org
Fri Nov 13 08:22:06 UTC 2020


The branch master has been updated
       via  31a6b52f6db009c639c67387a707dd235f29a430 (commit)
      from  0bb450fe2fa9597ce8206cdd8177c5bd9aa15786 (commit)


- Log -----------------------------------------------------------------
commit 31a6b52f6db009c639c67387a707dd235f29a430
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Sep 25 20:02:56 2020 +0200

    EVP: Adapt EVP_PKEY2PKCS8() to better handle provider-native keys
    
    It doesn't downgread the keys to legacy any more.  Instead, it uses
    OSSL_ENCODER to encode the key to DER, and d2i_PKCS8_PRIV_KEY_INFO()
    to make a PKCS8_PRIV_KEY_INFO structure from that.
    
    Fixes #12990
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12995)

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

Summary of changes:
 crypto/evp/evp_pkey.c | 70 +++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 51 insertions(+), 19 deletions(-)

diff --git a/crypto/evp/evp_pkey.c b/crypto/evp/evp_pkey.c
index b5a8f1cd72..766dfb46ec 100644
--- a/crypto/evp/evp_pkey.c
+++ b/crypto/evp/evp_pkey.c
@@ -12,6 +12,8 @@
 #include "internal/cryptlib.h"
 #include <openssl/x509.h>
 #include <openssl/rand.h>
+#include <openssl/encoder.h>
+#include "internal/provider.h"
 #include "crypto/asn1.h"
 #include "crypto/evp.h"
 #include "crypto/x509.h"
@@ -69,35 +71,65 @@ EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8)
 
 PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey)
 {
-    PKCS8_PRIV_KEY_INFO *p8 = PKCS8_PRIV_KEY_INFO_new();
-    if (p8  == NULL) {
-        EVPerr(EVP_F_EVP_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
-        return NULL;
-    }
+    PKCS8_PRIV_KEY_INFO *p8 = NULL;
+    OSSL_ENCODER_CTX *ctx = NULL;
+
+    /*
+     * The implementation for provider-native keys is to encode the
+     * key to a DER encoded PKCS#8 structure, then convert it to a
+     * PKCS8_PRIV_KEY_INFO with good old d2i functions.
+     */
+    if (evp_pkey_is_provided(pkey)) {
+        int selection = OSSL_KEYMGMT_SELECT_ALL;
+        const OSSL_PROVIDER *prov = EVP_KEYMGMT_provider(pkey->keymgmt);
+        OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov);
+        unsigned char *der = NULL;
+        size_t derlen = 0;
+        const unsigned char *pp;
+
+        if ((ctx = OSSL_ENCODER_CTX_new_by_EVP_PKEY(pkey, selection,
+                                                    "DER", "pkcs8",
+                                                    libctx, NULL)) == NULL
+            || !OSSL_ENCODER_to_data(ctx, &der, &derlen))
+            goto error;
 
-    /* Force a key downgrade if that's possible */
-    /* TODO(3.0) Is there a better way for provider-native keys? */
-    if (EVP_PKEY_get0(pkey) == NULL)
-        goto error;
+        pp = der;
+        p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &pp, (long)derlen);
+        OPENSSL_free(der);
+        if (p8 == NULL)
+            goto error;
+    } else {
+        p8 = PKCS8_PRIV_KEY_INFO_new();
+        if (p8  == NULL) {
+            EVPerr(EVP_F_EVP_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
 
-    if (pkey->ameth) {
-        if (pkey->ameth->priv_encode) {
-            if (!pkey->ameth->priv_encode(p8, pkey)) {
-                EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_PRIVATE_KEY_ENCODE_ERROR);
+        if (pkey->ameth != NULL) {
+            if (pkey->ameth->priv_encode != NULL) {
+                if (!pkey->ameth->priv_encode(p8, pkey)) {
+                    EVPerr(EVP_F_EVP_PKEY2PKCS8,
+                           EVP_R_PRIVATE_KEY_ENCODE_ERROR);
+                    goto error;
+                }
+            } else {
+                EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_METHOD_NOT_SUPPORTED);
                 goto error;
             }
         } else {
-            EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_METHOD_NOT_SUPPORTED);
+            EVPerr(EVP_F_EVP_PKEY2PKCS8,
+                   EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
             goto error;
         }
-    } else {
-        EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
-        goto error;
     }
-    return p8;
+    goto end;
  error:
     PKCS8_PRIV_KEY_INFO_free(p8);
-    return NULL;
+    p8 = NULL;
+ end:
+    OSSL_ENCODER_CTX_free(ctx);
+    return p8;
+
 }
 
 /* EVP_PKEY attribute functions */


More information about the openssl-commits mailing list