Additional ASN checks for GetSequence and GetSet. Cleanup of the buffer space check error to use BUFFER_E.

This commit is contained in:
David Garske 2017-02-09 09:50:06 -08:00
parent 8f1c2965af
commit 321392998d

View File

@ -554,11 +554,16 @@ WOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,
word32 idx = *inOutIdx;
if ((idx + 1) > maxIdx)
return ASN_PARSE_E;
return BUFFER_E;
if (input[idx++] != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
GetLength(input, &idx, &length, maxIdx) < 0)
GetLength(input, &idx, &length, maxIdx) < 0) {
return ASN_PARSE_E;
}
/* make sure length exists in buffer */
if ((idx + length) > maxIdx)
return BUFFER_E;
*len = length;
*inOutIdx = idx;
@ -574,12 +579,16 @@ WOLFSSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len,
word32 idx = *inOutIdx;
if ((idx + 1) > maxIdx)
return ASN_PARSE_E;
return BUFFER_E;
if (input[idx++] != (ASN_SET | ASN_CONSTRUCTED) ||
GetLength(input, &idx, &length, maxIdx) < 0)
return ASN_PARSE_E;
/* make sure length exists in buffer */
if ((idx + length) > maxIdx)
return BUFFER_E;
*len = length;
*inOutIdx = idx;
@ -622,7 +631,7 @@ int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx)
/* check for type and length bytes */
if ((idx + 2) > maxIdx)
return ASN_PARSE_E;
return BUFFER_E;
if (input[idx++] != ASN_INTEGER)
return ASN_PARSE_E;
@ -653,7 +662,7 @@ static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version,
WOLFSSL_ENTER("GetExplicitVersion");
if ((idx + 1) > maxIdx)
return ASN_PARSE_E;
return BUFFER_E;
if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
*inOutIdx = ++idx; /* skip header */
@ -674,7 +683,7 @@ int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx,
int length;
if ((idx + 1) > maxIdx)
return ASN_PARSE_E;
return BUFFER_E;
b = input[idx++];
if (b != ASN_INTEGER)
@ -714,7 +723,7 @@ static int GetIntRsa(RsaKey* key, mp_int* mpi, const byte* input,
(void)key;
if ((idx + 1) > maxIdx)
return ASN_PARSE_E;
return BUFFER_E;
b = input[idx++];
if (b != ASN_INTEGER)
@ -1336,8 +1345,8 @@ int DecodeObjectId(const byte* in, word32 inSz, word16* out, word32* outSz)
int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
word32 oidType, word32 maxIdx)
{
int length;
word32 i = *inOutIdx;
int ret = 0, length;
word32 idx = *inOutIdx;
#ifndef NO_VERIFY_OID
word32 actualOidSz = 0;
const byte* actualOid;
@ -1348,32 +1357,35 @@ int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
WOLFSSL_ENTER("GetObjectId()");
*oid = 0;
b = input[i++];
b = input[idx++];
if (b != ASN_OBJECT_ID)
return ASN_OBJECT_ID_E;
if (GetLength(input, &i, &length, maxIdx) < 0)
if (GetLength(input, &idx, &length, maxIdx) < 0)
return ASN_PARSE_E;
#ifndef NO_VERIFY_OID
actualOid = &input[i];
actualOid = &input[idx];
if (length > 0)
actualOidSz = (word32)length;
#endif /* NO_VERIFY_OID */
while (length--) {
/* odd HC08 compiler behavior here when input[i++] */
*oid += (word32)input[i];
i++;
/* odd HC08 compiler behavior here when input[idx++] */
*oid += (word32)input[idx];
idx++;
}
/* just sum it up for now */
*inOutIdx = i;
*inOutIdx = idx;
#ifndef NO_VERIFY_OID
{
const byte* checkOid = NULL;
word32 checkOidSz;
#ifdef ASN_DUMP_OID
int i;
#endif
if (oidType != oidIgnoreType) {
checkOid = OidFromId(*oid, oidType, &checkOidSz);
@ -1387,7 +1399,6 @@ int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
printf("\n");
#ifdef HAVE_OID_DECODING
{
int ret;
word16 decOid[16];
word32 decOidSz = sizeof(decOid);
ret = DecodeObjectId(actualOid, actualOidSz, decOid, &decOidSz);
@ -1415,7 +1426,7 @@ int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
}
#endif /* NO_VERIFY_OID */
return 0;
return ret;
}
@ -1428,7 +1439,7 @@ static int SkipObjectId(const byte* input, word32* inOutIdx, word32 maxIdx)
int length;
if ((idx + 1) > maxIdx)
return ASN_PARSE_E;
return BUFFER_E;
if (input[idx++] != ASN_OBJECT_ID)
return ASN_OBJECT_ID_E;
@ -1465,6 +1476,9 @@ WOLFSSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
b = input[idx];
if (b == ASN_TAG_NULL) {
if ((idx + 1) > maxIdx)
return BUFFER_E;
idx++;
b = input[idx++];
if (b != 0)
@ -1923,7 +1937,7 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
}
}
if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
if (GetSequence(input, &inOutIdx, &length, sz) <= 0) {
ERROR_OUT(ASN_PARSE_E, exit_tte);
}
@ -2052,7 +2066,7 @@ int DecryptContent(byte* input, word32 sz,const char* password,int passwordSz)
}
}
if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
if (GetSequence(input, &inOutIdx, &length, sz) <= 0) {
ERROR_OUT(ASN_PARSE_E, exit_dc);
}
@ -2100,6 +2114,10 @@ int DecryptContent(byte* input, word32 sz,const char* password,int passwordSz)
ERROR_OUT(ASN_PARSE_E, exit_dc); /* PKCS v2 algo id error */
}
if ((inOutIdx + 1) > sz) {
ERROR_OUT(BUFFER_E, exit_dc);
}
if (input[inOutIdx++] != ASN_OCTET_STRING) {
ERROR_OUT(ASN_PARSE_E, exit_dc);
}
@ -2160,7 +2178,7 @@ int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
if ((*inOutIdx + 1) > inSz)
return ASN_PARSE_E;
return BUFFER_E;
b = input[*inOutIdx];
if (b != ASN_INTEGER) {
@ -2268,7 +2286,7 @@ int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
byte b;
int length;
if (GetSequence(input, &idx, &length, inSz) < 0)
if (GetSequence(input, &idx, &length, inSz) <= 0)
return ASN_PARSE_E;
b = input[idx++];
@ -2295,6 +2313,9 @@ int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
}
idx += length;
if ((idx + 1) > inSz)
return BUFFER_E;
b = input[idx++];
if (b != ASN_INTEGER)
return ASN_PARSE_E;
@ -2951,7 +2972,7 @@ static int GetName(DecodedCert* cert, int nameType)
WOLFSSL_MSG("Cert name lacks set header, trying sequence");
}
if (GetSequence(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0)
if (GetSequence(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) <= 0)
return ASN_PARSE_E;
b = cert->source[cert->srcIdx++];
@ -4352,7 +4373,7 @@ static int DecodeAltNames(byte* input, int sz, DecodedCert* cert)
cert->weOwnAltNames = 1;
while (length > 0) {
byte b = input[idx++];
byte b = input[idx++];
length--;
@ -4695,6 +4716,7 @@ static int DecodeAuthInfo(byte* input, int sz, DecodedCert* cert)
if (GetObjectId(input, &idx, &oid, oidCertAuthInfoType, sz) < 0)
return ASN_PARSE_E;
/* Only supporting URIs right now. */
b = input[idx++];
if (GetLength(input, &idx, &length, sz) < 0)
@ -6916,7 +6938,7 @@ static int SetOidValue(byte* out, word32 outSz, const byte *oid, word32 oidSz,
/* sequence, + 1 => byte to put value size */
idx = SetSequence(inSz + oidSz + 1, out);
if (outSz < idx + inSz + oidSz + 1)
if ((idx + inSz + oidSz + 1) > outSz)
return BUFFER_E;
XMEMCPY(out+idx, oid, oidSz);
@ -6952,7 +6974,7 @@ static int SetSKID(byte* output, word32 outSz, byte *input, word32 length)
idx = SetSequence(length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz+1,
output);
if (outSz < length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz + 1)
if ((length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz + 1) > outSz)
return BUFFER_E;
/* put oid */
@ -8938,7 +8960,7 @@ int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
if (*outLen < (rLen + rLeadingZero + sLen + sLeadingZero +
headerSz + 2)) /* SEQ_TAG + LEN(ENUM) */
return BAD_FUNC_ARG;
return BUFFER_E;
idx = SetSequence(rLen+rLeadingZero+sLen+sLeadingZero+headerSz, out);
@ -9047,7 +9069,7 @@ int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
*inOutIdx += length;
if ((*inOutIdx + 1) > inSz)
return ASN_PARSE_E;
return BUFFER_E;
/* prefix 0, may have */
b = input[*inOutIdx];
@ -9488,6 +9510,9 @@ static int DecodeOcspRespExtensions(byte* source,
WOLFSSL_ENTER("DecodeOcspRespExtensions");
if ((idx + 1) > sz)
return BUFFER_E;
if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
return ASN_PARSE_E;