From 3b7b81fea7e4786eb9ac1c3c4c89688175520871 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Sun, 15 Sep 2019 22:59:18 -0600 Subject: [PATCH] add local CheckASNTag function --- src/ssl.c | 2 +- wolfcrypt/src/asn.c | 196 ++++++++++++++++++++++---------------- wolfcrypt/src/pkcs12.c | 36 +++---- wolfcrypt/src/pkcs7.c | 195 ++++++++++++++++++++++--------------- wolfcrypt/src/wc_pkcs11.c | 6 +- wolfssl/wolfcrypt/asn.h | 2 + 6 files changed, 260 insertions(+), 177 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index e18ae778c..9bd7382eb 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -34723,7 +34723,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) int length; word32 idx = 0; - if (a->obj[idx++] != ASN_OBJECT_ID) { + if (CheckASNTag(a->obj, ASN_OBJECT_ID, idx++, a->objSz) != 0) { WOLFSSL_MSG("Bad ASN1 Object"); return WOLFSSL_FAILURE; } diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 9328e51ef..d2958b7c3 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -199,18 +199,30 @@ WOLFSSL_LOCAL int GetLength_ex(const byte* input, word32* inOutIdx, int* len, } +/* returns 0 if the tag matches on success or negative value on failure + * does not advance idx */ +int CheckASNTag(const byte* input, byte tag, word32 idx, word32 inputSz) +{ + if (idx + 1 > inputSz) { + WOLFSSL_MSG("Buffer to small for ASN tag"); + return BUFFER_E; + } + + if (tag == input[idx]) { + return 0; + } + + return ASN_PARSE_E; +} + + static int GetASNHeader_ex(const byte* input, byte tag, word32* inOutIdx, int* len, word32 maxIdx, int check) { word32 idx = *inOutIdx; - byte b; int length; - if ((idx + 1) > maxIdx) - return BUFFER_E; - - b = input[idx++]; - if (b != tag) + if (CheckASNTag(input, tag, idx++, maxIdx) != 0) return ASN_PARSE_E; if (GetLength_ex(input, &idx, &length, maxIdx, check) < 0) @@ -450,7 +462,7 @@ static int GetInteger7Bit(const byte* input, word32* inOutIdx, word32 maxIdx) if ((idx + 3) > maxIdx) return BUFFER_E; - if (input[idx++] != ASN_INTEGER) + if (CheckASNTag(input, ASN_INTEGER, idx++, maxIdx) != 0) return ASN_PARSE_E; if (input[idx++] != 1) return ASN_PARSE_E; @@ -678,7 +690,7 @@ WOLFSSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx, if ((idx + MIN_VERSION_SZ) > maxIdx) return ASN_PARSE_E; - if (input[idx++] != ASN_INTEGER) + if (CheckASNTag(input, ASN_INTEGER, idx++, maxIdx) != 0) return ASN_PARSE_E; if (input[idx++] != 0x01) @@ -704,7 +716,7 @@ WOLFSSL_LOCAL int GetShortInt(const byte* input, word32* inOutIdx, int* number, if ((idx + 2) > maxIdx) return BUFFER_E; - if (input[idx++] != ASN_INTEGER) + if (CheckASNTag(input, ASN_INTEGER, idx++, maxIdx) != 0) return ASN_PARSE_E; len = input[idx++]; @@ -773,14 +785,17 @@ WOLFSSL_LOCAL int SetShortInt(byte* input, word32* inOutIdx, word32 number, word static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version, word32 maxIdx) { + int ret; word32 idx = *inOutIdx; WOLFSSL_ENTER("GetExplicitVersion"); - if ((idx + 1) > maxIdx) - return BUFFER_E; + ret = CheckASNTag(input, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED), + idx++, maxIdx); + if (ret == BUFFER_E) + return ret; - if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) { + if (ret == 0) { *inOutIdx = ++idx; /* skip header */ return GetMyVersion(input, inOutIdx, version, maxIdx); } @@ -848,11 +863,9 @@ 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 (CheckASNTag(input, ASN_BIT_STRING, idx++, maxIdx) != 0) { return ASN_BITSTR_E; + } if (GetLength(input, &idx, &length, maxIdx) < 0) return ASN_PARSE_E; @@ -972,8 +985,8 @@ int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz) type = ber[i]; indef = ber[i+1] == ASN_INDEF_LENGTH; if (indef && (type & 0xC0) == 0 && - ber[i] != (ASN_SEQUENCE | ASN_CONSTRUCTED) && - ber[i] != (ASN_SET | ASN_CONSTRUCTED)) { + CheckASNTag(ber, (ASN_SEQUENCE | ASN_CONSTRUCTED), i, berSz) != 0 && + CheckASNTag(ber, (ASN_SET | ASN_CONSTRUCTED), i, berSz) != 0) { /* Indefinite length OCTET STRING or other simple type. * Put all the data into one entry. */ @@ -2097,14 +2110,12 @@ int GetASNObjectId(const byte* input, word32* inOutIdx, int* len, word32 maxIdx) { word32 idx = *inOutIdx; - byte b; int length; if ((idx + 1) > maxIdx) return BUFFER_E; - b = input[idx++]; - if (b != ASN_OBJECT_ID) + if (CheckASNTag(input, ASN_OBJECT_ID, idx++, maxIdx) != 0) return ASN_OBJECT_ID_E; if (GetLength(input, &idx, &length, maxIdx) < 0) @@ -2247,7 +2258,7 @@ 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) { + if (idx < maxIdx && CheckASNTag(input, ASN_TAG_NULL, idx, maxIdx) == 0) { ret = GetASNNull(input, &idx, maxIdx); if (ret != 0) return ret; @@ -2337,7 +2348,7 @@ 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 (CheckASNTag(input, ASN_OBJECT_ID, idx, sz) == 0) { if (SkipObjectId(input, &idx, sz) < 0) return ASN_PARSE_E; } @@ -3451,7 +3462,8 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password, } /* OPTIONAL key length */ - if (seqEnd > inOutIdx && input[inOutIdx] == ASN_INTEGER) { + if (seqEnd > inOutIdx && + CheckASNTag(input, ASN_INTEGER, inOutIdx, sz) == 0) { if (GetShortInt(input, &inOutIdx, &keySz, sz) < 0) { ERROR_OUT(ASN_PARSE_E, exit_tte); } @@ -3805,7 +3817,8 @@ int DecryptContent(byte* input, word32 sz,const char* password, int passwordSz) } /* OPTIONAL key length */ - if (seqEnd > inOutIdx && input[inOutIdx] == ASN_INTEGER) { + if (seqEnd > inOutIdx && + CheckASNTag(input, ASN_INTEGER, inOutIdx, sz) == 0) { if (GetShortInt(input, &inOutIdx, &keySz, sz) < 0) { ERROR_OUT(ASN_PARSE_E, exit_dc); } @@ -3847,7 +3860,7 @@ int DecryptContent(byte* input, word32 sz,const char* password, int passwordSz) inOutIdx += length; } - if (input[inOutIdx++] != (ASN_CONTEXT_SPECIFIC | 0)) { + if (CheckASNTag(input, (ASN_CONTEXT_SPECIFIC | 0), inOutIdx++, sz) != 0) { ERROR_OUT(ASN_PARSE_E, exit_dc); } @@ -3883,9 +3896,6 @@ 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; -#endif if (input == NULL || inOutIdx == NULL) return BAD_FUNC_ARG; @@ -3894,11 +3904,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) - return BUFFER_E; + ret = CheckASNTag(input, ASN_INTEGER, *inOutIdx, inSz); + if (ret == BUFFER_E) + return ret; - b = input[*inOutIdx]; - if (b != ASN_INTEGER) { + if (ret != 0) { /* not from decoded cert, will have algo id, skip past */ if (GetSequence(input, inOutIdx, &length, inSz) < 0) return ASN_PARSE_E; @@ -3910,7 +3920,7 @@ int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz, if (*inOutIdx >= inSz) { return BUFFER_E; } - if (input[*inOutIdx] == ASN_TAG_NULL) { + if (CheckASNTag(input, ASN_TAG_NULL, *inOutIdx, inSz) == 0) { ret = GetASNNull(input, inOutIdx, inSz); if (ret != 0) return ret; @@ -4500,8 +4510,8 @@ static int GetKey(DecodedCert* cert) int pubLen = length + 1 + SetLength(length, seq); byte* publicKey; - if (cert->source[cert->srcIdx] != - (ASN_SEQUENCE | ASN_CONSTRUCTED)) { + if (CheckASNTag(cert->source, (ASN_SEQUENCE | ASN_CONSTRUCTED), + cert->srcIdx, cert->maxIdx) != 0) { if (GetObjectId(cert->source, &cert->srcIdx, &cert->pkCurveOID, oidCurveType, cert->maxIdx) < 0) return ASN_PARSE_E; @@ -4672,7 +4682,8 @@ static int GetName(DecodedCert* cert, int nameType) return BUFFER_E; } - if (cert->source[cert->srcIdx] == ASN_OBJECT_ID) { + if (CheckASNTag(cert->source, ASN_OBJECT_ID, cert->srcIdx, cert->maxIdx) + == 0) { WOLFSSL_MSG("Trying optional prefix..."); if (SkipObjectId(cert->source, &cert->srcIdx, cert->maxIdx) < 0) @@ -6861,7 +6872,8 @@ static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert) return ASN_PARSE_E; } - if (input[idx++] != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) { + if (CheckASNTag(input, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED), + idx++, sz) != 0) { WOLFSSL_MSG("\twrong type"); return ASN_PARSE_E; } @@ -6992,20 +7004,22 @@ 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)) + if (CheckASNTag(input, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0), idx, + sz) == 0) { idx++; if (GetLength(input, &idx, &length, sz) < 0) return ASN_PARSE_E; - if (input[idx] == - (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CRLDP_FULL_NAME)) + if (CheckASNTag(input, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | + CRLDP_FULL_NAME), idx, sz) == 0) { idx++; if (GetLength(input, &idx, &length, sz) < 0) return ASN_PARSE_E; - if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI)) + if (CheckASNTag(input, (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI), + idx, sz) == 0) { idx++; if (GetLength(input, &idx, &length, sz) < 0) @@ -7027,7 +7041,8 @@ static int DecodeCrlDist(const byte* input, int sz, DecodedCert* cert) /* Check for reasonFlags */ if (idx < (word32)sz && - input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) + CheckASNTag(input, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1), idx, + sz) == 0) { idx++; if (GetLength(input, &idx, &length, sz) < 0) @@ -7037,7 +7052,8 @@ static int DecodeCrlDist(const byte* input, int sz, DecodedCert* cert) /* Check for cRLIssuer */ if (idx < (word32)sz && - input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2)) + CheckASNTag(input, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2), idx, + sz) == 0) { idx++; if (GetLength(input, &idx, &length, sz) < 0) @@ -7063,7 +7079,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 +7099,10 @@ static int DecodeAuthInfo(const byte* input, int sz, DecodedCert* cert) /* Only supporting URIs right now. */ - b = input[idx++]; + if (CheckASNTag(input, (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI), idx++, + sz) == 0) + b = (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI); + if (GetLength(input, &idx, &length, sz) < 0) return ASN_PARSE_E; @@ -7113,7 +7132,7 @@ static int DecodeAuthKeyId(const byte* input, int sz, DecodedCert* cert) return ASN_PARSE_E; } - if (input[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) { + if (CheckASNTag(input, (ASN_CONTEXT_SPECIFIC | 0), idx++, sz) != 0) { WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available\n"); return 0; } @@ -7570,7 +7589,7 @@ static int DecodeCertExtensions(DecodedCert* cert) if (input == NULL || sz == 0) return BAD_FUNC_ARG; - if (input[idx++] != ASN_EXTENSIONS) { + if (CheckASNTag(input, ASN_EXTENSIONS, idx++, sz) != 0) { WOLFSSL_MSG("\tfail: should be an EXTENSIONS"); return ASN_PARSE_E; } @@ -7604,7 +7623,7 @@ static int DecodeCertExtensions(DecodedCert* cert) return BUFFER_E; } - if (input[idx] == ASN_BOOLEAN) { + if (CheckASNTag(input, ASN_BOOLEAN, idx, sz) == 0) { ret = GetBoolean(input, &idx, sz); if (ret < 0) { WOLFSSL_MSG("\tfail: critical boolean"); @@ -7929,7 +7948,8 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, } if (ret == 0) { /* version - optional */ - if (cert[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) { + if (CheckASNTag(cert, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED), + idx, certSz) == 0) { idx++; if (GetLength(cert, &idx, &len, certSz) < 0) ret = ASN_PARSE_E; @@ -7989,7 +8009,8 @@ 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)) { + if (CheckASNTag(cert, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1), + idx, certSz) == 0) { idx++; if (GetLength(cert, &idx, &len, certSz) < 0) ret = ASN_PARSE_E; @@ -8002,7 +8023,8 @@ 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)) { + if (CheckASNTag(cert, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2), + idx, certSz) == 0) { idx++; if (GetLength(cert, &idx, &len, certSz) < 0) ret = ASN_PARSE_E; @@ -8015,7 +8037,8 @@ 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)) { + if (ret == 0 && CheckASNTag(cert, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | + 3), idx, certSz) == 0) { idx++; if (GetLength(cert, &idx, &extLen, certSz) < 0) ret = ASN_PARSE_E; @@ -8044,7 +8067,7 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, } if (ret == 0) { - if (cert[extIdx] == ASN_BOOLEAN) { + if (CheckASNTag(cert, ASN_BOOLEAN, extIdx, certSz) == 0) { if (GetBoolean(cert, &extIdx, certSz) < 0) ret = ASN_PARSE_E; } @@ -8065,7 +8088,8 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, ret = BUFFER_E; if (ret == 0 && - cert[extIdx++] == (ASN_CONTEXT_SPECIFIC | 0)) { + CheckASNTag(cert, (ASN_CONTEXT_SPECIFIC | 0), + extIdx++, certSz) == 0) { if (GetLength(cert, &extIdx, &extLen, certSz) <= 0) ret = ASN_PARSE_E; if (ret == 0) { @@ -12953,14 +12977,12 @@ static int SetAltNamesFromDcert(Cert* cert, DecodedCert* decoded) int ret = 0; if (decoded->extensions) { - byte b; int length; word32 maxExtensionsIdx; decoded->srcIdx = decoded->extensionsIdx; - b = decoded->source[decoded->srcIdx++]; - - if (b != ASN_EXTENSIONS) { + if (CheckASNTag(decoded->source, ASN_EXTENSIONS, decoded->srcIdx++, + decoded->maxIdx) != 0) { ret = ASN_PARSE_E; } else if (GetLength(decoded->source, &decoded->srcIdx, &length, @@ -13692,7 +13714,7 @@ static int ASNToHexString(const byte* input, word32* inOutIdx, char** out, return BUFFER_E; } - if (input[*inOutIdx] == ASN_INTEGER) { + if (CheckASNTag(input, ASN_INTEGER, *inOutIdx, inSz) == 0) { if (GetASNInt(input, inOutIdx, &len, inSz) < 0) return ASN_PARSE_E; } @@ -13738,7 +13760,8 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, return BUFFER_E; } - if (input[*inOutIdx] == (ASN_SEQUENCE | ASN_CONSTRUCTED)) { + if (CheckASNTag(input, (ASN_SEQUENCE | ASN_CONSTRUCTED), *inOutIdx, inSz) + == 0) { #ifdef WOLFSSL_CUSTOM_CURVES ecc_set_type* curve; int len; @@ -13790,7 +13813,8 @@ 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) { + if (*inOutIdx < inSz && CheckASNTag(input, ASN_BIT_STRING, + *inOutIdx, inSz) == 0) { len = 0; ret = GetASNHeader(input, ASN_BIT_STRING, inOutIdx, &len, inSz); *inOutIdx += len; @@ -14300,7 +14324,8 @@ 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; @@ -14309,11 +14334,14 @@ static int GetEnumerated(const byte* input, word32* inOutIdx, int *value) *value = 0; - if (input[idx++] != ASN_ENUMERATED) + if (CheckASNTag(input, ASN_ENUMERATED, idx++, sz) != 0) 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--) { @@ -14411,7 +14439,8 @@ static int DecodeSingleResponse(byte* source, * unprocessed data in the singleResponse wrapper. */ if (((int)(idx - prevIndex) < wrapperSz) && - (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))) + CheckASNTag(source, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0), idx, + size) == 0) { idx++; if (GetLength(source, &idx, &length, size) < 0) @@ -14431,7 +14460,8 @@ static int DecodeSingleResponse(byte* source, #endif } if (((int)(idx - prevIndex) < wrapperSz) && - (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))) + CheckASNTag(source, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1), idx, + size) == 0) { idx++; if (GetLength(source, &idx, &length, size) < 0) @@ -14458,7 +14488,8 @@ static int DecodeOcspRespExtensions(byte* source, if ((idx + 1) > sz) return BUFFER_E; - if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) + if (CheckASNTag(source, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1), idx++, + sz) != 0) return ASN_PARSE_E; if (GetLength(source, &idx, &length, sz) < 0) @@ -14487,7 +14518,7 @@ static int DecodeOcspRespExtensions(byte* source, return BUFFER_E; } - if (source[idx] == ASN_BOOLEAN) { + if (CheckASNTag(source, ASN_BOOLEAN, idx, sz) == 0) { WOLFSSL_MSG("\tfound optional critical flag, moving past"); ret = GetBoolean(source, &idx, sz); if (ret < 0) @@ -14522,7 +14553,6 @@ static int DecodeResponseData(byte* source, word32 idx = *ioIndex, prev_idx; int length; int version; - word32 responderId = 0; int ret; WOLFSSL_ENTER("DecodeResponseData"); @@ -14537,7 +14567,8 @@ 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)) + if (CheckASNTag(source, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED), idx, + size) == 0) { idx += 2; /* Eat the value and length */ if (GetMyVersion(source, &idx, &version, size) < 0) @@ -14545,10 +14576,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))) + if (CheckASNTag(source, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1), idx, + size) == 0 || + CheckASNTag(source, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2), idx, + size) == 0) { + idx++; /* advance past ASN tag */ if (GetLength(source, &idx, &length, size) < 0) return ASN_PARSE_E; idx += length; @@ -14586,7 +14619,8 @@ static int DecodeCerts(byte* source, WOLFSSL_ENTER("DecodeCerts"); - if (source[idx++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) + if (CheckASNTag(source, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC), idx++, + size) == 0) { int length; @@ -14760,7 +14794,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) @@ -14769,7 +14803,8 @@ 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 (CheckASNTag(source, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC), idx++, + size) != 0) return ASN_PARSE_E; if (GetLength(source, &idx, &length, size) < 0) return ASN_PARSE_E; @@ -15082,7 +15117,7 @@ WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash, WOLFSSL_ENTER("GetNameHash"); - if (source[*idx] == ASN_OBJECT_ID) { + if (CheckASNTag(source, ASN_OBJECT_ID, *idx, maxIdx) == 0) { WOLFSSL_MSG("Trying optional prefix..."); if (GetLength(source, idx, &length, maxIdx) < 0) @@ -15260,7 +15295,7 @@ int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm) dcrl->sigIndex = len + idx; /* may have version */ - if (buff[idx] == ASN_INTEGER) { + if (CheckASNTag(buff, ASN_INTEGER, idx, sz) == 0) { if (GetMyVersion(buff, &idx, &version, sz) < 0) return ASN_PARSE_E; } @@ -15297,7 +15332,8 @@ int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm) #endif } - if (idx != dcrl->sigIndex && buff[idx] != CRL_EXTENSIONS) { + if (idx != dcrl->sigIndex && + CheckASNTag(buff, CRL_EXTENSIONS, idx, sz) != 0) { if (GetSequence(buff, &idx, &len, sz) < 0) return ASN_PARSE_E; diff --git a/wolfcrypt/src/pkcs12.c b/wolfcrypt/src/pkcs12.c index c221f7b22..8780a2647 100644 --- a/wolfcrypt/src/pkcs12.c +++ b/wolfcrypt/src/pkcs12.c @@ -215,7 +215,8 @@ static int GetSafeContent(WC_PKCS12* pkcs12, const byte* input, safe->oid = oid; /* check tag, length */ - if (input[localIdx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) { + if (CheckASNTag(input, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC), localIdx++, + maxIdx) != 0) { WOLFSSL_MSG("Unexpected tag in PKCS12 DER"); freeSafe(safe, pkcs12->heap); return ASN_PARSE_E; @@ -233,7 +234,7 @@ 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 (CheckASNTag(input, ASN_OCTET_STRING, localIdx++, maxIdx) != 0) { WOLFSSL_MSG("Wrong tag with content PKCS12 type DATA"); freeSafe(safe, pkcs12->heap); return ASN_PARSE_E; @@ -380,7 +381,7 @@ 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 (CheckASNTag(mem, ASN_OCTET_STRING, curIdx++, totalSz) != 0) { WOLFSSL_MSG("Failed to get digest"); XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS); return ASN_PARSE_E; @@ -411,7 +412,7 @@ 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 (CheckASNTag(mem, ASN_OCTET_STRING, curIdx++, totalSz) != 0) { WOLFSSL_MSG("Failed to get salt"); ERROR_OUT(ASN_PARSE_E, exit_gsd); } @@ -978,7 +979,8 @@ int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, WOLFSSL_MSG("Decrypting PKCS12 Content Info Container"); data = ci->data; - if (data[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) { + if (CheckASNTag(data, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC), + idx++, ci->dataSz) != 0) { ERROR_OUT(ASN_PARSE_E, exit_pk12par); } if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) { @@ -1036,13 +1038,14 @@ 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 (CheckASNTag(data, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC), + idx++, ci->dataSz) != 0) { 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 (CheckASNTag(data, ASN_OCTET_STRING, idx++, ci->dataSz) != 0) { ERROR_OUT(ASN_PARSE_E, exit_pk12par); } if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) { @@ -1072,8 +1075,8 @@ 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 (CheckASNTag(data, (ASN_CONSTRUCTED | + ASN_CONTEXT_SPECIFIC), idx++, ci->dataSz) != 0) { ERROR_OUT(ASN_PARSE_E, exit_pk12par); } if ((ret = GetLength(data, &idx, &size, ci->dataSz)) <= 0) { @@ -1106,8 +1109,8 @@ 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 (CheckASNTag(data, (ASN_CONSTRUCTED | + ASN_CONTEXT_SPECIFIC), idx++, ci->dataSz) != 0) { ERROR_OUT(ASN_PARSE_E, exit_pk12par); } if ((ret = GetLength(data, &idx, &size, @@ -1168,8 +1171,8 @@ 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 (CheckASNTag(data, (ASN_CONSTRUCTED | + ASN_CONTEXT_SPECIFIC), idx++, ci->dataSz) != 0) { ERROR_OUT(ASN_PARSE_E, exit_pk12par); } if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) { @@ -1190,15 +1193,16 @@ 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 (CheckASNTag(data, (ASN_CONSTRUCTED | + ASN_CONTEXT_SPECIFIC), idx++, ci->dataSz) != 0) { 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 (CheckASNTag(data, ASN_OCTET_STRING, idx++, + ci->dataSz) != 0) { ERROR_OUT(ASN_PARSE_E, exit_pk12par); } diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index c41d6b724..b399c5858 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -1197,7 +1197,7 @@ static PKCS7DecodedAttrib* findAttrib(PKCS7* pkcs7, const byte* oid, word32 oidS word32 idx = 0; int length = 0; - if (list->oid[idx++] != ASN_OBJECT_ID) { + if (CheckASNTag(list->oid, ASN_OBJECT_ID, idx++, list->oidSz) != 0) { WOLFSSL_MSG("Bad attribute ASN1 syntax"); return NULL; } @@ -3918,8 +3918,8 @@ 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)) { + if (ret == 0 && CheckASNTag(in, (ASN_CONSTRUCTED | + ASN_CONTEXT_SPECIFIC | 0), idx, inSz) == 0) { idx++; if (ret == 0 && GetLength(in, &idx, &length, inSz) <= 0) { @@ -3929,7 +3929,8 @@ 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 && CheckASNTag(in, ASN_OCTET_STRING, idx++, inSz) + != 0) ret = ASN_PARSE_E; if (ret == 0 && GetLength(in, &idx, &length, inSz) < 0) @@ -3938,7 +3939,7 @@ 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) { + if (CheckASNTag(in, ASN_CONTEXT_SPECIFIC, idx, inSz) == 0) { idx++; if (ret == 0 && GetLength(in, &idx, &length, inSz) < 0) ret = ASN_PARSE_E; @@ -3971,8 +3972,8 @@ 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)) { + if (ret == 0 && CheckASNTag(in, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC + | 0), idx, inSz) == 0) { idx++; if (GetLength(in, &idx, &length, inSz) < 0) @@ -4165,8 +4166,8 @@ 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 && CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | + ASN_CONTEXT_SPECIFIC | 0), idx++, totalSz) != 0) ret = ASN_PARSE_E; if (ret == 0 && GetLength_ex(pkiMsg, &idx, &length, totalSz, @@ -4266,7 +4267,8 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, break; } - if (pkiMsg[localIdx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) + if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | + 0), localIdx++, pkiMsgSz) != 0) ret = ASN_PARSE_E; if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, &length, pkiMsgSz, @@ -4278,7 +4280,8 @@ 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 && CheckASNTag(pkiMsg, (ASN_OCTET_STRING | + ASN_CONSTRUCTED), localIdx, pkiMsgSz) == 0) { multiPart = 1; localIdx++; @@ -4293,7 +4296,8 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, ret = BUFFER_E; } - if (ret == 0 && pkiMsg[localIdx++] != ASN_OCTET_STRING) + if (ret == 0 && CheckASNTag(pkiMsg, ASN_OCTET_STRING, + localIdx++, pkiMsgSz) != 0) ret = ASN_PARSE_E; if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, &length, pkiMsgSz, @@ -4310,7 +4314,8 @@ 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 (CheckASNTag(pkiMsg, ASN_OCTET_STRING, localIdx++, pkiMsgSz) + != 0) ret = ASN_PARSE_E; if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, @@ -4437,7 +4442,8 @@ 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 (CheckASNTag(pkiMsg, ASN_OCTET_STRING, localIdx++, + totalSz) != 0) ret = ASN_PARSE_E; if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, totalSz) < 0) @@ -4544,8 +4550,8 @@ 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)) { + if (ret == 0 && CheckASNTag(pkiMsg2, (ASN_CONSTRUCTED | + ASN_CONTEXT_SPECIFIC | 0), idx, pkiMsg2Sz) == 0) { idx++; if (GetLength_ex(pkiMsg2, &idx, &length, maxIdx, NO_USER_CHECK) < 0) @@ -4627,7 +4633,8 @@ 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 (CheckASNTag(pkiMsg2, (ASN_CONSTRUCTED | ASN_SEQUENCE), + certIdx++, pkiMsg2Sz) == 0) { if (GetLength(pkiMsg2, &certIdx, &certSz, pkiMsg2Sz) < 0) ret = ASN_PARSE_E; @@ -4678,8 +4685,8 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, certIdx + 1 < (word32)length; i++) { localIdx = certIdx; - if (pkiMsg2[certIdx++] == - (ASN_CONSTRUCTED | ASN_SEQUENCE)) { + if (CheckASNTag(pkiMsg2, (ASN_CONSTRUCTED | + ASN_SEQUENCE), certIdx++, pkiMsg2Sz) == 0) { if (GetLength(pkiMsg2, &certIdx, &sz, pkiMsg2Sz) < 0) { ret = ASN_PARSE_E; @@ -4793,8 +4800,8 @@ 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)) { + if (ret == 0 && CheckASNTag(pkiMsg2, (ASN_CONSTRUCTED | + ASN_CONTEXT_SPECIFIC | 1), idx, pkiMsg2Sz) == 0) { idx++; if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0) ret = ASN_PARSE_E; @@ -4864,7 +4871,8 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, ret = BUFFER_E; /* Get the signature */ - if (ret == 0 && pkiMsg2[idx] == ASN_OCTET_STRING) { + if (ret == 0 && CheckASNTag(pkiMsg2, ASN_OCTET_STRING, idx, + pkiMsg2Sz) == 0) { idx++; if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0) @@ -8014,14 +8022,15 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, } else { /* remove SubjectKeyIdentifier */ - if (pkiMsg[(*idx)++] != - (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) + if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC + | 0), (*idx)++, pkiMsgSz) != 0) return ASN_PARSE_E; if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) return ASN_PARSE_E; - if (pkiMsg[(*idx)++] != ASN_OCTET_STRING) + if (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) + != 0) return ASN_PARSE_E; if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) @@ -8043,7 +8052,7 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, return ALGO_ID_E; /* read encryptedKey */ - if (pkiMsg[(*idx)++] != ASN_OCTET_STRING) { + if (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) != 0){ return ASN_PARSE_E; } @@ -8188,7 +8197,8 @@ static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari, return BAD_FUNC_ARG; /* remove OriginatorIdentifierOrKey */ - if (pkiMsg[*idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) { + if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0), + *idx, pkiMsgSz) == 0) { (*idx)++; if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) return ASN_PARSE_E; @@ -8198,7 +8208,8 @@ static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari, } /* remove OriginatorPublicKey */ - if (pkiMsg[*idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) { + if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1), *idx, + pkiMsgSz) == 0) { (*idx)++; if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) return ASN_PARSE_E; @@ -8224,13 +8235,15 @@ static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari, } /* remove ECPoint BIT STRING */ - if ((pkiMsgSz > (*idx + 1)) && (pkiMsg[(*idx)++] != ASN_BIT_STRING)) + if ((pkiMsgSz > (*idx + 1)) && (CheckASNTag(pkiMsg, ASN_BIT_STRING, (*idx)++, + pkiMsgSz) != 0)) return ASN_PARSE_E; if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) return ASN_PARSE_E; - if ((pkiMsgSz < (*idx + 1)) || (pkiMsg[(*idx)++] != 0x00)) + if ((pkiMsgSz < (*idx + 1)) || (CheckASNTag(pkiMsg, ASN_OTHER_TYPE, + (*idx)++, pkiMsgSz) != 0)) return ASN_EXPECT_0_E; /* get sender ephemeral public ECDSA key */ @@ -8270,7 +8283,8 @@ 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 (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1), + (*idx)++, pkiMsgSz) != 0) { *idx = savedIdx; return 0; } @@ -8282,7 +8296,7 @@ static int wc_PKCS7_KariGetUserKeyingMaterial(WC_PKCS7_KARI* kari, /* get OCTET STRING */ if ( (pkiMsgSz > ((*idx) + 1)) && - (pkiMsg[(*idx)++] != ASN_OCTET_STRING) ) { + (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) != 0)) { *idx = savedIdx; return 0; } @@ -8357,7 +8371,8 @@ static int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari, /* remove RecipientKeyIdentifier IMPLICIT [0] */ if ( (pkiMsgSz > (*idx + 1)) && - (pkiMsg[(*idx)++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) ) { + (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0), + (*idx)++, pkiMsgSz) == 0) ) { if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) return ASN_PARSE_E; @@ -8368,7 +8383,7 @@ static int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari, /* remove SubjectKeyIdentifier */ if ( (pkiMsgSz > (*idx + 1)) && - (pkiMsg[(*idx)++] != ASN_OCTET_STRING) ) + (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) != 0)) return ASN_PARSE_E; if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) @@ -8501,7 +8516,8 @@ 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)) ) { + (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0), + *idx, pkiMsgSz) == 0) ) { /* try to get RecipientKeyIdentifier */ ret = wc_PKCS7_KariGetSubjectKeyIdentifier(kari, pkiMsg, pkiMsgSz, @@ -8518,7 +8534,7 @@ static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari, /* remove EncryptedKey */ if ( (pkiMsgSz > (*idx + 1)) && - (pkiMsg[(*idx)++] != ASN_OCTET_STRING) ) + (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) != 0)) return ASN_PARSE_E; if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) @@ -8732,7 +8748,8 @@ 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 (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | + 0), (*idx)++, pkiMsgSz) != 0) return ASN_PARSE_E; if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) @@ -8748,7 +8765,8 @@ static int wc_PKCS7_DecryptPwri(PKCS7* pkcs7, byte* in, word32 inSz, /* get KDF salt OCTET STRING */ if ( (pkiMsgSz > ((*idx) + 1)) && - (pkiMsg[(*idx)++] != ASN_OCTET_STRING) ) { + (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) + != 0)) { return ASN_PARSE_E; } @@ -8801,7 +8819,8 @@ 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) ) { + (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) + != 0)) { XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7); return ASN_PARSE_E; } @@ -8822,7 +8841,7 @@ static int wc_PKCS7_DecryptPwri(PKCS7* pkcs7, byte* in, word32 inSz, /* get EncryptedKey */ if ( (pkiMsgSz < ((*idx) + 1)) || - (pkiMsg[(*idx)++] != ASN_OCTET_STRING) ) { + (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) != 0)) { XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7); return ASN_PARSE_E; } @@ -8952,7 +8971,7 @@ static int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz, kekIdSz = length; - if (pkiMsg[(*idx)++] != ASN_OCTET_STRING) + if (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) != 0) return ASN_PARSE_E; if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) @@ -8964,7 +8983,8 @@ 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)) { + if ((*idx < kekIdSz) && (CheckASNTag(pkiMsg, ASN_GENERALIZED_TIME, + *idx, pkiMsgSz) == 0)) { if (wc_GetDateInfo(pkiMsg + *idx, pkiMsgSz, &datePtr, &dateFormat, &dateLen) != 0) { return ASN_PARSE_E; @@ -8973,8 +8993,8 @@ static int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz, } /* may have OPTIONAL OtherKeyAttribute */ - if ((*idx < kekIdSz) && (pkiMsg[*idx] == - (ASN_SEQUENCE | ASN_CONSTRUCTED))) { + if ((*idx < kekIdSz) && (CheckASNTag(pkiMsg, (ASN_SEQUENCE | + ASN_CONSTRUCTED), *idx, pkiMsgSz) == 0)) { if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) return ASN_PARSE_E; @@ -8988,7 +9008,7 @@ static int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz, return ASN_PARSE_E; /* get EncryptedKey */ - if (pkiMsg[(*idx)++] != ASN_OCTET_STRING) + if (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) != 0) return ASN_PARSE_E; if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) @@ -9418,7 +9438,8 @@ static int wc_PKCS7_DecryptRecipientInfos(PKCS7* pkcs7, byte* in, else { /* kari is IMPLICIT[1] */ *idx = savedIdx; - if (pkiMsg[*idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) { + if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | + 1), *idx, pkiMsgSz) == 0) { (*idx)++; @@ -9447,8 +9468,8 @@ 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 (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | + ASN_CONTEXT_SPECIFIC | 2), *idx, pkiMsgSz) == 0) { (*idx)++; if (GetLength(pkiMsg, idx, &version, pkiMsgSz) < 0) @@ -9476,8 +9497,8 @@ 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 (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | + ASN_CONTEXT_SPECIFIC | 3), *idx, pkiMsgSz) == 0) { #if !defined(NO_PWDBASED) && !defined(NO_SHA) (*idx)++; @@ -9509,8 +9530,8 @@ 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 (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | + ASN_CONTEXT_SPECIFIC | 4), *idx, pkiMsgSz) == 0) { (*idx)++; /* found ori */ @@ -9687,8 +9708,8 @@ static int wc_PKCS7_ParseToRecipientInfoSet(PKCS7* pkcs7, byte* in, } } - if (ret == 0 && pkiMsg[(*idx)++] != - (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) + if (ret == 0 && CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | + ASN_CONTEXT_SPECIFIC | 0), (*idx)++, pkiMsgSz) != 0) ret = ASN_PARSE_E; if (ret == 0 && GetLength_ex(pkiMsg, idx, &length, pkiMsgSz, @@ -9985,7 +10006,8 @@ 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 && CheckASNTag(pkiMsg, ASN_OCTET_STRING, idx++, + pkiMsgSz) != 0) { ret = ASN_PARSE_E; } @@ -10042,12 +10064,17 @@ 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; + if (CheckASNTag(pkiMsg, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | + 0), idx, pkiMsgSz) == 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 && CheckASNTag(pkiMsg, (ASN_CONTEXT_SPECIFIC | 0), idx, + pkiMsgSz) != 0 && + CheckASNTag(pkiMsg, (ASN_CONTEXT_SPECIFIC | + ASN_CONSTRUCTED | 0), idx, pkiMsgSz) != 0) { ret = ASN_PARSE_E; } idx++; @@ -10058,7 +10085,8 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, } if (ret == 0 && explicitOctet) { - if (ret == 0 && pkiMsg[idx++] != ASN_OCTET_STRING) { + if (ret == 0 && CheckASNTag(pkiMsg, ASN_OCTET_STRING, idx++, + pkiMsgSz) != 0) { ret = ASN_PARSE_E; break; } @@ -10845,7 +10873,8 @@ 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 && CheckASNTag(pkiMsg, ASN_OCTET_STRING, idx++, + pkiMsgSz) != 0) { ret = ASN_PARSE_E; } @@ -10898,13 +10927,18 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in, } if (ret == 0) { - explicitOctet = pkiMsg[idx] == - (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0); + explicitOctet = 0; + if (CheckASNTag(pkiMsg, (ASN_CONTEXT_SPECIFIC | + ASN_CONSTRUCTED | 0), idx, pkiMsgSz) == 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 && + CheckASNTag(pkiMsg, (ASN_CONTEXT_SPECIFIC | 0), idx, + pkiMsgSz) != 0 && + CheckASNTag(pkiMsg, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED + | 0), idx, pkiMsgSz) != 0) { ret = ASN_PARSE_E; } idx++; @@ -10915,7 +10949,8 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in, } if (explicitOctet) { - if (ret == 0 && pkiMsg[idx++] != ASN_OCTET_STRING) { + if (ret == 0 && CheckASNTag(pkiMsg, ASN_OCTET_STRING, idx++, + pkiMsgSz) != 0) { ret = ASN_PARSE_E; } @@ -10989,8 +11024,8 @@ 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)) { + if (ret == 0 && CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | + ASN_CONTEXT_SPECIFIC | 1), idx, pkiMsgSz) == 0) { encodedAttribIdx = idx; encodedAttribs = pkiMsg + idx; idx++; @@ -11098,7 +11133,8 @@ authenv_atrbend: /* get authTag OCTET STRING */ - if (ret == 0 && pkiMsg[idx++] != ASN_OCTET_STRING) { + if (ret == 0 && CheckASNTag(pkiMsg, ASN_OCTET_STRING, idx++, + pkiMsgSz) != 0) { ret = ASN_PARSE_E; } @@ -11536,7 +11572,8 @@ static int wc_PKCS7_DecodeUnprotectedAttributes(PKCS7* pkcs7, byte* pkiMsg, idx = *inOutIdx; - if (pkiMsg[idx] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) + if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1), idx, + pkiMsgSz) != 0) return ASN_PARSE_E; idx++; @@ -11653,8 +11690,8 @@ 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 && CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | + ASN_CONTEXT_SPECIFIC | 0), idx++, pkiMsgSz) != 0) ret = ASN_PARSE_E; if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) @@ -11746,7 +11783,8 @@ 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 && CheckASNTag(pkiMsg, ASN_OCTET_STRING, idx++, + pkiMsgSz) != 0) ret = ASN_PARSE_E; if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) @@ -11793,7 +11831,8 @@ 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 && CheckASNTag(pkiMsg, (ASN_CONTEXT_SPECIFIC | 0), + idx++, pkiMsgSz) != 0) ret = ASN_PARSE_E; if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz, @@ -12144,7 +12183,8 @@ 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 (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0), idx++, + pkiMsgSz) != 0) return ASN_PARSE_E; if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) @@ -12185,14 +12225,15 @@ 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 (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0), idx++, + pkiMsgSz) != 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 (CheckASNTag(pkiMsg, ASN_OCTET_STRING, idx++, pkiMsgSz) != 0) return ASN_PARSE_E; if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) diff --git a/wolfcrypt/src/wc_pkcs11.c b/wolfcrypt/src/wc_pkcs11.c index b7f5cd5bd..742bfb1d9 100644 --- a/wolfcrypt/src/wc_pkcs11.c +++ b/wolfcrypt/src/wc_pkcs11.c @@ -1360,7 +1360,7 @@ 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 && CheckASNTag(point, ASN_OCTET_STRING, i++, pointSz) != 0) ret = ASN_PARSE_E; if (ret == 0 && point[i] >= ASN_LONG_LENGTH) { if (point[i++] != (ASN_LONG_LENGTH | 1)) @@ -1690,7 +1690,7 @@ 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 && CheckASNTag(in, ASN_INTGER, i++, inSz) != 0) ret = ASN_PARSE_E; if (ret == 0 && (len = in[i++]) > sz + 1) ret = ASN_PARSE_E; @@ -1712,7 +1712,7 @@ 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 && CheckASNTag(in, ASN_INTGER, i++, inSz) != 0) ret = ASN_PARSE_E; if (ret == 0 && (len = in[i++]) > sz + 1) ret = ASN_PARSE_E; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 008ebe2da..4d3f8e142 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -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 CheckASNTag(const byte* input, byte tag, word32 idx, + 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);