mirror of https://github.com/wolfSSL/wolfssl
Explicit curve data in public ECC key
Certificate's public key data contains more of the encoding. PKCS #7 using public key from certificates calls proper decode.
This commit is contained in:
parent
274110a10c
commit
7160384a19
|
@ -8918,8 +8918,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||
#ifdef HAVE_ECC
|
||||
case ECDSAk:
|
||||
{
|
||||
int curveId;
|
||||
int keyRet = 0;
|
||||
word32 idx = 0;
|
||||
|
||||
if (ssl->peerEccDsaKey == NULL) {
|
||||
/* alloc/init on demand */
|
||||
keyRet = AllocKey(ssl, DYNAMIC_TYPE_ECC,
|
||||
|
@ -8930,11 +8931,10 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||
ssl->peerEccDsaKeyPresent = 0;
|
||||
}
|
||||
|
||||
curveId = wc_ecc_get_oid(args->dCert->keyOID, NULL, NULL);
|
||||
if (keyRet != 0 ||
|
||||
wc_ecc_import_x963_ex(args->dCert->publicKey,
|
||||
args->dCert->pubKeySize, ssl->peerEccDsaKey,
|
||||
curveId) != 0) {
|
||||
wc_EccPublicKeyDecode(args->dCert->publicKey, &idx,
|
||||
ssl->peerEccDsaKey,
|
||||
args->dCert->pubKeySize) != 0) {
|
||||
ret = PEER_KEY_ERROR;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -16415,6 +16415,8 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
|
|||
/* decode ECC key */
|
||||
#ifdef HAVE_ECC
|
||||
if (key->type == EVP_PKEY_EC) {
|
||||
word32 idx = 0;
|
||||
|
||||
key->ownEcc = 1;
|
||||
key->ecc = wolfSSL_EC_KEY_new();
|
||||
if (key->ecc == NULL || key->ecc->internal == NULL) {
|
||||
|
@ -16424,9 +16426,9 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
|
|||
|
||||
/* not using wolfSSL_EC_KEY_LoadDer because public key in x509
|
||||
* is in the format of x963 (no sequence at start of buffer) */
|
||||
if (wc_ecc_import_x963((const unsigned char*)key->pkey.ptr,
|
||||
key->pkey_sz, (ecc_key*)key->ecc->internal) < 0) {
|
||||
WOLFSSL_MSG("wc_ecc_import_x963 failed");
|
||||
if (wc_EccPublicKeyDecode((const unsigned char*)key->pkey.ptr,
|
||||
&idx, (ecc_key*)key->ecc->internal, key->pkey_sz) < 0) {
|
||||
WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
|
||||
XFREE(key, x509->heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
wolfSSL_EC_KEY_free(key->ecc);
|
||||
return NULL;
|
||||
|
|
|
@ -3918,7 +3918,7 @@ static int StoreRsaKey(DecodedCert* cert)
|
|||
static int GetKey(DecodedCert* cert)
|
||||
{
|
||||
int length;
|
||||
#ifdef HAVE_NTRU
|
||||
#if defined(HAVE_ECC) || defined(HAVE_NTRU)
|
||||
int tmpIdx = cert->srcIdx;
|
||||
#endif
|
||||
|
||||
|
@ -4011,7 +4011,11 @@ static int GetKey(DecodedCert* cert)
|
|||
case ECDSAk:
|
||||
{
|
||||
int ret;
|
||||
byte seq[5];
|
||||
int pubLen = length + 1 + SetLength(length, seq);
|
||||
|
||||
if (cert->source[cert->srcIdx] !=
|
||||
(ASN_SEQUENCE | ASN_CONSTRUCTED)) {
|
||||
if (GetObjectId(cert->source, &cert->srcIdx,
|
||||
&cert->pkCurveOID, oidCurveType, cert->maxIdx) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
@ -4024,16 +4028,17 @@ static int GetKey(DecodedCert* cert)
|
|||
cert->maxIdx, 1, NULL);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
cert->publicKey = (byte*)XMALLOC(length, cert->heap,
|
||||
cert->publicKey = (byte*)XMALLOC(pubLen, cert->heap,
|
||||
DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
if (cert->publicKey == NULL)
|
||||
return MEMORY_E;
|
||||
XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length);
|
||||
XMEMCPY(cert->publicKey, &cert->source[tmpIdx], pubLen);
|
||||
cert->pubKeyStored = 1;
|
||||
cert->pubKeySize = length;
|
||||
cert->pubKeySize = pubLen;
|
||||
|
||||
cert->srcIdx += length;
|
||||
cert->srcIdx = tmpIdx + pubLen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -5366,6 +5371,8 @@ static int ConfirmSignature(SignatureCtx* sigCtx,
|
|||
#ifdef HAVE_ECC
|
||||
case ECDSAk:
|
||||
{
|
||||
word32 idx = 0;
|
||||
|
||||
sigCtx->verify = 0;
|
||||
sigCtx->key.ecc = (ecc_key*)XMALLOC(sizeof(ecc_key),
|
||||
sigCtx->heap, DYNAMIC_TYPE_ECC);
|
||||
|
@ -5376,8 +5383,9 @@ static int ConfirmSignature(SignatureCtx* sigCtx,
|
|||
sigCtx->devId)) < 0) {
|
||||
goto exit_cs;
|
||||
}
|
||||
if ((ret = wc_ecc_import_x963(key, keySz,
|
||||
sigCtx->key.ecc)) < 0) {
|
||||
ret = wc_EccPublicKeyDecode(key, &idx, sigCtx->key.ecc,
|
||||
keySz);
|
||||
if (ret < 0) {
|
||||
WOLFSSL_MSG("ASN Key import error ECC");
|
||||
goto exit_cs;
|
||||
}
|
||||
|
@ -11014,6 +11022,43 @@ int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
|
|||
}
|
||||
|
||||
|
||||
#ifdef WOLFSSL_CUSTOM_CURVES
|
||||
static void ByteToHex(byte n, char* str)
|
||||
{
|
||||
static char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
|
||||
str[0] = hex[n >> 4];
|
||||
str[1] = hex[n & 0xf];
|
||||
}
|
||||
static int ASNToHexString(const byte* input, word32* inOutIdx, char** out,
|
||||
word32 inSz, void* heap, int heapType)
|
||||
{
|
||||
int len;
|
||||
int i;
|
||||
char* str;
|
||||
|
||||
if (input[*inOutIdx] == ASN_INTEGER) {
|
||||
if (GetASNInt(input, inOutIdx, &len, inSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
else {
|
||||
if (GetOctetString(input, inOutIdx, &len, inSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
|
||||
str = XMALLOC(len * 2 + 1, heap, heapType);
|
||||
for (i=0; i<len; i++)
|
||||
ByteToHex(input[*inOutIdx + i], str + i*2);
|
||||
str[len*2] = '\0';
|
||||
|
||||
*inOutIdx += len;
|
||||
*out = str;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
|
||||
ecc_key* key, word32 inSz)
|
||||
{
|
||||
|
@ -11035,6 +11080,117 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
|
|||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
if (input[*inOutIdx] == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
|
||||
#ifdef WOLFSSL_CUSTOM_CURVES
|
||||
ecc_set_type* params;
|
||||
int len;
|
||||
char* point;
|
||||
|
||||
ret = 0;
|
||||
|
||||
params = XMALLOC(sizeof(*params), NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (params == NULL)
|
||||
ret = MEMORY_E;
|
||||
|
||||
if (ret == 0) {
|
||||
XMEMSET(params, 0, sizeof(*params));
|
||||
params->name = "Custom";
|
||||
params->id = ECC_CURVE_CUSTOM;
|
||||
|
||||
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
GetInteger7Bit(input, inOutIdx, inSz);
|
||||
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
SkipObjectId(input, inOutIdx, inSz);
|
||||
ret = ASNToHexString(input, inOutIdx, (char**)¶ms->prime, inSz,
|
||||
NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
}
|
||||
if (ret == 0) {
|
||||
params->size = (int)XSTRLEN(params->prime) / 2;
|
||||
|
||||
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = ASNToHexString(input, inOutIdx, (char**)¶ms->Af, inSz,
|
||||
NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = ASNToHexString(input, inOutIdx, (char**)¶ms->Bf, inSz,
|
||||
NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
}
|
||||
if (ret == 0) {
|
||||
if (input[*inOutIdx] == ASN_BIT_STRING) {
|
||||
len = 0;
|
||||
ret = GetASNHeader(input, ASN_BIT_STRING, inOutIdx, &len, inSz);
|
||||
inOutIdx += len;
|
||||
}
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = ASNToHexString(input, inOutIdx, (char**)&point, inSz, NULL,
|
||||
DYNAMIC_TYPE_ECC_BUFFER);
|
||||
}
|
||||
if (ret == 0) {
|
||||
params->Gx = XMALLOC(params->size * 2 + 2, NULL,
|
||||
DYNAMIC_TYPE_ECC_BUFFER);
|
||||
params->Gy = XMALLOC(params->size * 2 + 2, NULL,
|
||||
DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (params->Gx == NULL || params->Gy == NULL)
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
XMEMCPY((char*)params->Gx, point + 2, params->size * 2);
|
||||
XMEMCPY((char*)params->Gy, point + params->size * 2 + 2,
|
||||
params->size * 2);
|
||||
((char*)params->Gx)[params->size * 2] = '\0';
|
||||
((char*)params->Gy)[params->size * 2] = '\0';
|
||||
XFREE(point, NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
ret = ASNToHexString(input, inOutIdx, (char**)¶ms->order, inSz,
|
||||
NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
}
|
||||
if (ret == 0) {
|
||||
params->cofactor = GetInteger7Bit(input, inOutIdx, inSz);
|
||||
|
||||
params->oid = NULL;
|
||||
params->oidSz = 0;
|
||||
params->oidSum = 0;
|
||||
|
||||
if (wc_ecc_set_custom_curve(key, params) < 0) {
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
key->deallocSet = 1;
|
||||
params = NULL;
|
||||
}
|
||||
if (params != NULL) {
|
||||
if (params->prime != NULL)
|
||||
XFREE((void*)params->prime, NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (params->Af != NULL)
|
||||
XFREE((void*)params->Af, NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (params->Bf != NULL)
|
||||
XFREE((void*)params->Bf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (params->order != NULL)
|
||||
XFREE((void*)params->order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (params->Gx != NULL)
|
||||
XFREE((void*)params->Gx, NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (params->Gy != NULL)
|
||||
XFREE((void*)params->Gy, NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
|
||||
XFREE((void*)params, NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
#else
|
||||
return ASN_PARSE_E;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
/* ecc params information */
|
||||
ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType, inSz);
|
||||
if (ret != 0)
|
||||
|
@ -11044,6 +11200,7 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
|
|||
curve_id = wc_ecc_get_oid(oidSum, NULL, 0);
|
||||
if (curve_id < 0)
|
||||
return ECC_CURVE_OID_E;
|
||||
}
|
||||
|
||||
/* key header */
|
||||
ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
|
||||
|
|
|
@ -3895,6 +3895,26 @@ int wc_ecc_free(ecc_key* key)
|
|||
|
||||
mp_forcezero(&key->k);
|
||||
#endif /* WOLFSSL_ATECC508A */
|
||||
|
||||
#ifdef WOLFSSL_CUSTOM_CURVES
|
||||
if (key->deallocSet && key->dp != NULL) {
|
||||
if (key->dp->prime != NULL)
|
||||
XFREE((void*)key->dp->prime, NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (key->dp->Af != NULL)
|
||||
XFREE((void*)key->dp->Af, NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (key->dp->Bf != NULL)
|
||||
XFREE((void*)key->dp->Bf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (key->dp->order != NULL)
|
||||
XFREE((void*)key->dp->order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (key->dp->Gx != NULL)
|
||||
XFREE((void*)key->dp->Gx, NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
if (key->dp->Gy != NULL)
|
||||
XFREE((void*)key->dp->Gy, NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
|
||||
XFREE((void*)key->dp, NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5454,6 +5474,7 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
|
|||
int curve_id)
|
||||
{
|
||||
int ret;
|
||||
word32 idx = 0;
|
||||
|
||||
if (key == NULL || priv == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
@ -5461,6 +5482,8 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
|
|||
/* public optional, NULL if only importing private */
|
||||
if (pub != NULL) {
|
||||
ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id);
|
||||
if (ret < 0)
|
||||
ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz);
|
||||
key->type = ECC_PRIVATEKEY;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1380,6 +1380,7 @@ static int wc_PKCS7_EcdsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
|
|||
ecc_key stack_key;
|
||||
ecc_key* key = &stack_key;
|
||||
#endif
|
||||
word32 idx = 0;
|
||||
|
||||
if (pkcs7 == NULL || sig == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
@ -1409,7 +1410,8 @@ static int wc_PKCS7_EcdsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (wc_ecc_import_x963(pkcs7->publicKey, pkcs7->publicKeySz, key) < 0) {
|
||||
if (wc_EccPublicKeyDecode(pkcs7->publicKey, &idx, key,
|
||||
pkcs7->publicKeySz) < 0) {
|
||||
WOLFSSL_MSG("ASN ECDSA key decode error");
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
@ -2346,9 +2348,11 @@ static int wc_PKCS7_KariParseRecipCert(WC_PKCS7_KARI* kari, const byte* cert,
|
|||
/* get recip public key */
|
||||
if (kari->direction == WC_PKCS7_ENCODE) {
|
||||
|
||||
ret = wc_ecc_import_x963(kari->decoded->publicKey,
|
||||
kari->decoded->pubKeySize,
|
||||
kari->recipKey);
|
||||
idx = 0;
|
||||
ret = wc_EccPublicKeyDecode(kari->decoded->publicKey, &idx,
|
||||
kari->recipKey, kari->decoded->pubKeySize);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
/* get recip private key */
|
||||
else if (kari->direction == WC_PKCS7_DECODE) {
|
||||
|
|
|
@ -295,6 +295,9 @@ struct ecc_key {
|
|||
word32 flags;
|
||||
const ecc_set_type* dp; /* domain parameters, either points to NIST
|
||||
curves (idx >= 0) or user supplied */
|
||||
#ifdef WOLFSSL_CUSTOM_CURVES
|
||||
int deallocSet;
|
||||
#endif
|
||||
void* heap; /* heap hint */
|
||||
ecc_point pubkey; /* public key */
|
||||
mp_int k; /* private key */
|
||||
|
|
Loading…
Reference in New Issue