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:
Sean Parkinson
2022-04-05 08:03:03 +10:00
committed by GitHub

View File

@@ -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