[openssl] master update
beldmit at gmail.com
beldmit at gmail.com
Tue Feb 23 08:28:00 UTC 2021
The branch master has been updated
via 444b25b1e96fa444ffe3a67671796cfc1b599735 (commit)
from f16f363a85baa6338744e20671c5a227844f2847 (commit)
- Log -----------------------------------------------------------------
commit 444b25b1e96fa444ffe3a67671796cfc1b599735
Author: Shane Lontis <shane.lontis at oracle.com>
Date: Mon Feb 22 13:03:21 2021 +1000
Add back in legacy paths for d2i_PrivateKey/d2i_AutoPrivateKey.
Fixes #14263
If the new decoder code fails, it now falls back to the old legacy code
and tries that also.
Tested manually using gost engine master.
Reviewed-by: Richard Levitte <levitte at openssl.org>
Reviewed-by: Paul Dale <pauli at openssl.org>
Reviewed-by: Dmitry Belyavskiy <beldmit at gmail.com>
(Merged from https://github.com/openssl/openssl/pull/14266)
-----------------------------------------------------------------------
Summary of changes:
crypto/asn1/d2i_pr.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 79 insertions(+), 5 deletions(-)
diff --git a/crypto/asn1/d2i_pr.c b/crypto/asn1/d2i_pr.c
index c657f0f3a7..4da5a0c9be 100644
--- a/crypto/asn1/d2i_pr.c
+++ b/crypto/asn1/d2i_pr.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -23,9 +23,9 @@
#include "crypto/evp.h"
#include "internal/asn1.h"
-EVP_PKEY *d2i_PrivateKey_ex(int keytype, EVP_PKEY **a, const unsigned char **pp,
- long length, OSSL_LIB_CTX *libctx,
- const char *propq)
+static EVP_PKEY *
+d2i_PrivateKey_decoder(int keytype, EVP_PKEY **a, const unsigned char **pp,
+ long length, OSSL_LIB_CTX *libctx, const char *propq)
{
OSSL_DECODER_CTX *dctx = NULL;
size_t len = length;
@@ -44,6 +44,8 @@ EVP_PKEY *d2i_PrivateKey_ex(int keytype, EVP_PKEY **a, const unsigned char **pp,
ppkey = a;
for (i = 0; i < (int)OSSL_NELEM(input_structures); ++i) {
+ const unsigned char *p = *pp;
+
dctx = OSSL_DECODER_CTX_new_for_pkey(ppkey, "DER",
input_structures[i], key_name,
EVP_PKEY_KEYPAIR, libctx, propq);
@@ -56,6 +58,7 @@ EVP_PKEY *d2i_PrivateKey_ex(int keytype, EVP_PKEY **a, const unsigned char **pp,
if (*ppkey != NULL
&& evp_keymgmt_util_has(*ppkey, OSSL_KEYMGMT_SELECT_PRIVATE_KEY))
return *ppkey;
+ *pp = p;
goto err;
}
}
@@ -132,12 +135,77 @@ EVP_PKEY *evp_privatekey_from_binary(int keytype, EVP_PKEY **a,
return NULL;
}
+EVP_PKEY *d2i_PrivateKey_ex(int keytype, EVP_PKEY **a, const unsigned char **pp,
+ long length, OSSL_LIB_CTX *libctx,
+ const char *propq)
+{
+ EVP_PKEY *ret;
+
+ ret = d2i_PrivateKey_decoder(keytype, a, pp, length, libctx, propq);
+ /* try the legacy path if the decoder failed */
+ if (ret == NULL)
+ ret = evp_privatekey_from_binary(keytype, a, pp, length, libctx, propq);
+ return ret;
+}
+
EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
long length)
{
return d2i_PrivateKey_ex(type, a, pp, length, NULL, NULL);
}
+static EVP_PKEY *d2i_AutoPrivateKey_legacy(EVP_PKEY **a,
+ const unsigned char **pp,
+ long length,
+ OSSL_LIB_CTX *libctx,
+ const char *propq)
+{
+ STACK_OF(ASN1_TYPE) *inkey;
+ const unsigned char *p;
+ int keytype;
+
+ p = *pp;
+ /*
+ * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by
+ * analyzing it we can determine the passed structure: this assumes the
+ * input is surrounded by an ASN1 SEQUENCE.
+ */
+ inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
+ p = *pp;
+ /*
+ * Since we only need to discern "traditional format" RSA and DSA keys we
+ * can just count the elements.
+ */
+ if (sk_ASN1_TYPE_num(inkey) == 6) {
+ keytype = EVP_PKEY_DSA;
+ } else if (sk_ASN1_TYPE_num(inkey) == 4) {
+ keytype = EVP_PKEY_EC;
+ } else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not
+ * traditional format */
+ PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
+ EVP_PKEY *ret;
+
+ sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
+ if (p8 == NULL) {
+ ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+ return NULL;
+ }
+ ret = EVP_PKCS82PKEY_ex(p8, libctx, propq);
+ PKCS8_PRIV_KEY_INFO_free(p8);
+ if (ret == NULL)
+ return NULL;
+ *pp = p;
+ if (a) {
+ *a = ret;
+ }
+ return ret;
+ } else {
+ keytype = EVP_PKEY_RSA;
+ }
+ sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
+ return evp_privatekey_from_binary(keytype, a, pp, length, libctx, propq);
+}
+
/*
* This works like d2i_PrivateKey() except it passes the keytype as
* EVP_PKEY_NONE, which then figures out the type during decoding.
@@ -146,7 +214,13 @@ EVP_PKEY *d2i_AutoPrivateKey_ex(EVP_PKEY **a, const unsigned char **pp,
long length, OSSL_LIB_CTX *libctx,
const char *propq)
{
- return d2i_PrivateKey_ex(EVP_PKEY_NONE, a, pp, length, libctx, propq);
+ EVP_PKEY *ret;
+
+ ret = d2i_PrivateKey_decoder(EVP_PKEY_NONE, a, pp, length, libctx, propq);
+ /* try the legacy path if the decoder failed */
+ if (ret == NULL)
+ ret = d2i_AutoPrivateKey_legacy(a, pp, length, libctx, propq);
+ return ret;
}
EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
More information about the openssl-commits
mailing list