Do not free caller's EVP_PKEY until d2i has a replacement

pull/10962/head
Takashi Kojo 2026-08-07 07:18:12 +09:00
parent 7635f3ab9d
commit f79cb90071
2 changed files with 32 additions and 6 deletions

View File

@ -679,6 +679,34 @@ int test_wolfSSL_PEM_PrivateKey_mldsa(void)
}
BIO_free(bio);
bio = NULL;
/* A failed read into the same pointer must leave the held key
* untouched, not freed (the caller would otherwise be left with
* a dangling pointer and a later double free). */
{
static const char badPem[] =
"-----BEGIN PRIVATE KEY-----\n"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
"-----END PRIVATE KEY-----\n";
static const unsigned char junk[8] =
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
const unsigned char* jp = junk;
ExpectNull(wolfSSL_d2i_PrivateKey(WC_EVP_PKEY_DILITHIUM, &pkey,
&jp, (long)sizeof(junk)));
ExpectNotNull(pkey);
ExpectIntEQ(EVP_PKEY_id(pkey), EVP_PKEY_DILITHIUM);
ExpectNotNull(bio = BIO_new_mem_buf(badPem,
(int)sizeof(badPem) - 1));
ExpectNull(wolfSSL_PEM_read_bio_PrivateKey(bio, &pkey, NULL,
NULL));
ExpectNotNull(pkey);
ExpectIntEQ(EVP_PKEY_id(pkey), EVP_PKEY_DILITHIUM);
BIO_free(bio);
bio = NULL;
}
EVP_PKEY_free(pkey);
pkey = NULL;
}

View File

@ -1501,12 +1501,8 @@ static WOLFSSL_EVP_PKEY* d2i_evp_pkey(int type, WOLFSSL_EVP_PKEY** out,
}
}
/* Dispose of any WOLFSSL_EVP_PKEY passed in. */
if (out != NULL && *out != NULL) {
wolfSSL_EVP_PKEY_free(*out);
*out = NULL;
}
/* Create a new WOLFSSL_EVP_PKEY and populate. */
/* Create a new WOLFSSL_EVP_PKEY and populate. Any WOLFSSL_EVP_PKEY
* passed in is replaced only on success. */
local = wolfSSL_EVP_PKEY_new();
if (local == NULL) {
return NULL;
@ -1631,6 +1627,8 @@ static WOLFSSL_EVP_PKEY* d2i_evp_pkey(int type, WOLFSSL_EVP_PKEY** out,
*in += local->pkey_sz;
}
if (out != NULL) {
/* Dispose of any WOLFSSL_EVP_PKEY passed in. */
wolfSSL_EVP_PKEY_free(*out);
*out = local;
}
}