forked from wolfSSL/wolfssl
Merge pull request #5011 from dgarske/ecc_key_decode
Fix to check if `wc_EccPublicKeyToDer` has enough output buffer space
This commit is contained in:
@@ -21123,81 +21123,38 @@ static int SetEccPublicKey(byte* output, ecc_key* key, int outLen,
|
|||||||
int with_header)
|
int with_header)
|
||||||
{
|
{
|
||||||
#ifndef WOLFSSL_ASN_TEMPLATE
|
#ifndef WOLFSSL_ASN_TEMPLATE
|
||||||
byte bitString[1 + MAX_LENGTH_SZ + 1];
|
int ret, idx = 0, algoSz, curveSz, bitStringSz;
|
||||||
int algoSz;
|
word32 pubSz;
|
||||||
int curveSz;
|
byte bitString[1 + MAX_LENGTH_SZ + 1]; /* 6 */
|
||||||
int bitStringSz;
|
byte algo[MAX_ALGO_SZ]; /* 20 */
|
||||||
int idx;
|
byte curve[MAX_ALGO_SZ]; /* 20 */
|
||||||
word32 pubSz = ECC_BUFSIZE;
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
byte* algo = NULL;
|
|
||||||
byte* curve = NULL;
|
|
||||||
byte* pub;
|
|
||||||
#else
|
|
||||||
byte algo[MAX_ALGO_SZ];
|
|
||||||
byte curve[MAX_ALGO_SZ];
|
|
||||||
byte pub[ECC_BUFSIZE];
|
|
||||||
#endif
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
(void)outLen;
|
/* public size */
|
||||||
|
pubSz = key->dp ? key->dp->size : MAX_ECC_BYTES;
|
||||||
|
pubSz = 1 + 2 * pubSz;
|
||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
/* check for buffer overflow */
|
||||||
pub = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
if (output != NULL && pubSz > (word32)outLen) {
|
||||||
if (pub == NULL)
|
return BUFFER_E;
|
||||||
return MEMORY_E;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HAVE_SELFTEST) || defined(HAVE_FIPS)
|
|
||||||
/* older version of ecc.c can not handle dp being NULL */
|
|
||||||
if (key != NULL && key->dp == NULL) {
|
|
||||||
pubSz = 1 + 2 * MAX_ECC_BYTES;
|
|
||||||
ret = LENGTH_ONLY_E;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PRIVATE_KEY_UNLOCK();
|
|
||||||
ret = wc_ecc_export_x963(key, pub, &pubSz);
|
|
||||||
PRIVATE_KEY_LOCK();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
ret = wc_ecc_export_x963(key, pub, &pubSz);
|
|
||||||
#endif
|
|
||||||
if (ret != 0) {
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#endif
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* headers */
|
/* headers */
|
||||||
if (with_header) {
|
if (with_header) {
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
curve = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
if (curve == NULL) {
|
|
||||||
XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
return MEMORY_E;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
curveSz = SetCurve(key, curve);
|
curveSz = SetCurve(key, curve);
|
||||||
if (curveSz <= 0) {
|
if (curveSz <= 0) {
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#endif
|
|
||||||
return curveSz;
|
return curveSz;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
/* calculate size */
|
||||||
algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
if (algo == NULL) {
|
|
||||||
XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
return MEMORY_E;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
algoSz = SetAlgoID(ECDSAk, algo, oidKeyType, curveSz);
|
algoSz = SetAlgoID(ECDSAk, algo, oidKeyType, curveSz);
|
||||||
|
|
||||||
bitStringSz = SetBitString(pubSz, 0, bitString);
|
bitStringSz = SetBitString(pubSz, 0, bitString);
|
||||||
|
idx = SetSequence(pubSz + curveSz + bitStringSz + algoSz, NULL);
|
||||||
|
|
||||||
|
/* check for buffer overflow */
|
||||||
|
if (output != NULL &&
|
||||||
|
curveSz + algoSz + bitStringSz + idx + pubSz > (word32)outLen) {
|
||||||
|
return BUFFER_E;
|
||||||
|
}
|
||||||
|
|
||||||
idx = SetSequence(pubSz + curveSz + bitStringSz + algoSz, output);
|
idx = SetSequence(pubSz + curveSz + bitStringSz + algoSz, output);
|
||||||
/* algo */
|
/* algo */
|
||||||
@@ -21213,21 +21170,17 @@ static int SetEccPublicKey(byte* output, ecc_key* key, int outLen,
|
|||||||
XMEMCPY(output + idx, bitString, bitStringSz);
|
XMEMCPY(output + idx, bitString, bitStringSz);
|
||||||
idx += bitStringSz;
|
idx += bitStringSz;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
idx = 0;
|
|
||||||
|
|
||||||
/* pub */
|
/* pub */
|
||||||
if (output)
|
if (output) {
|
||||||
XMEMCPY(output + idx, pub, pubSz);
|
PRIVATE_KEY_UNLOCK();
|
||||||
idx += pubSz;
|
ret = wc_ecc_export_x963(key, output + idx, &pubSz);
|
||||||
|
PRIVATE_KEY_LOCK();
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
if (ret != 0) {
|
||||||
if (with_header) {
|
return ret;
|
||||||
XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
}
|
}
|
||||||
XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
}
|
||||||
#endif
|
idx += pubSz;
|
||||||
|
|
||||||
return idx;
|
return idx;
|
||||||
#else
|
#else
|
||||||
|
Reference in New Issue
Block a user