X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fevp%2Fevp_pkey.c;h=8f3f1503756c09fdae33b43421111a4d0c4bf44b;hp=f82d6f8081e176442fb7ac0b86516b3279286fd7;hb=HEAD;hpb=6c9bc258d2e9e7b500236a1c696da1f384f0b907 diff --git a/crypto/evp/evp_pkey.c b/crypto/evp/evp_pkey.c index f82d6f8081..a4505a9d03 100644 --- a/crypto/evp/evp_pkey.c +++ b/crypto/evp/evp_pkey.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2023 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 @@ -15,6 +15,7 @@ #include #include #include "internal/provider.h" +#include "internal/sizes.h" #include "crypto/asn1.h" #include "crypto/evp.h" #include "crypto/x509.h" @@ -32,7 +33,7 @@ EVP_PKEY *evp_pkcs82pkey_legacy(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *lib return NULL; if ((pkey = EVP_PKEY_new()) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); return NULL; } @@ -70,8 +71,16 @@ EVP_PKEY *EVP_PKCS82PKEY_ex(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx, const unsigned char *p8_data = NULL; unsigned char *encoded_data = NULL; int encoded_len; + int selection; size_t len; OSSL_DECODER_CTX *dctx = NULL; + const ASN1_OBJECT *algoid = NULL; + char keytype[OSSL_MAX_NAME_SIZE]; + + if (p8 == NULL + || !PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8) + || !OBJ_obj2txt(keytype, sizeof(keytype), algoid, 0)) + return NULL; if ((encoded_len = i2d_PKCS8_PRIV_KEY_INFO(p8, &encoded_data)) <= 0 || encoded_data == NULL) @@ -79,8 +88,22 @@ EVP_PKEY *EVP_PKCS82PKEY_ex(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx, p8_data = encoded_data; len = encoded_len; - dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", "pkcs8", EVP_PKEY_NONE, - 0, libctx, propq); + selection = EVP_PKEY_KEYPAIR | EVP_PKEY_KEY_PARAMETERS; + dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", "PrivateKeyInfo", + keytype, selection, libctx, propq); + + if (dctx != NULL && OSSL_DECODER_CTX_get_num_decoders(dctx) == 0) { + OSSL_DECODER_CTX_free(dctx); + + /* + * This could happen if OBJ_obj2txt() returned a text OID and the + * decoder has not got that OID as an alias. We fall back to a NULL + * keytype + */ + dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", "PrivateKeyInfo", + NULL, selection, libctx, propq); + } + if (dctx == NULL || !OSSL_DECODER_from_data(dctx, &p8_data, &len)) /* try legacy */ @@ -115,7 +138,7 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey) const unsigned char *pp; if ((ctx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection, - "DER", "pkcs8", + "DER", "PrivateKeyInfo", NULL)) == NULL || !OSSL_ENCODER_to_data(ctx, &der, &derlen)) goto error; @@ -128,7 +151,7 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey) } else { p8 = PKCS8_PRIV_KEY_INFO_new(); if (p8 == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EVP, ERR_R_ASN1_LIB); return NULL; } @@ -225,7 +248,7 @@ const char *EVP_PKEY_get0_type_name(const EVP_PKEY *key) const char *name = NULL; if (key->keymgmt != NULL) - return EVP_KEYMGMT_name(key->keymgmt); + return EVP_KEYMGMT_get0_name(key->keymgmt); /* Otherwise fallback to legacy */ ameth = EVP_PKEY_get0_asn1(key); @@ -235,3 +258,10 @@ const char *EVP_PKEY_get0_type_name(const EVP_PKEY *key) return name; } + +const OSSL_PROVIDER *EVP_PKEY_get0_provider(const EVP_PKEY *key) +{ + if (evp_pkey_is_provided(key)) + return EVP_KEYMGMT_get0_provider(key->keymgmt); + return NULL; +}