forked from wolfSSL/wolfssl
Fixes for encoding/decoding ecc public keys.
This commit is contained in:
29
src/pk.c
29
src/pk.c
@ -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. */
|
||||
|
19
src/ssl.c
19
src/ssl.c
@ -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) {
|
||||
|
59
tests/api.c
59
tests/api.c
@ -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),
|
||||
|
Reference in New Issue
Block a user