mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 15:30:49 +02:00
evp: fix EVP_PKEY2PKCS8 returning NULL for private-key-only EC keys
When an EC_KEY is created via EC_KEY_new + EC_KEY_set_group +
EC_KEY_set_private_key (no public point set), SetECKeyInternal
incorrectly marks the internal ecc_key as ECC_PRIVATEKEY (instead of
ECC_PRIVATEKEY_ONLY) because pub_key is always non-NULL — EC_KEY_new
always allocates it as an empty, zero-initialised EC_POINT.
ECC_populate_EVP_PKEY only calls wc_ecc_make_pub for ECC_PRIVATEKEY_ONLY
keys, so the zero public-key point was serialised into the DER stored in
pkey->pkey.ptr. After commit 929dd9913 made wc_ecc_import_x963_ex always
pass untrusted=1, the re-decode inside wolfSSL_EVP_PKEY2PKCS8 →
wolfSSL_d2i_PrivateKey_EVP correctly rejected that zero point with an
on-curve failure, causing EVP_PKEY2PKCS8 to return NULL.
Fix: in ECC_populate_EVP_PKEY, also call wc_ecc_make_pub when the key
type is ECC_PRIVATEKEY but pubkey.x is zero (meaning the public key was
never actually populated). This reconstructs the public key from the
private scalar so that the encoded DER contains a valid on-curve point.
This commit is contained in:
+15
-1
@@ -3704,6 +3704,10 @@ int wolfSSL_EVP_PKEY_keygen_init(WOLFSSL_EVP_PKEY_CTX *ctx)
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
static int ECC_populate_EVP_PKEY(WOLFSSL_EVP_PKEY* pkey, WOLFSSL_EC_KEY *key);
|
||||
#endif
|
||||
|
||||
int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx,
|
||||
WOLFSSL_EVP_PKEY **ppkey)
|
||||
{
|
||||
@@ -3758,6 +3762,8 @@ int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx,
|
||||
ret = wolfSSL_EC_KEY_generate_key(pkey->ecc);
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
pkey->ownEcc = 1;
|
||||
if (ECC_populate_EVP_PKEY(pkey, pkey->ecc) != WOLFSSL_SUCCESS)
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -9516,7 +9522,15 @@ static int ECC_populate_EVP_PKEY(WOLFSSL_EVP_PKEY* pkey, WOLFSSL_EC_KEY *key)
|
||||
else
|
||||
#endif /* HAVE_PKCS8 */
|
||||
{
|
||||
if (ecc->type == ECC_PRIVATEKEY_ONLY) {
|
||||
if (ecc->type == ECC_PRIVATEKEY_ONLY ||
|
||||
(ecc->type == ECC_PRIVATEKEY &&
|
||||
mp_iszero(ecc->pubkey.x))) {
|
||||
/* Reconstruct public key from private scalar. This covers
|
||||
* both ECC_PRIVATEKEY_ONLY keys and ECC_PRIVATEKEY keys whose
|
||||
* public-key point was never populated (e.g. when only
|
||||
* EC_KEY_set_private_key was called, SetECKeyInternal copies
|
||||
* the zero-initialized pub_key point and marks the type as
|
||||
* ECC_PRIVATEKEY, leaving pubkey.x == 0). */
|
||||
if (wc_ecc_make_pub(ecc, NULL) != MP_OKAY) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user