Fixes for encoding/decoding ecc public keys.

This commit is contained in:
Anthony Hu
2023-02-17 16:33:12 -05:00
parent da04e0fb4c
commit c2daca1393
3 changed files with 103 additions and 4 deletions

View File

@ -11915,7 +11915,34 @@ int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
}
else {
ret = wc_EccPublicKeyDecode(derBuf, &idx, (ecc_key*)key->internal,
derSz);
derSz);
if (ret < 0) {
ecc_key *tmp = (ecc_key*)XMALLOC(sizeof(ecc_key),
((ecc_key*)key->internal)->heap, DYNAMIC_TYPE_ECC);
if (tmp == NULL) {
ret = -1;
}
else {
/* We now try again as x.963 [point type][x][opt y]. */
ret = wc_ecc_init_ex(tmp, ((ecc_key*)key->internal)->heap,
INVALID_DEVID);
if (ret == 0) {
ret = wc_ecc_import_x963(derBuf, derSz, tmp);
if (ret == 0) {
/* Take ownership of new key - set tmp to the old
* key which will then be freed below. */
ecc_key *old = (ecc_key *)key->internal;
key->internal = tmp;
tmp = old;
idx = derSz;
}
wc_ecc_free(tmp);
}
XFREE(tmp, ((ecc_key*)key->internal)->heap,
DYNAMIC_TYPE_ECC);
}
}
}
if (ret < 0) {
/* Error returned from wolfSSL. */

View File

@ -23064,9 +23064,18 @@ int wolfSSL_i2d_PublicKey(const WOLFSSL_EVP_PKEY *key, unsigned char **der)
* might be a buffereed private key so we need to decode it and then encode
* the public part. */
if (ret == 0) {
local_derSz = wolfSSL_EVP_PKEY_get_der(key, &local_der);
if (local_derSz <= 0) {
ret = WOLFSSL_FATAL_ERROR;
ret = wolfSSL_EVP_PKEY_get_der(key, &local_der);
if (ret <= 0) {
/* In this case, there was no buffered DER at all. This could be the
* case where the key that was passed in was generated. So now we
* have to create the local DER. */
local_derSz = wolfSSL_i2d_ECPrivateKey(key->ecc, &local_der);
if (local_derSz == 0) {
ret = WOLFSSL_FATAL_ERROR;
}
} else {
local_derSz = ret;
ret = 0;
}
}
@ -23084,6 +23093,10 @@ int wolfSSL_i2d_PublicKey(const WOLFSSL_EVP_PKEY *key, unsigned char **der)
if (ret == 0) {
ret = wc_EccPublicKeyDecode(local_der, &inOutIdx, eccKey, local_derSz);
if (ret < 0) {
/* We now try again as x.963 [point type][x][opt y]. */
ret = wc_ecc_import_x963(local_der, local_derSz, eccKey);
}
}
if (ret == 0) {

View File

@ -47384,6 +47384,64 @@ static int test_wolfSSL_d2i_and_i2d_PublicKey(void)
return res;
}
static int test_wolfSSL_d2i_and_i2d_PublicKey_ecc(void)
{
int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && !defined(NO_CERTS) && \
!defined(NO_ASN) && !defined(NO_PWDBASED)
EVP_PKEY* pkey;
const unsigned char* p;
unsigned char *der = NULL, *tmp = NULL;
int derLen;
unsigned char pub_buf[65];
const int pub_len = 65;
BN_CTX * ctx;
EC_GROUP * curve;
EC_KEY * ephemeral_key;
const EC_POINT * h;
/* Generate an x963 key pair and get public part into pub_buf */
AssertNotNull(ctx = BN_CTX_new());
AssertNotNull(curve = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
AssertNotNull(ephemeral_key = EC_KEY_new_by_curve_name(
NID_X9_62_prime256v1));
AssertIntEQ(EC_KEY_generate_key(ephemeral_key), 1);
AssertNotNull(h = EC_KEY_get0_public_key(ephemeral_key));
AssertIntEQ(pub_len, EC_POINT_point2oct(curve, h,
POINT_CONVERSION_UNCOMPRESSED,
pub_buf, pub_len, ctx));
/* Prepare the EVP_PKEY */
AssertNotNull(pkey = EVP_PKEY_new());
p = pub_buf;
/* Check that key can be successfully decoded. */
AssertNotNull(wolfSSL_d2i_PublicKey(EVP_PKEY_EC, &pkey, &p,
pub_len));
/* Check that key can be successfully encoded. */
AssertIntGE((derLen = wolfSSL_i2d_PublicKey(pkey, &der)), 0);
/* Ensure that the encoded version matches the original. */
AssertIntEQ(derLen, pub_len);
AssertIntEQ(XMEMCMP(der, pub_buf, derLen), 0);
/* Do same test except with pre-allocated buffer to ensure the der pointer
* is advanced. */
tmp = der;
AssertIntGE((derLen = wolfSSL_i2d_PublicKey(pkey, &tmp)), 0);
AssertIntEQ(derLen, pub_len);
AssertIntEQ(XMEMCMP(der, pub_buf, derLen), 0);
AssertTrue(der + derLen == tmp);
XFREE(der, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
EVP_PKEY_free(pkey);
EC_KEY_free(ephemeral_key);
EC_GROUP_free(curve);
res = TEST_RES_CHECK(1);
#endif
return res;
}
static int test_wolfSSL_d2i_and_i2d_DSAparams(void)
{
int res = TEST_SKIPPED;
@ -62255,6 +62313,7 @@ TEST_CASE testCases[] = {
TEST_DECL(test_wolfSSL_PKEY_up_ref),
TEST_DECL(test_wolfSSL_EVP_Cipher_extra),
TEST_DECL(test_wolfSSL_d2i_and_i2d_PublicKey),
TEST_DECL(test_wolfSSL_d2i_and_i2d_PublicKey_ecc),
TEST_DECL(test_wolfSSL_d2i_and_i2d_DSAparams),
TEST_DECL(test_wolfSSL_i2d_PrivateKey),
TEST_DECL(test_wolfSSL_OCSP_id_get0_info),