diff options
author | Tomas Mraz <tomas@openssl.org> | 2021-03-23 16:40:53 +0100 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-03-25 15:24:00 +0100 |
commit | 4f0831b837e97504d4cfbfecfca069c527be4a2b (patch) | |
tree | 90411cdb7d183a26a30e84f5f5b94add560f7e39 /crypto/evp/evp_pkey.c | |
parent | 468d9d556409a53da2c5d16961f9531dd10a6e1b (diff) |
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@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14659)
Diffstat (limited to 'crypto/evp/evp_pkey.c')
-rw-r--r-- | crypto/evp/evp_pkey.c | 33 |
1 files changed, 31 insertions, 2 deletions
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); |