mirror of
https://github.com/openssl/openssl.git
synced 2025-01-18 13:44:20 +08:00
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)
This commit is contained in:
parent
468d9d5564
commit
4f0831b837
@ -106,7 +106,7 @@ d2i_PrivateKey_legacy(int keytype, EVP_PKEY **a, const unsigned char **pp,
|
|||||||
ERR_clear_last_mark();
|
ERR_clear_last_mark();
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
tmp = EVP_PKCS82PKEY_ex(p8, libctx, propq);
|
tmp = evp_pkcs82pkey_legacy(p8, libctx, propq);
|
||||||
PKCS8_PRIV_KEY_INFO_free(p8);
|
PKCS8_PRIV_KEY_INFO_free(p8);
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
ERR_clear_last_mark();
|
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);
|
ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ret = EVP_PKCS82PKEY_ex(p8, libctx, propq);
|
ret = evp_pkcs82pkey_legacy(p8, libctx, propq);
|
||||||
PKCS8_PRIV_KEY_INFO_free(p8);
|
PKCS8_PRIV_KEY_INFO_free(p8);
|
||||||
if (ret == NULL)
|
if (ret == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
#include <openssl/encoder.h>
|
#include <openssl/encoder.h>
|
||||||
|
#include <openssl/decoder.h>
|
||||||
#include "internal/provider.h"
|
#include "internal/provider.h"
|
||||||
#include "crypto/asn1.h"
|
#include "crypto/asn1.h"
|
||||||
#include "crypto/evp.h"
|
#include "crypto/evp.h"
|
||||||
@ -20,8 +21,8 @@
|
|||||||
|
|
||||||
/* Extract a private key from a PKCS8 structure */
|
/* Extract a private key from a PKCS8 structure */
|
||||||
|
|
||||||
EVP_PKEY *EVP_PKCS82PKEY_ex(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx,
|
EVP_PKEY *evp_pkcs82pkey_legacy(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx,
|
||||||
const char *propq)
|
const char *propq)
|
||||||
{
|
{
|
||||||
EVP_PKEY *pkey = NULL;
|
EVP_PKEY *pkey = NULL;
|
||||||
const ASN1_OBJECT *algoid;
|
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;
|
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)
|
EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8)
|
||||||
{
|
{
|
||||||
return EVP_PKCS82PKEY_ex(p8, NULL, NULL);
|
return EVP_PKCS82PKEY_ex(p8, NULL, NULL);
|
||||||
|
@ -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);
|
int evp_pkey_copy_downgraded(EVP_PKEY **dest, const EVP_PKEY *src);
|
||||||
void *evp_pkey_get_legacy(EVP_PKEY *pk);
|
void *evp_pkey_get_legacy(EVP_PKEY *pk);
|
||||||
void evp_pkey_free_legacy(EVP_PKEY *x);
|
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
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "internal/cryptlib.h" /* ossl_assert */
|
#include "internal/cryptlib.h" /* ossl_assert */
|
||||||
#include "crypto/pem.h" /* For PVK and "blob" PEM headers */
|
#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 "helpers/predefined_dhparams.h"
|
||||||
#include "testutil.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);
|
TEST_note("%s isn't any of %s", type, namelist);
|
||||||
OPENSSL_free(namelist);
|
OPENSSL_free(namelist);
|
||||||
}
|
}
|
||||||
|
ok = ok && TEST_FL_true(evp_pkey_is_provided(pkey));
|
||||||
EVP_PKEY_free(pkey);
|
EVP_PKEY_free(pkey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user