Merge pull request #2465 from JacobBarthelmeh/Fuzzer

sanity check on length before read
This commit is contained in:
toddouska
2019-09-19 13:34:42 -07:00
committed by GitHub
6 changed files with 648 additions and 223 deletions

View File

@ -34722,8 +34722,13 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
if (no_name == 1) {
int length;
word32 idx = 0;
byte tag;
if (a->obj[idx++] != ASN_OBJECT_ID) {
if (GetASNTag(a->obj, &idx, &tag, a->objSz) != 0) {
return WOLFSSL_FAILURE;
}
if (tag != ASN_OBJECT_ID) {
WOLFSSL_MSG("Bad ASN1 Object");
return WOLFSSL_FAILURE;
}

View File

@ -199,18 +199,44 @@ WOLFSSL_LOCAL int GetLength_ex(const byte* input, word32* inOutIdx, int* len,
}
/* input : buffer to read from
* inOutIdx : index to start reading from, gets advanced by 1 if successful
* maxIdx : maximum index value
* tag : ASN tag value found
*
* returns 0 on success
*/
int GetASNTag(const byte* input, word32* inOutIdx, byte* tag, word32 maxIdx)
{
word32 idx;
if (tag == NULL || inOutIdx == NULL || input == NULL) {
return BAD_FUNC_ARG;
}
idx = *inOutIdx;
if (idx + ASN_TAG_SZ > maxIdx) {
WOLFSSL_MSG("Buffer too small for ASN tag");
return BUFFER_E;
}
*tag = input[idx];
*inOutIdx = idx + ASN_TAG_SZ;
return 0;
}
static int GetASNHeader_ex(const byte* input, byte tag, word32* inOutIdx, int* len,
word32 maxIdx, int check)
{
word32 idx = *inOutIdx;
byte b;
byte tagFound;
int length;
if ((idx + 1) > maxIdx)
return BUFFER_E;
if (GetASNTag(input, &idx, &tagFound, maxIdx) != 0)
return ASN_PARSE_E;
b = input[idx++];
if (b != tag)
if (tagFound != tag)
return ASN_PARSE_E;
if (GetLength_ex(input, &idx, &length, maxIdx, check) < 0)
@ -450,7 +476,9 @@ static int GetInteger7Bit(const byte* input, word32* inOutIdx, word32 maxIdx)
if ((idx + 3) > maxIdx)
return BUFFER_E;
if (input[idx++] != ASN_INTEGER)
if (GetASNTag(input, &idx, &b, maxIdx) != 0)
return ASN_PARSE_E;
if (b != ASN_INTEGER)
return ASN_PARSE_E;
if (input[idx++] != 1)
return ASN_PARSE_E;
@ -674,11 +702,15 @@ WOLFSSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx,
int* version, word32 maxIdx)
{
word32 idx = *inOutIdx;
byte tag;
if ((idx + MIN_VERSION_SZ) > maxIdx)
return ASN_PARSE_E;
if (input[idx++] != ASN_INTEGER)
if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
return ASN_PARSE_E;
if (tag != ASN_INTEGER)
return ASN_PARSE_E;
if (input[idx++] != 0x01)
@ -697,6 +729,7 @@ WOLFSSL_LOCAL int GetShortInt(const byte* input, word32* inOutIdx, int* number,
{
word32 idx = *inOutIdx;
word32 len;
byte tag;
*number = 0;
@ -704,7 +737,10 @@ WOLFSSL_LOCAL int GetShortInt(const byte* input, word32* inOutIdx, int* number,
if ((idx + 2) > maxIdx)
return BUFFER_E;
if (input[idx++] != ASN_INTEGER)
if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
return ASN_PARSE_E;
if (tag != ASN_INTEGER)
return ASN_PARSE_E;
len = input[idx++];
@ -774,13 +810,14 @@ static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version,
word32 maxIdx)
{
word32 idx = *inOutIdx;
byte tag;
WOLFSSL_ENTER("GetExplicitVersion");
if ((idx + 1) > maxIdx)
return BUFFER_E;
if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
return ASN_PARSE_E;
if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
*inOutIdx = ++idx; /* skip header */
return GetMyVersion(input, inOutIdx, version, maxIdx);
}
@ -848,11 +885,13 @@ static int CheckBitString(const byte* input, word32* inOutIdx, int* len,
int length;
byte b;
if ((idx + 1) > maxIdx)
return BUFFER_E;
if (input[idx++] != ASN_BIT_STRING)
if (GetASNTag(input, &idx, &b, maxIdx) != 0) {
return ASN_BITSTR_E;
}
if (b != ASN_BIT_STRING) {
return ASN_BITSTR_E;
}
if (GetLength(input, &idx, &length, maxIdx) < 0)
return ASN_PARSE_E;
@ -949,6 +988,9 @@ int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz)
outSz = *derSz;
for (i = 0, j = 0; i < berSz; ) {
word32 localIdx;
byte tag;
/* Check that there is data for an ASN item to parse. */
if (i + 2 > berSz)
return ASN_PARSE_E;
@ -971,9 +1013,14 @@ int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz)
/* Indefinite length is encoded as: 0x80 */
type = ber[i];
indef = ber[i+1] == ASN_INDEF_LENGTH;
localIdx = i;
if (GetASNTag(ber, &localIdx, &tag, berSz) != 0)
return ASN_PARSE_E;
if (indef && (type & 0xC0) == 0 &&
ber[i] != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
ber[i] != (ASN_SET | ASN_CONSTRUCTED)) {
tag != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
tag != (ASN_SET | ASN_CONSTRUCTED)) {
/* Indefinite length OCTET STRING or other simple type.
* Put all the data into one entry.
*/
@ -2097,14 +2144,16 @@ int GetASNObjectId(const byte* input, word32* inOutIdx, int* len,
word32 maxIdx)
{
word32 idx = *inOutIdx;
byte b;
int length;
byte tag;
if ((idx + 1) > maxIdx)
return BUFFER_E;
b = input[idx++];
if (b != ASN_OBJECT_ID)
if (GetASNTag(input, &idx, &tag, maxIdx) != 0)
return ASN_PARSE_E;
if (tag != ASN_OBJECT_ID)
return ASN_OBJECT_ID_E;
if (GetLength(input, &idx, &length, maxIdx) < 0)
@ -2247,10 +2296,17 @@ WOLFSSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
return ASN_OBJECT_ID_E;
/* could have NULL tag and 0 terminator, but may not */
if (idx < maxIdx && input[idx] == ASN_TAG_NULL) {
ret = GetASNNull(input, &idx, maxIdx);
if (ret != 0)
return ret;
if (idx < maxIdx) {
word32 localIdx = idx; /*use localIdx to not advance when checking tag*/
byte tag;
if (GetASNTag(input, &localIdx, &tag, maxIdx) == 0) {
if (tag == ASN_TAG_NULL) {
ret = GetASNNull(input, &idx, maxIdx);
if (ret != 0)
return ret;
}
}
}
*inOutIdx = idx;
@ -2322,6 +2378,7 @@ int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz,
word32 idx;
int version, length;
int ret;
byte tag;
if (input == NULL || inOutIdx == NULL)
return BAD_FUNC_ARG;
@ -2337,7 +2394,11 @@ int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz,
if (GetAlgoId(input, &idx, algId, oidKeyType, sz) < 0)
return ASN_PARSE_E;
if (input[idx] == ASN_OBJECT_ID) {
if (GetASNTag(input, &idx, &tag, sz) < 0)
return ASN_PARSE_E;
idx = idx - 1; /* reset idx after finding tag */
if (tag == ASN_OBJECT_ID) {
if (SkipObjectId(input, &idx, sz) < 0)
return ASN_PARSE_E;
}
@ -3451,8 +3512,16 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password,
}
/* OPTIONAL key length */
if (seqEnd > inOutIdx && input[inOutIdx] == ASN_INTEGER) {
if (GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {
if (seqEnd > inOutIdx) {
word32 localIdx = inOutIdx;
byte tag;
if (GetASNTag(input, &localIdx, &tag, sz) < 0) {
ERROR_OUT(ASN_PARSE_E, exit_tte);
}
if (tag == ASN_INTEGER &&
GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {
ERROR_OUT(ASN_PARSE_E, exit_tte);
}
}
@ -3749,6 +3818,7 @@ int DecryptContent(byte* input, word32 sz,const char* password, int passwordSz)
byte salt[MAX_SALT_SIZE];
byte cbcIv[MAX_IV_SIZE];
#endif
byte tag;
if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) {
ERROR_OUT(ASN_PARSE_E, exit_dc);
@ -3805,8 +3875,15 @@ int DecryptContent(byte* input, word32 sz,const char* password, int passwordSz)
}
/* OPTIONAL key length */
if (seqEnd > inOutIdx && input[inOutIdx] == ASN_INTEGER) {
if (GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {
if (seqEnd > inOutIdx) {
word32 localIdx = inOutIdx;
if (GetASNTag(input, &localIdx, &tag, sz) < 0) {
ERROR_OUT(ASN_PARSE_E, exit_dc);
}
if (tag == ASN_INTEGER &&
GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {
ERROR_OUT(ASN_PARSE_E, exit_dc);
}
}
@ -3847,7 +3924,11 @@ int DecryptContent(byte* input, word32 sz,const char* password, int passwordSz)
inOutIdx += length;
}
if (input[inOutIdx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
if (GetASNTag(input, &inOutIdx, &tag, sz) < 0) {
ERROR_OUT(ASN_PARSE_E, exit_dc);
}
if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {
ERROR_OUT(ASN_PARSE_E, exit_dc);
}
@ -3884,7 +3965,8 @@ int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
int ret = 0;
int length = 0;
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
byte b;
word32 localIdx;
byte tag;
#endif
if (input == NULL || inOutIdx == NULL)
@ -3894,11 +3976,11 @@ int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
return ASN_PARSE_E;
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
if ((*inOutIdx + 1) > inSz)
localIdx = *inOutIdx;
if (GetASNTag(input, &localIdx, &tag, inSz) < 0)
return BUFFER_E;
b = input[*inOutIdx];
if (b != ASN_INTEGER) {
if (tag != ASN_INTEGER) {
/* not from decoded cert, will have algo id, skip past */
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
return ASN_PARSE_E;
@ -3910,7 +3992,12 @@ int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
if (*inOutIdx >= inSz) {
return BUFFER_E;
}
if (input[*inOutIdx] == ASN_TAG_NULL) {
localIdx = *inOutIdx;
if (GetASNTag(input, &localIdx, &tag, inSz) < 0)
return ASN_PARSE_E;
if (tag == ASN_TAG_NULL) {
ret = GetASNNull(input, inOutIdx, inSz);
if (ret != 0)
return ret;
@ -4498,10 +4585,15 @@ static int GetKey(DecodedCert* cert)
int ret;
byte seq[5];
int pubLen = length + 1 + SetLength(length, seq);
word32 localIdx;
byte* publicKey;
byte tag;
if (cert->source[cert->srcIdx] !=
(ASN_SEQUENCE | ASN_CONSTRUCTED)) {
localIdx = cert->srcIdx;
if (GetASNTag(cert->source, &localIdx, &tag, cert->maxIdx) < 0)
return ASN_PARSE_E;
if (tag != (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
if (GetObjectId(cert->source, &cert->srcIdx,
&cert->pkCurveOID, oidCurveType, cert->maxIdx) < 0)
return ASN_PARSE_E;
@ -4647,7 +4739,8 @@ static int GetName(DecodedCert* cert, int nameType)
int ret;
char* full;
byte* hash;
word32 idx;
word32 idx, localIdx = 0;
byte tag;
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
DecodedName* dName =
(nameType == ISSUER) ? &cert->issuerName : &cert->subjectName;
@ -4672,7 +4765,12 @@ static int GetName(DecodedCert* cert, int nameType)
return BUFFER_E;
}
if (cert->source[cert->srcIdx] == ASN_OBJECT_ID) {
localIdx = cert->srcIdx;
if (GetASNTag(cert->source, &localIdx, &tag, cert->maxIdx) < 0) {
return ASN_PARSE_E;
}
if (tag == ASN_OBJECT_ID) {
WOLFSSL_MSG("Trying optional prefix...");
if (SkipObjectId(cert->source, &cert->srcIdx, cert->maxIdx) < 0)
@ -6843,6 +6941,7 @@ static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert)
word32 lenStartIdx = idx;
word32 oid = 0;
int ret;
byte tag;
if (GetLength(input, &idx, &strLen, sz) < 0) {
WOLFSSL_MSG("\tfail: other name length");
@ -6861,7 +6960,11 @@ static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert)
return ASN_PARSE_E;
}
if (input[idx++] != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
if (GetASNTag(input, &idx, &tag, sz) < 0) {
return ASN_PARSE_E;
}
if (tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
WOLFSSL_MSG("\twrong type");
return ASN_PARSE_E;
}
@ -6955,8 +7058,9 @@ static int DecodeBasicCaConstraint(const byte* input, int sz, DecodedCert* cert)
cert->isCA = (byte)ret;
/* If there isn't any more data, return. */
if (idx >= (word32)sz)
if (idx >= (word32)sz) {
return 0;
}
ret = GetInteger7Bit(input, &idx, sz);
if (ret < 0)
@ -6976,8 +7080,9 @@ static int DecodeBasicCaConstraint(const byte* input, int sz, DecodedCert* cert)
static int DecodeCrlDist(const byte* input, int sz, DecodedCert* cert)
{
word32 idx = 0;
word32 idx = 0, localIdx;
int length = 0;
byte tag = 0;
WOLFSSL_ENTER("DecodeCrlDist");
@ -6992,20 +7097,26 @@ static int DecodeCrlDist(const byte* input, int sz, DecodedCert* cert)
/* The Distribution Point has three explicit optional members
* First check for a DistributionPointName
*/
if (input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
localIdx = idx;
if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
{
idx++;
if (GetLength(input, &idx, &length, sz) < 0)
return ASN_PARSE_E;
if (input[idx] ==
(ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CRLDP_FULL_NAME))
localIdx = idx;
if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED |
CRLDP_FULL_NAME))
{
idx++;
if (GetLength(input, &idx, &length, sz) < 0)
return ASN_PARSE_E;
if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI))
localIdx = idx;
if (GetASNTag(input, &localIdx, &tag, sz) == 0 &&
tag == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI))
{
idx++;
if (GetLength(input, &idx, &length, sz) < 0)
@ -7026,8 +7137,10 @@ static int DecodeCrlDist(const byte* input, int sz, DecodedCert* cert)
}
/* Check for reasonFlags */
localIdx = idx;
if (idx < (word32)sz &&
input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
GetASNTag(input, &localIdx, &tag, sz) == 0 &&
tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
{
idx++;
if (GetLength(input, &idx, &length, sz) < 0)
@ -7036,8 +7149,10 @@ static int DecodeCrlDist(const byte* input, int sz, DecodedCert* cert)
}
/* Check for cRLIssuer */
localIdx = idx;
if (idx < (word32)sz &&
input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
GetASNTag(input, &localIdx, &tag, sz) == 0 &&
tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
{
idx++;
if (GetLength(input, &idx, &length, sz) < 0)
@ -7063,7 +7178,7 @@ static int DecodeAuthInfo(const byte* input, int sz, DecodedCert* cert)
{
word32 idx = 0;
int length = 0;
byte b;
byte b = 0;
word32 oid;
WOLFSSL_ENTER("DecodeAuthInfo");
@ -7083,7 +7198,9 @@ static int DecodeAuthInfo(const byte* input, int sz, DecodedCert* cert)
/* Only supporting URIs right now. */
b = input[idx++];
if (GetASNTag(input, &idx, &b, sz) < 0)
return ASN_PARSE_E;
if (GetLength(input, &idx, &length, sz) < 0)
return ASN_PARSE_E;
@ -7105,6 +7222,7 @@ static int DecodeAuthKeyId(const byte* input, int sz, DecodedCert* cert)
{
word32 idx = 0;
int length = 0, ret = 0;
byte tag;
WOLFSSL_ENTER("DecodeAuthKeyId");
@ -7113,7 +7231,11 @@ static int DecodeAuthKeyId(const byte* input, int sz, DecodedCert* cert)
return ASN_PARSE_E;
}
if (input[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
if (GetASNTag(input, &idx, &tag, sz) < 0) {
return ASN_PARSE_E;
}
if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {
WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available\n");
return 0;
}
@ -7564,13 +7686,18 @@ static int DecodeCertExtensions(DecodedCert* cert)
word32 oid;
byte critical = 0;
byte criticalFail = 0;
byte tag = 0;
WOLFSSL_ENTER("DecodeCertExtensions");
if (input == NULL || sz == 0)
return BAD_FUNC_ARG;
if (input[idx++] != ASN_EXTENSIONS) {
if (GetASNTag(input, &idx, &tag, sz) < 0) {
return ASN_PARSE_E;
}
if (tag != ASN_EXTENSIONS) {
WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
return ASN_PARSE_E;
}
@ -7586,6 +7713,8 @@ static int DecodeCertExtensions(DecodedCert* cert)
}
while (idx < (word32)sz) {
word32 localIdx;
if (GetSequence(input, &idx, &length, sz) < 0) {
WOLFSSL_MSG("\tfail: should be a SEQUENCE");
return ASN_PARSE_E;
@ -7604,14 +7733,17 @@ static int DecodeCertExtensions(DecodedCert* cert)
return BUFFER_E;
}
if (input[idx] == ASN_BOOLEAN) {
ret = GetBoolean(input, &idx, sz);
if (ret < 0) {
WOLFSSL_MSG("\tfail: critical boolean");
return ret;
}
localIdx = idx;
if (GetASNTag(input, &localIdx, &tag, sz) == 0) {
if (tag == ASN_BOOLEAN) {
ret = GetBoolean(input, &idx, sz);
if (ret < 0) {
WOLFSSL_MSG("\tfail: critical boolean");
return ret;
}
critical = (byte)ret;
critical = (byte)ret;
}
}
/* process the extension based on the OID */
@ -7899,6 +8031,9 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap,
int extAuthKeyIdSet = 0;
#endif
int ret = 0;
word32 localIdx;
byte tag;
if (cert == NULL) {
return BAD_FUNC_ARG;
@ -7929,11 +8064,14 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap,
}
if (ret == 0) {
/* version - optional */
if (cert[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
idx++;
if (GetLength(cert, &idx, &len, certSz) < 0)
ret = ASN_PARSE_E;
idx += len;
localIdx = idx;
if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
idx++;
if (GetLength(cert, &idx, &len, certSz) < 0)
ret = ASN_PARSE_E;
idx += len;
}
}
}
@ -7989,11 +8127,14 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap,
}
if (ret == 0) {
/* issuerUniqueID - optional */
if (cert[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
idx++;
if (GetLength(cert, &idx, &len, certSz) < 0)
ret = ASN_PARSE_E;
idx += len;
localIdx = idx;
if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
idx++;
if (GetLength(cert, &idx, &len, certSz) < 0)
ret = ASN_PARSE_E;
idx += len;
}
}
}
if (ret == 0) {
@ -8002,11 +8143,14 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap,
}
if (ret == 0) {
/* subjectUniqueID - optional */
if (cert[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) {
idx++;
if (GetLength(cert, &idx, &len, certSz) < 0)
ret = ASN_PARSE_E;
idx += len;
localIdx = idx;
if (GetASNTag(cert, &localIdx, &tag, certSz) == 0) {
if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) {
idx++;
if (GetLength(cert, &idx, &len, certSz) < 0)
ret = ASN_PARSE_E;
idx += len;
}
}
}
@ -8015,7 +8159,9 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap,
ret = BUFFER_E;
}
/* extensions - optional */
if (ret == 0 && cert[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)) {
localIdx = idx;
if (ret == 0 && GetASNTag(cert, &localIdx, &tag, certSz) == 0 &&
tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)) {
idx++;
if (GetLength(cert, &idx, &extLen, certSz) < 0)
ret = ASN_PARSE_E;
@ -8036,9 +8182,17 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap,
certSz) < 0) {
ret = ASN_PARSE_E;
}
if (ret == 0) {
if ((extIdx + 1) > certSz)
ret = BUFFER_E;
}
}
if (ret == 0) {
if (cert[extIdx] == ASN_BOOLEAN) {
localIdx = extIdx;
if (GetASNTag(cert, &localIdx, &tag, certSz) == 0 &&
tag == ASN_BOOLEAN) {
if (GetBoolean(cert, &extIdx, certSz) < 0)
ret = ASN_PARSE_E;
}
@ -8055,8 +8209,12 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap,
if (GetSequence(cert, &extIdx, &extLen, certSz) < 0)
ret = ASN_PARSE_E;
if (ret == 0 && (extIdx + 1) >= certSz)
ret = BUFFER_E;
if (ret == 0 &&
cert[extIdx++] == (ASN_CONTEXT_SPECIFIC | 0)) {
GetASNTag(cert, &extIdx, &tag, certSz) == 0 &&
tag == (ASN_CONTEXT_SPECIFIC | 0)) {
if (GetLength(cert, &extIdx, &extLen, certSz) <= 0)
ret = ASN_PARSE_E;
if (ret == 0) {
@ -12942,16 +13100,19 @@ int wc_SetExtKeyUsageOID(Cert *cert, const char *in, word32 sz, byte idx,
static int SetAltNamesFromDcert(Cert* cert, DecodedCert* decoded)
{
int ret = 0;
byte tag;
if (decoded->extensions) {
byte b;
int length;
word32 maxExtensionsIdx;
decoded->srcIdx = decoded->extensionsIdx;
b = decoded->source[decoded->srcIdx++];
if (GetASNTag(decoded->source, &decoded->srcIdx, &tag, decoded->maxIdx)
!= 0) {
return ASN_PARSE_E;
}
if (b != ASN_EXTENSIONS) {
if (tag != ASN_EXTENSIONS) {
ret = ASN_PARSE_E;
}
else if (GetLength(decoded->source, &decoded->srcIdx, &length,
@ -13678,12 +13839,15 @@ static int ASNToHexString(const byte* input, word32* inOutIdx, char** out,
int len;
int i;
char* str;
word32 localIdx;
byte tag;
if (*inOutIdx >= inSz) {
return BUFFER_E;
}
if (input[*inOutIdx] == ASN_INTEGER) {
localIdx = *inOutIdx;
if (GetASNTag(input, &localIdx, &tag, inSz) == 0 && tag == ASN_INTEGER) {
if (GetASNInt(input, inOutIdx, &len, inSz) < 0)
return ASN_PARSE_E;
}
@ -13710,7 +13874,8 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
int length;
int ret;
int curve_id = ECC_CURVE_DEF;
word32 oidSum;
word32 oidSum, localIdx;
byte tag;
if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
return BAD_FUNC_ARG;
@ -13729,7 +13894,9 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
return BUFFER_E;
}
if (input[*inOutIdx] == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
localIdx = *inOutIdx;
if (GetASNTag(input, &localIdx, &tag, inSz) == 0 &&
tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
#ifdef WOLFSSL_CUSTOM_CURVES
ecc_set_type* curve;
int len;
@ -13781,7 +13948,9 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
key->heap, DYNAMIC_TYPE_ECC_BUFFER);
}
if (ret == 0) {
if (*inOutIdx < inSz && input[*inOutIdx] == ASN_BIT_STRING) {
localIdx = *inOutIdx;
if (*inOutIdx < inSz && GetASNTag(input, &localIdx, &tag, inSz)
== 0 && tag == ASN_BIT_STRING) {
len = 0;
ret = GetASNHeader(input, ASN_BIT_STRING, inOutIdx, &len, inSz);
*inOutIdx += len;
@ -14291,20 +14460,28 @@ static int GetBasicDate(const byte* source, word32* idx, byte* date,
#ifdef HAVE_OCSP
static int GetEnumerated(const byte* input, word32* inOutIdx, int *value)
static int GetEnumerated(const byte* input, word32* inOutIdx, int *value,
int sz)
{
word32 idx = *inOutIdx;
word32 len;
byte tag;
WOLFSSL_ENTER("GetEnumerated");
*value = 0;
if (input[idx++] != ASN_ENUMERATED)
if (GetASNTag(input, &idx, &tag, sz) < 0)
return ASN_PARSE_E;
if (tag != ASN_ENUMERATED)
return ASN_PARSE_E;
if ((int)idx >= sz)
return BUFFER_E;
len = input[idx++];
if (len > 4)
if (len > 4 || (int)len > sz)
return ASN_PARSE_E;
while (len--) {
@ -14320,10 +14497,11 @@ static int GetEnumerated(const byte* input, word32* inOutIdx, int *value)
static int DecodeSingleResponse(byte* source,
word32* ioIndex, OcspResponse* resp, word32 size)
{
word32 idx = *ioIndex, prevIndex, oid;
word32 idx = *ioIndex, prevIndex, oid, localIdx;
int length, wrapperSz;
CertStatus* cs = resp->status;
int ret;
byte tag;
WOLFSSL_ENTER("DecodeSingleResponse");
@ -14401,8 +14579,10 @@ static int DecodeSingleResponse(byte* source,
/* The following items are optional. Only check for them if there is more
* unprocessed data in the singleResponse wrapper. */
localIdx = idx;
if (((int)(idx - prevIndex) < wrapperSz) &&
(source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)))
GetASNTag(source, &localIdx, &tag, size) == 0 &&
tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
{
idx++;
if (GetLength(source, &idx, &length, size) < 0)
@ -14421,8 +14601,11 @@ static int DecodeSingleResponse(byte* source,
#endif
#endif
}
localIdx = idx;
if (((int)(idx - prevIndex) < wrapperSz) &&
(source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)))
GetASNTag(source, &localIdx, &tag, size) == 0 &&
tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
{
idx++;
if (GetLength(source, &idx, &length, size) < 0)
@ -14443,13 +14626,17 @@ static int DecodeOcspRespExtensions(byte* source,
int ext_bound; /* boundary index for the sequence of extensions */
word32 oid;
int ret;
byte tag;
WOLFSSL_ENTER("DecodeOcspRespExtensions");
if ((idx + 1) > sz)
return BUFFER_E;
if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
if (GetASNTag(source, &idx, &tag, sz) < 0)
return ASN_PARSE_E;
if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
return ASN_PARSE_E;
if (GetLength(source, &idx, &length, sz) < 0)
@ -14461,6 +14648,8 @@ static int DecodeOcspRespExtensions(byte* source,
ext_bound = idx + length;
while (idx < (word32)ext_bound) {
word32 localIdx;
if (GetSequence(source, &idx, &length, sz) < 0) {
WOLFSSL_MSG("\tfail: should be a SEQUENCE");
return ASN_PARSE_E;
@ -14478,7 +14667,8 @@ static int DecodeOcspRespExtensions(byte* source,
return BUFFER_E;
}
if (source[idx] == ASN_BOOLEAN) {
localIdx = idx;
if (GetASNTag(source, &localIdx, &tag, sz) == 0 && tag == ASN_BOOLEAN) {
WOLFSSL_MSG("\tfound optional critical flag, moving past");
ret = GetBoolean(source, &idx, sz);
if (ret < 0)
@ -14510,11 +14700,11 @@ static int DecodeOcspRespExtensions(byte* source,
static int DecodeResponseData(byte* source,
word32* ioIndex, OcspResponse* resp, word32 size)
{
word32 idx = *ioIndex, prev_idx;
word32 idx = *ioIndex, prev_idx, localIdx;
int length;
int version;
word32 responderId = 0;
int ret;
byte tag;
WOLFSSL_ENTER("DecodeResponseData");
@ -14528,7 +14718,9 @@ static int DecodeResponseData(byte* source,
* item isn't an EXPLICIT[0], then set version to zero and move
* onto the next item.
*/
if (source[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
localIdx = idx;
if (GetASNTag(source, &localIdx, &tag, size) == 0 &&
tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
{
idx += 2; /* Eat the value and length */
if (GetMyVersion(source, &idx, &version, size) < 0)
@ -14536,10 +14728,12 @@ static int DecodeResponseData(byte* source,
} else
version = 0;
responderId = source[idx++];
if ((responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) ||
(responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)))
localIdx = idx;
if (GetASNTag(source, &localIdx, &tag, size) == 0 &&
( tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1) ||
tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2) ))
{
idx++; /* advance past ASN tag */
if (GetLength(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
idx += length;
@ -14574,10 +14768,14 @@ static int DecodeCerts(byte* source,
word32* ioIndex, OcspResponse* resp, word32 size)
{
word32 idx = *ioIndex;
byte tag;
WOLFSSL_ENTER("DecodeCerts");
if (source[idx++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
if (GetASNTag(source, &idx, &tag, size) < 0)
return ASN_PARSE_E;
if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
{
int length;
@ -14743,6 +14941,7 @@ int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify)
byte* source = resp->source;
word32 size = resp->maxIdx;
word32 oid;
byte tag;
WOLFSSL_ENTER("OcspResponseDecode");
@ -14751,7 +14950,7 @@ int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify)
return ASN_PARSE_E;
/* First get the responseStatus, an ENUMERATED */
if (GetEnumerated(source, &idx, &resp->responseStatus) < 0)
if (GetEnumerated(source, &idx, &resp->responseStatus, size) < 0)
return ASN_PARSE_E;
if (resp->responseStatus != OCSP_SUCCESSFUL)
@ -14760,7 +14959,9 @@ int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify)
/* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
if (idx >= size)
return ASN_INPUT_E;
if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
if (GetASNTag(source, &idx, &tag, size) < 0)
return ASN_PARSE_E;
if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
return ASN_PARSE_E;
if (GetLength(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
@ -15070,10 +15271,12 @@ WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
int length; /* length of all distinguished names */
int ret;
word32 dummy;
byte tag;
WOLFSSL_ENTER("GetNameHash");
if (source[*idx] == ASN_OBJECT_ID) {
dummy = *idx;
if (GetASNTag(source, &dummy, &tag, maxIdx) == 0 && tag == ASN_OBJECT_ID) {
WOLFSSL_MSG("Trying optional prefix...");
if (GetLength(source, idx, &length, maxIdx) < 0)
@ -15228,9 +15431,10 @@ int VerifyCRL_Signature(SignatureCtx* sigCtx, const byte* toBeSigned,
int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
{
int version, len, doNextDate = 1;
word32 oid, idx = 0, dateIdx;
word32 oid, idx = 0, dateIdx, localIdx;
Signer* ca = NULL;
SignatureCtx sigCtx;
byte tag;
WOLFSSL_MSG("ParseCRL");
@ -15251,7 +15455,8 @@ int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
dcrl->sigIndex = len + idx;
/* may have version */
if (buff[idx] == ASN_INTEGER) {
localIdx = idx;
if (GetASNTag(buff, &localIdx, &tag, sz) == 0 && tag == ASN_INTEGER) {
if (GetMyVersion(buff, &idx, &version, sz) < 0)
return ASN_PARSE_E;
}
@ -15288,7 +15493,9 @@ int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
#endif
}
if (idx != dcrl->sigIndex && buff[idx] != CRL_EXTENSIONS) {
localIdx = idx;
if (idx != dcrl->sigIndex &&
GetASNTag(buff, &localIdx, &tag, sz) == 0 && tag != CRL_EXTENSIONS) {
if (GetSequence(buff, &idx, &len, sz) < 0)
return ASN_PARSE_E;

View File

@ -198,6 +198,7 @@ static int GetSafeContent(WC_PKCS12* pkcs12, const byte* input,
word32 localIdx = *idx;
int ret;
int size = 0;
byte tag;
safe = (AuthenticatedSafe*)XMALLOC(sizeof(AuthenticatedSafe), pkcs12->heap,
DYNAMIC_TYPE_PKCS);
@ -215,7 +216,12 @@ static int GetSafeContent(WC_PKCS12* pkcs12, const byte* input,
safe->oid = oid;
/* check tag, length */
if (input[localIdx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
if (GetASNTag(input, &localIdx, &tag, maxIdx) < 0) {
freeSafe(safe, pkcs12->heap);
return ASN_PARSE_E;
}
if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
WOLFSSL_MSG("Unexpected tag in PKCS12 DER");
freeSafe(safe, pkcs12->heap);
return ASN_PARSE_E;
@ -233,7 +239,12 @@ static int GetSafeContent(WC_PKCS12* pkcs12, const byte* input,
case WC_PKCS12_DATA:
WOLFSSL_MSG("Found PKCS12 OBJECT: DATA");
/* get octets holding contents */
if (input[localIdx++] != ASN_OCTET_STRING) {
if (GetASNTag(input, &localIdx, &tag, maxIdx) < 0) {
freeSafe(safe, pkcs12->heap);
return ASN_PARSE_E;
}
if (tag != ASN_OCTET_STRING) {
WOLFSSL_MSG("Wrong tag with content PKCS12 type DATA");
freeSafe(safe, pkcs12->heap);
return ASN_PARSE_E;
@ -347,6 +358,7 @@ static int GetSignData(WC_PKCS12* pkcs12, const byte* mem, word32* idx,
word32 curIdx = *idx;
word32 oid = 0;
int size, ret;
byte tag;
/* Digest Info : Sequence
* DigestAlgorithmIdentifier
@ -380,7 +392,12 @@ static int GetSignData(WC_PKCS12* pkcs12, const byte* mem, word32* idx,
#endif
/* Digest: should be octet type holding digest */
if (mem[curIdx++] != ASN_OCTET_STRING) {
if (GetASNTag(mem, &curIdx, &tag, totalSz) < 0) {
XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
return ASN_PARSE_E;
}
if (tag != ASN_OCTET_STRING) {
WOLFSSL_MSG("Failed to get digest");
XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
return ASN_PARSE_E;
@ -411,7 +428,11 @@ static int GetSignData(WC_PKCS12* pkcs12, const byte* mem, word32* idx,
curIdx += mac->digestSz;
/* get salt, should be octet string */
if (mem[curIdx++] != ASN_OCTET_STRING) {
if (GetASNTag(mem, &curIdx, &tag, totalSz) < 0) {
ERROR_OUT(ASN_PARSE_E, exit_gsd);
}
if (tag != ASN_OCTET_STRING) {
WOLFSSL_MSG("Failed to get salt");
ERROR_OUT(ASN_PARSE_E, exit_gsd);
}
@ -972,13 +993,18 @@ int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
byte* data;
word32 idx = 0;
int size, totalSz;
byte tag;
if (ci->type == WC_PKCS12_ENCRYPTED_DATA) {
int number;
WOLFSSL_MSG("Decrypting PKCS12 Content Info Container");
data = ci->data;
if (data[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
ERROR_OUT(ASN_PARSE_E, exit_pk12par);
}
if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
ERROR_OUT(ASN_PARSE_E, exit_pk12par);
}
if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
@ -1036,13 +1062,21 @@ int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
else { /* type DATA */
WOLFSSL_MSG("Parsing PKCS12 DATA Content Info Container");
data = ci->data;
if (data[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
ERROR_OUT(ASN_PARSE_E, exit_pk12par);
}
if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
ERROR_OUT(ASN_PARSE_E, exit_pk12par);
}
if ((ret = GetLength(data, &idx, &size, ci->dataSz)) <= 0) {
goto exit_pk12par;
}
if (data[idx++] != ASN_OCTET_STRING) {
if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
ERROR_OUT(ASN_PARSE_E, exit_pk12par);
}
if (tag != ASN_OCTET_STRING) {
ERROR_OUT(ASN_PARSE_E, exit_pk12par);
}
if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
@ -1072,8 +1106,10 @@ int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
switch (oid) {
case WC_PKCS12_KeyBag: /* 667 */
WOLFSSL_MSG("PKCS12 Key Bag found");
if (data[idx++] !=
(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
ERROR_OUT(ASN_PARSE_E, exit_pk12par);
}
if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
ERROR_OUT(ASN_PARSE_E, exit_pk12par);
}
if ((ret = GetLength(data, &idx, &size, ci->dataSz)) <= 0) {
@ -1106,8 +1142,10 @@ int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
byte* k;
WOLFSSL_MSG("PKCS12 Shrouded Key Bag found");
if (data[idx++] !=
(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
ERROR_OUT(ASN_PARSE_E, exit_pk12par);
}
if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
ERROR_OUT(ASN_PARSE_E, exit_pk12par);
}
if ((ret = GetLength(data, &idx, &size,
@ -1168,8 +1206,10 @@ int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
{
WC_DerCertList* node;
WOLFSSL_MSG("PKCS12 Cert Bag found");
if (data[idx++] !=
(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
ERROR_OUT(ASN_PARSE_E, exit_pk12par);
}
if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
ERROR_OUT(ASN_PARSE_E, exit_pk12par);
}
if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
@ -1190,15 +1230,21 @@ int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
case WC_PKCS12_CertBag_Type1: /* 675 */
/* type 1 */
WOLFSSL_MSG("PKCS12 cert bag type 1");
if (data[idx++] !=
(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
ERROR_OUT(ASN_PARSE_E, exit_pk12par);
}
if (tag != (ASN_CONSTRUCTED |
ASN_CONTEXT_SPECIFIC)) {
ERROR_OUT(ASN_PARSE_E, exit_pk12par);
}
if ((ret = GetLength(data, &idx, &size, ci->dataSz))
<= 0) {
goto exit_pk12par;
}
if (data[idx++] != ASN_OCTET_STRING) {
if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
ERROR_OUT(ASN_PARSE_E, exit_pk12par);
}
if (tag != ASN_OCTET_STRING) {
ERROR_OUT(ASN_PARSE_E, exit_pk12par);
}

View File

@ -1196,8 +1196,12 @@ static PKCS7DecodedAttrib* findAttrib(PKCS7* pkcs7, const byte* oid, word32 oidS
word32 sz = oidSz;
word32 idx = 0;
int length = 0;
byte tag;
if (list->oid[idx++] != ASN_OBJECT_ID) {
if (GetASNTag(list->oid, &idx, &tag, list->oidSz) < 0) {
return NULL;
}
if (tag != ASN_OBJECT_ID) {
WOLFSSL_MSG("Bad attribute ASN1 syntax");
return NULL;
}
@ -3873,7 +3877,8 @@ static int wc_PKCS7_ParseSignerInfo(PKCS7* pkcs7, byte* in, word32 inSz,
int length;
int version;
word32 sigOID = 0, hashOID = 0;
word32 idx = *idxIn;
word32 idx = *idxIn, localIdx;
byte tag;
WOLFSSL_ENTER("wc_PKCS7_ParseSignerInfo");
/* require a signer if degenerate case not allowed */
@ -3918,8 +3923,9 @@ static int wc_PKCS7_ParseSignerInfo(PKCS7* pkcs7, byte* in, word32 inSz,
if (idx + 1 > inSz)
ret = BUFFER_E;
if (ret == 0 && in[idx] ==
(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
localIdx = idx;
if (ret == 0 && GetASNTag(in, &localIdx, &tag, inSz) == 0 &&
tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
idx++;
if (ret == 0 && GetLength(in, &idx, &length, inSz) <= 0) {
@ -3929,7 +3935,10 @@ static int wc_PKCS7_ParseSignerInfo(PKCS7* pkcs7, byte* in, word32 inSz,
if (idx + 1 > inSz)
ret = BUFFER_E;
if (ret == 0 && in[idx++] != ASN_OCTET_STRING)
if (ret == 0 && GetASNTag(in, &idx, &tag, inSz) < 0)
ret = ASN_PARSE_E;
if (ret == 0 && tag != ASN_OCTET_STRING)
ret = ASN_PARSE_E;
if (ret == 0 && GetLength(in, &idx, &length, inSz) < 0)
@ -3938,7 +3947,9 @@ static int wc_PKCS7_ParseSignerInfo(PKCS7* pkcs7, byte* in, word32 inSz,
else {
/* check if SKID with ASN_CONTEXT_SPECIFIC otherwise in version
* 3 try to get issuerAndSerial */
if (in[idx] == ASN_CONTEXT_SPECIFIC) {
localIdx = idx;
if (GetASNTag(in, &localIdx, &tag, inSz) == 0 &&
tag == ASN_CONTEXT_SPECIFIC) {
idx++;
if (ret == 0 && GetLength(in, &idx, &length, inSz) < 0)
ret = ASN_PARSE_E;
@ -3971,8 +3982,9 @@ static int wc_PKCS7_ParseSignerInfo(PKCS7* pkcs7, byte* in, word32 inSz,
pkcs7->hashOID = (int)hashOID;
/* Get the IMPLICIT[0] SET OF signedAttributes */
if (ret == 0 && in[idx] ==
(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
localIdx = idx;
if (ret == 0 && GetASNTag(in, &localIdx, &tag, inSz) == 0 &&
tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
idx++;
if (GetLength(in, &idx, &length, inSz) < 0)
@ -4042,6 +4054,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
word32 localIdx, start;
byte degenerate = 0;
byte detached = 0;
byte tag = 0;
#ifdef ASN_BER_TO_DER
byte* der;
#endif
@ -4165,8 +4178,10 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
}
/* get the ContentInfo content */
if (ret == 0 && pkiMsg[idx++] !=
(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, totalSz) != 0)
ret = ASN_PARSE_E;
if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
ret = ASN_PARSE_E;
if (ret == 0 && GetLength_ex(pkiMsg, &idx, &length, totalSz,
@ -4266,7 +4281,10 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
break;
}
if (pkiMsg[localIdx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) != 0)
ret = ASN_PARSE_E;
if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
ret = ASN_PARSE_E;
if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, &length, pkiMsgSz,
@ -4278,10 +4296,12 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
}
/* get length of content in the case that there is multiple parts */
if (ret == 0 && pkiMsg[localIdx] == (ASN_OCTET_STRING | ASN_CONSTRUCTED)) {
if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) < 0)
ret = ASN_PARSE_E;
if (ret == 0 && tag == (ASN_OCTET_STRING | ASN_CONSTRUCTED)) {
multiPart = 1;
localIdx++;
/* Get length of all OCTET_STRINGs. */
if (GetLength_ex(pkiMsg, &localIdx, &contentLen, pkiMsgSz,
NO_USER_CHECK) < 0)
@ -4293,7 +4313,11 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
ret = BUFFER_E;
}
if (ret == 0 && pkiMsg[localIdx++] != ASN_OCTET_STRING)
if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz)
!= 0)
ret = ASN_PARSE_E;
if (ret == 0 && tag != ASN_OCTET_STRING)
ret = ASN_PARSE_E;
if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, &length, pkiMsgSz,
@ -4310,7 +4334,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
/* get length of content in case of single part */
if (ret == 0 && !multiPart) {
if (pkiMsg[localIdx++] != ASN_OCTET_STRING)
if (ret == 0 && tag != ASN_OCTET_STRING)
ret = ASN_PARSE_E;
if (ret == 0 && GetLength_ex(pkiMsg, &localIdx,
@ -4437,7 +4461,9 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
start = localIdx;
/* Use the data from each OCTET_STRING. */
while (ret == 0 && localIdx < start + contentLen) {
if (pkiMsg[localIdx++] != ASN_OCTET_STRING)
if (GetASNTag(pkiMsg, &localIdx, &tag, totalSz) < 0)
ret = ASN_PARSE_E;
if (ret == 0 && tag != ASN_OCTET_STRING)
ret = ASN_PARSE_E;
if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, totalSz) < 0)
@ -4544,8 +4570,9 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
ret = BUFFER_E;
length = 0; /* set length to 0 to check if reading in any certs */
if (ret == 0 && pkiMsg2[idx] ==
(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
localIdx = idx;
if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag, pkiMsg2Sz) == 0
&& tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
idx++;
if (GetLength_ex(pkiMsg2, &idx, &length, maxIdx, NO_USER_CHECK)
< 0)
@ -4627,7 +4654,10 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
if (length < MAX_LENGTH_SZ + ASN_TAG_SZ)
ret = BUFFER_E;
if (pkiMsg2[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
if (ret == 0)
ret = GetASNTag(pkiMsg2, &certIdx, &tag, pkiMsg2Sz);
if (ret == 0 && tag == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
if (GetLength(pkiMsg2, &certIdx, &certSz, pkiMsg2Sz) < 0)
ret = ASN_PARSE_E;
@ -4678,8 +4708,14 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
certIdx + 1 < (word32)length; i++) {
localIdx = certIdx;
if (pkiMsg2[certIdx++] ==
(ASN_CONSTRUCTED | ASN_SEQUENCE)) {
if (ret == 0 && GetASNTag(pkiMsg2, &certIdx, &tag,
pkiMsg2Sz) < 0) {
ret = ASN_PARSE_E;
break;
}
if (ret == 0 &&
tag == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
if (GetLength(pkiMsg2, &certIdx, &sz,
pkiMsg2Sz) < 0) {
ret = ASN_PARSE_E;
@ -4793,8 +4829,9 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
if (ret == 0 && idx >= maxIdx)
ret = BUFFER_E;
if (ret == 0 && pkiMsg2[idx] ==
(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
localIdx = idx;
if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag, pkiMsg2Sz) == 0
&& tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
idx++;
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
ret = ASN_PARSE_E;
@ -4864,7 +4901,9 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
ret = BUFFER_E;
/* Get the signature */
if (ret == 0 && pkiMsg2[idx] == ASN_OCTET_STRING) {
localIdx = idx;
if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag,
pkiMsg2Sz) == 0 && tag == ASN_OCTET_STRING) {
idx++;
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
@ -7870,6 +7909,8 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz,
byte* outKey = NULL;
byte* pkiMsg = in;
word32 pkiMsgSz = inSz;
byte tag;
#ifndef NO_PKCS7_STREAM
word32 tmpIdx = *idx;
@ -8012,16 +8053,20 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz,
#endif
} else {
/* remove SubjectKeyIdentifier */
if (pkiMsg[(*idx)++] !=
(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
return ASN_PARSE_E;
if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
return ASN_PARSE_E;
if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
return ASN_PARSE_E;
if (pkiMsg[(*idx)++] != ASN_OCTET_STRING)
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
return ASN_PARSE_E;
if (tag != ASN_OCTET_STRING)
return ASN_PARSE_E;
if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
@ -8043,9 +8088,11 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz,
return ALGO_ID_E;
/* read encryptedKey */
if (pkiMsg[(*idx)++] != ASN_OCTET_STRING) {
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
return ASN_PARSE_E;
if (tag != ASN_OCTET_STRING)
return ASN_PARSE_E;
}
if (GetLength(pkiMsg, idx, &encryptedKeySz, pkiMsgSz) < 0) {
return ASN_PARSE_E;
@ -8183,13 +8230,14 @@ static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari,
int ret, length;
word32 keyOID, oidSum = 0;
int curve_id = ECC_CURVE_DEF;
byte tag;
if (kari == NULL || pkiMsg == NULL || idx == NULL)
return BAD_FUNC_ARG;
/* remove OriginatorIdentifierOrKey */
if (pkiMsg[*idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
(*idx)++;
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) == 0 &&
tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
return ASN_PARSE_E;
@ -8198,8 +8246,8 @@ static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari,
}
/* remove OriginatorPublicKey */
if (pkiMsg[*idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
(*idx)++;
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) == 0 &&
tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
return ASN_PARSE_E;
@ -8224,13 +8272,19 @@ static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari,
}
/* remove ECPoint BIT STRING */
if ((pkiMsgSz > (*idx + 1)) && (pkiMsg[(*idx)++] != ASN_BIT_STRING))
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
return ASN_PARSE_E;
if (tag != ASN_BIT_STRING)
return ASN_PARSE_E;
if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
return ASN_PARSE_E;
if ((pkiMsgSz < (*idx + 1)) || (pkiMsg[(*idx)++] != 0x00))
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
return ASN_EXPECT_0_E;
if (tag != ASN_OTHER_TYPE)
return ASN_EXPECT_0_E;
/* get sender ephemeral public ECDSA key */
@ -8263,6 +8317,7 @@ static int wc_PKCS7_KariGetUserKeyingMaterial(WC_PKCS7_KARI* kari,
{
int length;
word32 savedIdx;
byte tag;
if (kari == NULL || pkiMsg == NULL || idx == NULL)
return BAD_FUNC_ARG;
@ -8270,7 +8325,11 @@ static int wc_PKCS7_KariGetUserKeyingMaterial(WC_PKCS7_KARI* kari,
savedIdx = *idx;
/* starts with EXPLICIT [1] */
if (pkiMsg[(*idx)++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
*idx = savedIdx;
return 0;
}
if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
*idx = savedIdx;
return 0;
}
@ -8281,8 +8340,11 @@ static int wc_PKCS7_KariGetUserKeyingMaterial(WC_PKCS7_KARI* kari,
}
/* get OCTET STRING */
if ( (pkiMsgSz > ((*idx) + 1)) &&
(pkiMsg[(*idx)++] != ASN_OCTET_STRING) ) {
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
*idx = savedIdx;
return 0;
}
if (tag != ASN_OCTET_STRING) {
*idx = savedIdx;
return 0;
}
@ -8350,15 +8412,18 @@ static int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari,
int* recipFound, byte* rid)
{
int length;
byte tag;
if (kari == NULL || pkiMsg == NULL || idx == NULL || recipFound == NULL ||
rid == NULL)
return BAD_FUNC_ARG;
/* remove RecipientKeyIdentifier IMPLICIT [0] */
if ( (pkiMsgSz > (*idx + 1)) &&
(pkiMsg[(*idx)++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) ) {
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
return ASN_PARSE_E;
}
if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
return ASN_PARSE_E;
@ -8367,8 +8432,11 @@ static int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari,
}
/* remove SubjectKeyIdentifier */
if ( (pkiMsgSz > (*idx + 1)) &&
(pkiMsg[(*idx)++] != ASN_OCTET_STRING) )
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
return ASN_PARSE_E;
}
if (tag != ASN_OCTET_STRING)
return ASN_PARSE_E;
if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
@ -8485,6 +8553,8 @@ static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari,
{
int length;
int ret = 0;
byte tag;
word32 localIdx;
if (kari == NULL || pkiMsg == NULL || idx == NULL ||
recipFound == NULL || encryptedKey == NULL)
@ -8500,9 +8570,11 @@ static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari,
/* KeyAgreeRecipientIdentifier is CHOICE of IssuerAndSerialNumber
* or [0] IMMPLICIT RecipientKeyIdentifier */
if ( (pkiMsgSz > (*idx + 1)) &&
(pkiMsg[*idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) ) {
localIdx = *idx;
if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) < 0)
return ASN_PARSE_E;
if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
/* try to get RecipientKeyIdentifier */
ret = wc_PKCS7_KariGetSubjectKeyIdentifier(kari, pkiMsg, pkiMsgSz,
idx, recipFound, rid);
@ -8517,8 +8589,10 @@ static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari,
return ret;
/* remove EncryptedKey */
if ( (pkiMsgSz > (*idx + 1)) &&
(pkiMsg[(*idx)++] != ASN_OCTET_STRING) )
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
return ASN_PARSE_E;
if (tag != ASN_OCTET_STRING)
return ASN_PARSE_E;
if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
@ -8708,6 +8782,7 @@ static int wc_PKCS7_DecryptPwri(PKCS7* pkcs7, byte* in, word32 inSz,
word32 kdfAlgoId, pwriEncAlgoId, keyEncAlgoId, cekSz;
byte* pkiMsg = in;
word32 pkiMsgSz = inSz;
byte tag;
#ifndef NO_PKCS7_STREAM
word32 tmpIdx = *idx;
long rc;
@ -8732,7 +8807,10 @@ static int wc_PKCS7_DecryptPwri(PKCS7* pkcs7, byte* in, word32 inSz,
pkiMsgSz = (word32)rc;
#endif
/* remove KeyDerivationAlgorithmIdentifier */
if (pkiMsg[(*idx)++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
return ASN_PARSE_E;
if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
return ASN_PARSE_E;
if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
@ -8747,10 +8825,11 @@ static int wc_PKCS7_DecryptPwri(PKCS7* pkcs7, byte* in, word32 inSz,
return ASN_PARSE_E;
/* get KDF salt OCTET STRING */
if ( (pkiMsgSz > ((*idx) + 1)) &&
(pkiMsg[(*idx)++] != ASN_OCTET_STRING) ) {
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
return ASN_PARSE_E;
if (tag != ASN_OCTET_STRING)
return ASN_PARSE_E;
}
if (GetLength(pkiMsg, idx, &saltSz, pkiMsgSz) < 0)
return ASN_PARSE_E;
@ -8800,8 +8879,12 @@ static int wc_PKCS7_DecryptPwri(PKCS7* pkcs7, byte* in, word32 inSz,
}
/* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
if ( (pkiMsgSz > ((*idx) + 1)) &&
(pkiMsg[(*idx)++] != ASN_OCTET_STRING) ) {
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
return ASN_PARSE_E;
}
if (tag != ASN_OCTET_STRING) {
XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
return ASN_PARSE_E;
}
@ -8821,8 +8904,12 @@ static int wc_PKCS7_DecryptPwri(PKCS7* pkcs7, byte* in, word32 inSz,
*idx += length;
/* get EncryptedKey */
if ( (pkiMsgSz < ((*idx) + 1)) ||
(pkiMsg[(*idx)++] != ASN_OCTET_STRING) ) {
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
return ASN_PARSE_E;
}
if (tag != ASN_OCTET_STRING) {
XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
return ASN_PARSE_E;
}
@ -8916,8 +9003,8 @@ static int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz,
int length, keySz, dateLen, direction;
byte* keyId = NULL;
const byte* datePtr = NULL;
byte dateFormat;
word32 keyIdSz, kekIdSz, keyWrapOID;
byte dateFormat, tag;
word32 keyIdSz, kekIdSz, keyWrapOID, localIdx;
int ret = 0;
byte* pkiMsg = in;
@ -8952,7 +9039,10 @@ static int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz,
kekIdSz = length;
if (pkiMsg[(*idx)++] != ASN_OCTET_STRING)
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
return ASN_PARSE_E;
if (tag != ASN_OCTET_STRING)
return ASN_PARSE_E;
if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
@ -8964,7 +9054,9 @@ static int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz,
*idx += keyIdSz;
/* may have OPTIONAL GeneralizedTime */
if ((*idx < kekIdSz) && (pkiMsg[*idx] == ASN_GENERALIZED_TIME)) {
localIdx = *idx;
if ((*idx < kekIdSz) && GetASNTag(pkiMsg, &localIdx, &tag,
pkiMsgSz) == 0 && tag == ASN_GENERALIZED_TIME) {
if (wc_GetDateInfo(pkiMsg + *idx, pkiMsgSz, &datePtr, &dateFormat,
&dateLen) != 0) {
return ASN_PARSE_E;
@ -8973,9 +9065,10 @@ static int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz,
}
/* may have OPTIONAL OtherKeyAttribute */
if ((*idx < kekIdSz) && (pkiMsg[*idx] ==
(ASN_SEQUENCE | ASN_CONSTRUCTED))) {
localIdx = *idx;
if ((*idx < kekIdSz) && GetASNTag(pkiMsg, &localIdx, &tag,
pkiMsgSz) == 0 && tag == (ASN_SEQUENCE |
ASN_CONSTRUCTED)) {
if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
return ASN_PARSE_E;
@ -8988,7 +9081,10 @@ static int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz,
return ASN_PARSE_E;
/* get EncryptedKey */
if (pkiMsg[(*idx)++] != ASN_OCTET_STRING)
if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
return ASN_PARSE_E;
if (tag != ASN_OCTET_STRING)
return ASN_PARSE_E;
if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
@ -9317,6 +9413,7 @@ static int wc_PKCS7_DecryptRecipientInfos(PKCS7* pkcs7, byte* in,
int version, ret = 0, length;
byte* pkiMsg = in;
word32 pkiMsgSz = inSz;
byte tag;
#ifndef NO_PKCS7_STREAM
word32 tmpIdx;
long rc;
@ -9416,12 +9513,18 @@ static int wc_PKCS7_DecryptRecipientInfos(PKCS7* pkcs7, byte* in,
#endif
}
else {
word32 localIdx;
/* kari is IMPLICIT[1] */
*idx = savedIdx;
if (pkiMsg[*idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
localIdx = *idx;
if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) != 0) {
/* no room for recipient info */
break;
}
if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
(*idx)++;
if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
return ASN_PARSE_E;
@ -9447,8 +9550,7 @@ static int wc_PKCS7_DecryptRecipientInfos(PKCS7* pkcs7, byte* in,
return ret;
/* kekri is IMPLICIT[2] */
} else if (pkiMsg[*idx] == (ASN_CONSTRUCTED |
ASN_CONTEXT_SPECIFIC | 2)) {
} else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2)) {
(*idx)++;
if (GetLength(pkiMsg, idx, &version, pkiMsgSz) < 0)
@ -9476,8 +9578,7 @@ static int wc_PKCS7_DecryptRecipientInfos(PKCS7* pkcs7, byte* in,
return ret;
/* pwri is IMPLICIT[3] */
} else if (pkiMsg[*idx] == (ASN_CONSTRUCTED |
ASN_CONTEXT_SPECIFIC | 3)) {
} else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 3)) {
#if !defined(NO_PWDBASED) && !defined(NO_SHA)
(*idx)++;
@ -9509,8 +9610,7 @@ static int wc_PKCS7_DecryptRecipientInfos(PKCS7* pkcs7, byte* in,
#endif
/* ori is IMPLICIT[4] */
} else if (pkiMsg[*idx] == (ASN_CONSTRUCTED |
ASN_CONTEXT_SPECIFIC | 4)) {
} else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 4)) {
(*idx)++;
/* found ori */
@ -9552,6 +9652,7 @@ static int wc_PKCS7_ParseToRecipientInfoSet(PKCS7* pkcs7, byte* in,
word32 contentType;
byte* pkiMsg = in;
word32 pkiMsgSz = inSz;
byte tag;
#ifndef NO_PKCS7_STREAM
word32 tmpIdx = 0;
long rc;
@ -9687,8 +9788,11 @@ static int wc_PKCS7_ParseToRecipientInfoSet(PKCS7* pkcs7, byte* in,
}
}
if (ret == 0 && pkiMsg[(*idx)++] !=
(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
if (ret == 0 && GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) != 0)
ret = ASN_PARSE_E;
if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC
| 0))
ret = ASN_PARSE_E;
if (ret == 0 && GetLength_ex(pkiMsg, idx, &length, pkiMsgSz,
@ -9852,6 +9956,8 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in,
byte padLen;
byte* encryptedContent = NULL;
int explicitOctet;
word32 localIdx;
byte tag;
if (pkcs7 == NULL)
return BAD_FUNC_ARG;
@ -9985,7 +10091,11 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in,
}
/* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
if (ret == 0 && pkiMsg[idx++] != ASN_OCTET_STRING) {
if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) != 0) {
ret = ASN_PARSE_E;
}
if (ret == 0 && tag != ASN_OCTET_STRING) {
ret = ASN_PARSE_E;
}
@ -10042,12 +10152,16 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in,
XMEMCPY(tmpIv, &pkiMsg[idx], length);
idx += length;
explicitOctet = pkiMsg[idx] ==
(ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0);
explicitOctet = 0;
localIdx = idx;
if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&
tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
explicitOctet = 1;
}
/* read encryptedContent, cont[0] */
if (ret == 0 && pkiMsg[idx] != (ASN_CONTEXT_SPECIFIC | 0) &&
pkiMsg[idx] != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
if (ret == 0 && tag != (ASN_CONTEXT_SPECIFIC | 0) &&
tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
ret = ASN_PARSE_E;
}
idx++;
@ -10058,7 +10172,12 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in,
}
if (ret == 0 && explicitOctet) {
if (ret == 0 && pkiMsg[idx++] != ASN_OCTET_STRING) {
if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
ret = ASN_PARSE_E;
break;
}
if (tag != ASN_OCTET_STRING) {
ret = ASN_PARSE_E;
break;
}
@ -10716,6 +10835,8 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in,
word32 encodedAttribIdx = 0, encodedAttribSz = 0;
byte* authAttrib = NULL;
int authAttribSz = 0;
word32 localIdx;
byte tag;
if (pkcs7 == NULL)
return BAD_FUNC_ARG;
@ -10845,7 +10966,11 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in,
}
/* get nonce, stored in OPTIONAL parameter of AlgoID */
if (ret == 0 && pkiMsg[idx++] != ASN_OCTET_STRING) {
if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
ret = ASN_PARSE_E;
}
if (ret == 0 && tag != ASN_OCTET_STRING) {
ret = ASN_PARSE_E;
}
@ -10898,16 +11023,23 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in,
}
if (ret == 0) {
explicitOctet = pkiMsg[idx] ==
(ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0);
explicitOctet = 0;
localIdx = idx;
if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&
tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
explicitOctet = 1;
}
/* read encryptedContent, cont[0] */
if (ret == 0 && pkiMsg[idx] != (ASN_CONTEXT_SPECIFIC | 0) &&
pkiMsg[idx] != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
if (ret == 0) {
ret = GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz);
}
if (ret == 0 &&
tag != (ASN_CONTEXT_SPECIFIC | 0) &&
tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
ret = ASN_PARSE_E;
}
idx++;
if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz,
pkiMsgSz) <= 0) {
@ -10915,7 +11047,10 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in,
}
if (explicitOctet) {
if (ret == 0 && pkiMsg[idx++] != ASN_OCTET_STRING) {
if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
ret = ASN_PARSE_E;
}
if (ret == 0 && tag != ASN_OCTET_STRING) {
ret = ASN_PARSE_E;
}
@ -10989,8 +11124,9 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in,
#endif
/* may have IMPLICIT [1] authenticatedAttributes */
if (ret == 0 && pkiMsg[idx] ==
(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
localIdx = idx;
if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&
tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
encodedAttribIdx = idx;
encodedAttribs = pkiMsg + idx;
idx++;
@ -11098,7 +11234,10 @@ authenv_atrbend:
/* get authTag OCTET STRING */
if (ret == 0 && pkiMsg[idx++] != ASN_OCTET_STRING) {
if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
ret = ASN_PARSE_E;
}
if (ret == 0 && tag != ASN_OCTET_STRING) {
ret = ASN_PARSE_E;
}
@ -11529,6 +11668,7 @@ static int wc_PKCS7_DecodeUnprotectedAttributes(PKCS7* pkcs7, byte* pkiMsg,
{
int ret, attribLen;
word32 idx;
byte tag;
if (pkcs7 == NULL || pkiMsg == NULL ||
pkiMsgSz == 0 || inOutIdx == NULL)
@ -11536,9 +11676,11 @@ static int wc_PKCS7_DecodeUnprotectedAttributes(PKCS7* pkcs7, byte* pkiMsg,
idx = *inOutIdx;
if (pkiMsg[idx] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
return ASN_PARSE_E;
if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
return ASN_PARSE_E;
idx++;
if (GetLength(pkiMsg, &idx, &attribLen, pkiMsgSz) < 0)
return ASN_PARSE_E;
@ -11577,6 +11719,7 @@ int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* in, word32 inSz,
byte* pkiMsg = in;
word32 pkiMsgSz = inSz;
byte tag;
if (pkcs7 == NULL ||
((pkcs7->encryptionKey == NULL || pkcs7->encryptionKeySz == 0) &&
@ -11653,8 +11796,10 @@ int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* in, word32 inSz,
pkiMsgSz = (word32)rc;
#endif
if (pkcs7->version != 3) {
if (ret == 0 && pkiMsg[idx++] != (ASN_CONSTRUCTED |
ASN_CONTEXT_SPECIFIC | 0))
if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
ret = ASN_PARSE_E;
if (ret == 0 && tag !=
(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
ret = ASN_PARSE_E;
if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
@ -11746,7 +11891,9 @@ int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* in, word32 inSz,
/* restore saved variables */
expBlockSz = pkcs7->stream->varOne;
#endif
if (ret == 0 && pkiMsg[idx++] != ASN_OCTET_STRING)
if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
ret = ASN_PARSE_E;
if (ret == 0 && tag != ASN_OCTET_STRING)
ret = ASN_PARSE_E;
if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
@ -11793,7 +11940,9 @@ int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* in, word32 inSz,
XMEMCPY(tmpIv, &pkiMsg[idx], length);
idx += length;
/* read encryptedContent, cont[0] */
if (ret == 0 && pkiMsg[idx++] != (ASN_CONTEXT_SPECIFIC | 0))
if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
ret = ASN_PARSE_E;
if (ret == 0 && tag != (ASN_CONTEXT_SPECIFIC | 0))
ret = ASN_PARSE_E;
if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz,
@ -12144,7 +12293,10 @@ int wc_PKCS7_DecodeCompressedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz,
}
/* get ContentInfo content EXPLICIT SEQUENCE */
if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz < 0)
return ASN_PARSE_E;
if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
return ASN_PARSE_E;
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
@ -12185,14 +12337,20 @@ int wc_PKCS7_DecodeCompressedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz,
pkcs7->contentOID = contentType;
/* get eContent EXPLICIT SEQUENCE */
if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
return ASN_PARSE_E;
if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
return ASN_PARSE_E;
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
return ASN_PARSE_E;
/* get content OCTET STRING */
if (pkiMsg[idx++] != ASN_OCTET_STRING)
if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
return ASN_PARSE_E;
if (tag != ASN_OCTET_STRING)
return ASN_PARSE_E;
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)

View File

@ -1330,6 +1330,7 @@ static int Pkcs11GetEccPublicKey(ecc_key* key, Pkcs11Session* session,
int curveIdx;
unsigned char* point = NULL;
int pointSz;
byte tag;
CK_RV rv;
CK_ATTRIBUTE tmpl[] = {
{ CKA_EC_POINT, NULL_PTR, 0 },
@ -1360,7 +1361,9 @@ static int Pkcs11GetEccPublicKey(ecc_key* key, Pkcs11Session* session,
if (ret == 0 && pointSz < key->dp->size * 2 + 1 + 2)
ret = ASN_PARSE_E;
/* Step over the OCTET_STRING wrapper. */
if (ret == 0 && point[i++] != ASN_OCTET_STRING)
if (ret == 0 && GetASNTag(point, &i, &tag, pointSz) != 0)
ret = ASN_PARSE_E;
if (ret == 0 && tag != ASN_OCTET_STRING)
ret = ASN_PARSE_E;
if (ret == 0 && point[i] >= ASN_LONG_LENGTH) {
if (point[i++] != (ASN_LONG_LENGTH | 1))
@ -1690,7 +1693,9 @@ static int Pkcs11ECDSASig_Decode(const byte* in, word32 inSz, byte* sig,
ret = ASN_PARSE_E;
/* Check INT */
if (ret == 0 && in[i++] != ASN_INTEGER)
if (ret == 0 && GetASNTag(in, &i, &tag, inSz) != 0)
ret = ASN_PARSE_E;
if (ret == 0 && tag != ASN_INTGER)
ret = ASN_PARSE_E;
if (ret == 0 && (len = in[i++]) > sz + 1)
ret = ASN_PARSE_E;
@ -1712,7 +1717,9 @@ static int Pkcs11ECDSASig_Decode(const byte* in, word32 inSz, byte* sig,
if (ret == 0 && i + 2 > inSz)
ret = ASN_PARSE_E;
/* Check INT */
if (ret == 0 && in[i++] != ASN_INTEGER)
if (ret == 0 && GetASNTag(in, &i, &tag, inSz) != 0)
ret = ASN_PARSE_E;
if (ret == 0 && tag != ASN_INTGER)
ret = ASN_PARSE_E;
if (ret == 0 && (len = in[i++]) > sz + 1)
ret = ASN_PARSE_E;

View File

@ -1052,6 +1052,8 @@ WOLFSSL_LOCAL int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
word32 oidType, word32 maxIdx);
WOLFSSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
word32 oidType, word32 maxIdx);
WOLFSSL_LOCAL int GetASNTag(const byte* input, word32* idx, byte* tag,
word32 inputSz);
WOLFSSL_LOCAL word32 SetLength(word32 length, byte* output);
WOLFSSL_LOCAL word32 SetSequence(word32 len, byte* output);
WOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output);