From e6c48327c17309e2cc5ccfb3e7eeb3eb3bc674e6 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 11 Sep 2019 09:27:51 -0600 Subject: [PATCH 1/4] sanity check on length before read --- wolfcrypt/src/asn.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 18787949a..3b2fcd82f 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -8036,7 +8036,13 @@ 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) { if (GetBoolean(cert, &extIdx, certSz) < 0) @@ -8055,6 +8061,9 @@ 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)) { if (GetLength(cert, &extIdx, &extLen, certSz) <= 0) From 326f02d76db7d4317688556e8bb51c72c5cbe00c Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 11 Sep 2019 11:28:33 -0700 Subject: [PATCH 2/4] Fix for buffer overrun check logic. --- wolfcrypt/src/asn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 3b2fcd82f..9328e51ef 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -8061,7 +8061,7 @@ 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) + if (ret == 0 && (extIdx + 1) >= certSz) ret = BUFFER_E; if (ret == 0 && From 3b7b81fea7e4786eb9ac1c3c4c89688175520871 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Sun, 15 Sep 2019 22:59:18 -0600 Subject: [PATCH 3/4] 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); From f532143094fee0dd8ab169e0cb1f58fe10f693b2 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Thu, 19 Sep 2019 02:09:51 -0600 Subject: [PATCH 4/4] adjust CheckASNTag to be GetASNTag --- src/ssl.c | 7 +- wolfcrypt/src/asn.c | 416 ++++++++++++++++++++++++++------------ wolfcrypt/src/pkcs12.c | 82 ++++++-- wolfcrypt/src/pkcs7.c | 383 +++++++++++++++++++++++------------ wolfcrypt/src/wc_pkcs11.c | 13 +- wolfssl/wolfcrypt/asn.h | 4 +- 6 files changed, 619 insertions(+), 286 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 9bd7382eb..bc046ee9f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -34722,8 +34722,13 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) if (no_name == 1) { int length; word32 idx = 0; + byte tag; - if (CheckASNTag(a->obj, ASN_OBJECT_ID, idx++, a->objSz) != 0) { + 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; } diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index d2958b7c3..f54bdee2c 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -199,20 +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) +/* 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) { - if (idx + 1 > inputSz) { - WOLFSSL_MSG("Buffer to small for ASN tag"); + 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; } - if (tag == input[idx]) { - return 0; - } - - return ASN_PARSE_E; + *tag = input[idx]; + *inOutIdx = idx + ASN_TAG_SZ; + return 0; } @@ -220,9 +230,13 @@ static int GetASNHeader_ex(const byte* input, byte tag, word32* inOutIdx, int* l word32 maxIdx, int check) { word32 idx = *inOutIdx; + byte tagFound; int length; - if (CheckASNTag(input, tag, idx++, maxIdx) != 0) + if (GetASNTag(input, &idx, &tagFound, maxIdx) != 0) + return ASN_PARSE_E; + + if (tagFound != tag) return ASN_PARSE_E; if (GetLength_ex(input, &idx, &length, maxIdx, check) < 0) @@ -462,7 +476,9 @@ static int GetInteger7Bit(const byte* input, word32* inOutIdx, word32 maxIdx) if ((idx + 3) > maxIdx) return BUFFER_E; - if (CheckASNTag(input, ASN_INTEGER, idx++, maxIdx) != 0) + 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; @@ -686,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 (CheckASNTag(input, ASN_INTEGER, idx++, maxIdx) != 0) + if (GetASNTag(input, &idx, &tag, maxIdx) != 0) + return ASN_PARSE_E; + + if (tag != ASN_INTEGER) return ASN_PARSE_E; if (input[idx++] != 0x01) @@ -709,6 +729,7 @@ WOLFSSL_LOCAL int GetShortInt(const byte* input, word32* inOutIdx, int* number, { word32 idx = *inOutIdx; word32 len; + byte tag; *number = 0; @@ -716,7 +737,10 @@ WOLFSSL_LOCAL int GetShortInt(const byte* input, word32* inOutIdx, int* number, if ((idx + 2) > maxIdx) return BUFFER_E; - if (CheckASNTag(input, ASN_INTEGER, idx++, maxIdx) != 0) + if (GetASNTag(input, &idx, &tag, maxIdx) != 0) + return ASN_PARSE_E; + + if (tag != ASN_INTEGER) return ASN_PARSE_E; len = input[idx++]; @@ -785,17 +809,15 @@ 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; + byte tag; WOLFSSL_ENTER("GetExplicitVersion"); - ret = CheckASNTag(input, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED), - idx++, maxIdx); - if (ret == BUFFER_E) - return ret; + if (GetASNTag(input, &idx, &tag, maxIdx) != 0) + return ASN_PARSE_E; - if (ret == 0) { + if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) { *inOutIdx = ++idx; /* skip header */ return GetMyVersion(input, inOutIdx, version, maxIdx); } @@ -863,7 +885,11 @@ static int CheckBitString(const byte* input, word32* inOutIdx, int* len, int length; byte b; - if (CheckASNTag(input, ASN_BIT_STRING, idx++, maxIdx) != 0) { + if (GetASNTag(input, &idx, &b, maxIdx) != 0) { + return ASN_BITSTR_E; + } + + if (b != ASN_BIT_STRING) { return ASN_BITSTR_E; } @@ -962,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; @@ -984,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 && - CheckASNTag(ber, (ASN_SEQUENCE | ASN_CONSTRUCTED), i, berSz) != 0 && - CheckASNTag(ber, (ASN_SET | ASN_CONSTRUCTED), i, berSz) != 0) { + 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. */ @@ -2111,11 +2145,15 @@ int GetASNObjectId(const byte* input, word32* inOutIdx, int* len, { word32 idx = *inOutIdx; int length; + byte tag; if ((idx + 1) > maxIdx) return BUFFER_E; - if (CheckASNTag(input, ASN_OBJECT_ID, idx++, maxIdx) != 0) + 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) @@ -2258,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 && CheckASNTag(input, ASN_TAG_NULL, idx, maxIdx) == 0) { - 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; @@ -2333,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; @@ -2348,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 (CheckASNTag(input, ASN_OBJECT_ID, idx, sz) == 0) { + 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; } @@ -3462,9 +3512,16 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password, } /* OPTIONAL key length */ - if (seqEnd > inOutIdx && - CheckASNTag(input, ASN_INTEGER, inOutIdx, sz) == 0) { - 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); } } @@ -3761,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); @@ -3817,9 +3875,15 @@ int DecryptContent(byte* input, word32 sz,const char* password, int passwordSz) } /* OPTIONAL key length */ - if (seqEnd > inOutIdx && - CheckASNTag(input, ASN_INTEGER, inOutIdx, sz) == 0) { - 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); } } @@ -3860,7 +3924,11 @@ int DecryptContent(byte* input, word32 sz,const char* password, int passwordSz) inOutIdx += length; } - if (CheckASNTag(input, (ASN_CONTEXT_SPECIFIC | 0), inOutIdx++, sz) != 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); } @@ -3896,6 +3964,10 @@ 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) + word32 localIdx; + byte tag; +#endif if (input == NULL || inOutIdx == NULL) return BAD_FUNC_ARG; @@ -3904,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) - ret = CheckASNTag(input, ASN_INTEGER, *inOutIdx, inSz); - if (ret == BUFFER_E) - return ret; + localIdx = *inOutIdx; + if (GetASNTag(input, &localIdx, &tag, inSz) < 0) + return BUFFER_E; - if (ret != 0) { + 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; @@ -3920,7 +3992,12 @@ int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz, if (*inOutIdx >= inSz) { return BUFFER_E; } - if (CheckASNTag(input, ASN_TAG_NULL, *inOutIdx, inSz) == 0) { + + 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; @@ -4508,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 (CheckASNTag(cert->source, (ASN_SEQUENCE | ASN_CONSTRUCTED), - cert->srcIdx, cert->maxIdx) != 0) { + 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; @@ -4657,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; @@ -4682,8 +4765,12 @@ static int GetName(DecodedCert* cert, int nameType) return BUFFER_E; } - if (CheckASNTag(cert->source, ASN_OBJECT_ID, cert->srcIdx, cert->maxIdx) - == 0) { + 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) @@ -6854,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"); @@ -6872,8 +6960,11 @@ static int DecodeAltNames(const byte* input, int sz, DecodedCert* cert) return ASN_PARSE_E; } - if (CheckASNTag(input, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED), - idx++, sz) != 0) { + 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; } @@ -6967,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) @@ -6988,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"); @@ -7004,22 +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 (CheckASNTag(input, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0), idx, - sz) == 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 (CheckASNTag(input, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | - CRLDP_FULL_NAME), idx, sz) == 0) + 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 (CheckASNTag(input, (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI), - idx, sz) == 0) + localIdx = idx; + if (GetASNTag(input, &localIdx, &tag, sz) == 0 && + tag == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI)) { idx++; if (GetLength(input, &idx, &length, sz) < 0) @@ -7040,9 +7137,10 @@ static int DecodeCrlDist(const byte* input, int sz, DecodedCert* cert) } /* Check for reasonFlags */ + localIdx = idx; if (idx < (word32)sz && - CheckASNTag(input, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1), idx, - sz) == 0) + GetASNTag(input, &localIdx, &tag, sz) == 0 && + tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) { idx++; if (GetLength(input, &idx, &length, sz) < 0) @@ -7051,9 +7149,10 @@ static int DecodeCrlDist(const byte* input, int sz, DecodedCert* cert) } /* Check for cRLIssuer */ + localIdx = idx; if (idx < (word32)sz && - CheckASNTag(input, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2), idx, - sz) == 0) + GetASNTag(input, &localIdx, &tag, sz) == 0 && + tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2)) { idx++; if (GetLength(input, &idx, &length, sz) < 0) @@ -7099,9 +7198,8 @@ static int DecodeAuthInfo(const byte* input, int sz, DecodedCert* cert) /* Only supporting URIs right now. */ - if (CheckASNTag(input, (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI), idx++, - sz) == 0) - b = (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI); + if (GetASNTag(input, &idx, &b, sz) < 0) + return ASN_PARSE_E; if (GetLength(input, &idx, &length, sz) < 0) return ASN_PARSE_E; @@ -7124,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"); @@ -7132,7 +7231,11 @@ static int DecodeAuthKeyId(const byte* input, int sz, DecodedCert* cert) return ASN_PARSE_E; } - if (CheckASNTag(input, (ASN_CONTEXT_SPECIFIC | 0), idx++, sz) != 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; } @@ -7583,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 (CheckASNTag(input, ASN_EXTENSIONS, idx++, sz) != 0) { + 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; } @@ -7605,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; @@ -7623,14 +7733,17 @@ static int DecodeCertExtensions(DecodedCert* cert) return BUFFER_E; } - if (CheckASNTag(input, ASN_BOOLEAN, idx, sz) == 0) { - 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 */ @@ -7918,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; @@ -7948,12 +8064,14 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, } if (ret == 0) { /* version - optional */ - if (CheckASNTag(cert, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED), - idx, certSz) == 0) { - 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; + } } } @@ -8009,12 +8127,14 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, } if (ret == 0) { /* issuerUniqueID - optional */ - if (CheckASNTag(cert, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1), - idx, certSz) == 0) { - 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) { @@ -8023,12 +8143,14 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, } if (ret == 0) { /* subjectUniqueID - optional */ - if (CheckASNTag(cert, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2), - idx, certSz) == 0) { - 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; + } } } @@ -8037,8 +8159,9 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, ret = BUFFER_E; } /* extensions - optional */ - if (ret == 0 && CheckASNTag(cert, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | - 3), idx, certSz) == 0) { + 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; @@ -8067,7 +8190,9 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, } if (ret == 0) { - if (CheckASNTag(cert, ASN_BOOLEAN, extIdx, certSz) == 0) { + localIdx = extIdx; + if (GetASNTag(cert, &localIdx, &tag, certSz) == 0 && + tag == ASN_BOOLEAN) { if (GetBoolean(cert, &extIdx, certSz) < 0) ret = ASN_PARSE_E; } @@ -8088,8 +8213,8 @@ static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, ret = BUFFER_E; if (ret == 0 && - CheckASNTag(cert, (ASN_CONTEXT_SPECIFIC | 0), - extIdx++, certSz) == 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) { @@ -12975,14 +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) { int length; word32 maxExtensionsIdx; decoded->srcIdx = decoded->extensionsIdx; - if (CheckASNTag(decoded->source, ASN_EXTENSIONS, decoded->srcIdx++, - decoded->maxIdx) != 0) { + if (GetASNTag(decoded->source, &decoded->srcIdx, &tag, decoded->maxIdx) + != 0) { + return ASN_PARSE_E; + } + + if (tag != ASN_EXTENSIONS) { ret = ASN_PARSE_E; } else if (GetLength(decoded->source, &decoded->srcIdx, &length, @@ -13709,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 (CheckASNTag(input, ASN_INTEGER, *inOutIdx, inSz) == 0) { + localIdx = *inOutIdx; + if (GetASNTag(input, &localIdx, &tag, inSz) == 0 && tag == ASN_INTEGER) { if (GetASNInt(input, inOutIdx, &len, inSz) < 0) return ASN_PARSE_E; } @@ -13741,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; @@ -13760,8 +13894,9 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, return BUFFER_E; } - if (CheckASNTag(input, (ASN_SEQUENCE | ASN_CONSTRUCTED), *inOutIdx, inSz) - == 0) { + localIdx = *inOutIdx; + if (GetASNTag(input, &localIdx, &tag, inSz) == 0 && + tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) { #ifdef WOLFSSL_CUSTOM_CURVES ecc_set_type* curve; int len; @@ -13813,8 +13948,9 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, key->heap, DYNAMIC_TYPE_ECC_BUFFER); } if (ret == 0) { - if (*inOutIdx < inSz && CheckASNTag(input, ASN_BIT_STRING, - *inOutIdx, inSz) == 0) { + 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; @@ -14329,12 +14465,16 @@ static int GetEnumerated(const byte* input, word32* inOutIdx, int *value, { word32 idx = *inOutIdx; word32 len; + byte tag; WOLFSSL_ENTER("GetEnumerated"); *value = 0; - if (CheckASNTag(input, ASN_ENUMERATED, idx++, sz) != 0) + if (GetASNTag(input, &idx, &tag, sz) < 0) + return ASN_PARSE_E; + + if (tag != ASN_ENUMERATED) return ASN_PARSE_E; if ((int)idx >= sz) @@ -14357,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"); @@ -14438,9 +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) && - CheckASNTag(source, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0), idx, - size) == 0) + GetASNTag(source, &localIdx, &tag, size) == 0 && + tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) { idx++; if (GetLength(source, &idx, &length, size) < 0) @@ -14459,9 +14601,11 @@ static int DecodeSingleResponse(byte* source, #endif #endif } + + localIdx = idx; if (((int)(idx - prevIndex) < wrapperSz) && - CheckASNTag(source, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1), idx, - size) == 0) + GetASNTag(source, &localIdx, &tag, size) == 0 && + tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) { idx++; if (GetLength(source, &idx, &length, size) < 0) @@ -14482,14 +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 (CheckASNTag(source, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1), idx++, - sz) != 0) + 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) @@ -14501,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; @@ -14518,7 +14667,8 @@ static int DecodeOcspRespExtensions(byte* source, return BUFFER_E; } - if (CheckASNTag(source, ASN_BOOLEAN, idx, sz) == 0) { + 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) @@ -14550,10 +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; int ret; + byte tag; WOLFSSL_ENTER("DecodeResponseData"); @@ -14567,8 +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 (CheckASNTag(source, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED), idx, - size) == 0) + 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) @@ -14576,10 +14728,10 @@ static int DecodeResponseData(byte* source, } else version = 0; - if (CheckASNTag(source, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1), idx, - size) == 0 || - CheckASNTag(source, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2), idx, - size) == 0) + 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) @@ -14616,11 +14768,14 @@ static int DecodeCerts(byte* source, word32* ioIndex, OcspResponse* resp, word32 size) { word32 idx = *ioIndex; + byte tag; WOLFSSL_ENTER("DecodeCerts"); - if (CheckASNTag(source, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC), idx++, - size) == 0) + if (GetASNTag(source, &idx, &tag, size) < 0) + return ASN_PARSE_E; + + if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) { int length; @@ -14786,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"); @@ -14803,8 +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 (CheckASNTag(source, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC), idx++, - size) != 0) + 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; @@ -15114,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 (CheckASNTag(source, ASN_OBJECT_ID, *idx, maxIdx) == 0) { + 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) @@ -15272,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"); @@ -15295,7 +15455,8 @@ int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm) dcrl->sigIndex = len + idx; /* may have version */ - if (CheckASNTag(buff, ASN_INTEGER, idx, sz) == 0) { + localIdx = idx; + if (GetASNTag(buff, &localIdx, &tag, sz) == 0 && tag == ASN_INTEGER) { if (GetMyVersion(buff, &idx, &version, sz) < 0) return ASN_PARSE_E; } @@ -15332,8 +15493,9 @@ int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm) #endif } + localIdx = idx; if (idx != dcrl->sigIndex && - CheckASNTag(buff, CRL_EXTENSIONS, idx, sz) != 0) { + GetASNTag(buff, &localIdx, &tag, sz) == 0 && tag != CRL_EXTENSIONS) { if (GetSequence(buff, &idx, &len, sz) < 0) return ASN_PARSE_E; diff --git a/wolfcrypt/src/pkcs12.c b/wolfcrypt/src/pkcs12.c index 8780a2647..9c01204d3 100644 --- a/wolfcrypt/src/pkcs12.c +++ b/wolfcrypt/src/pkcs12.c @@ -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,8 +216,12 @@ static int GetSafeContent(WC_PKCS12* pkcs12, const byte* input, safe->oid = oid; /* check tag, length */ - if (CheckASNTag(input, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC), localIdx++, - maxIdx) != 0) { + 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; @@ -234,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 (CheckASNTag(input, ASN_OCTET_STRING, localIdx++, maxIdx) != 0) { + 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; @@ -348,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 @@ -381,7 +392,12 @@ static int GetSignData(WC_PKCS12* pkcs12, const byte* mem, word32* idx, #endif /* Digest: should be octet type holding digest */ - if (CheckASNTag(mem, ASN_OCTET_STRING, curIdx++, totalSz) != 0) { + 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; @@ -412,7 +428,11 @@ static int GetSignData(WC_PKCS12* pkcs12, const byte* mem, word32* idx, curIdx += mac->digestSz; /* get salt, should be octet string */ - if (CheckASNTag(mem, ASN_OCTET_STRING, curIdx++, totalSz) != 0) { + 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); } @@ -973,14 +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 (CheckASNTag(data, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC), - idx++, ci->dataSz) != 0) { + 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) { @@ -1038,14 +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 (CheckASNTag(data, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC), - idx++, ci->dataSz) != 0) { + 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 (CheckASNTag(data, ASN_OCTET_STRING, idx++, ci->dataSz) != 0) { + + 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) { @@ -1075,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 (CheckASNTag(data, (ASN_CONSTRUCTED | - ASN_CONTEXT_SPECIFIC), idx++, ci->dataSz) != 0) { + 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) { @@ -1109,8 +1142,10 @@ int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, byte* k; WOLFSSL_MSG("PKCS12 Shrouded Key Bag found"); - if (CheckASNTag(data, (ASN_CONSTRUCTED | - ASN_CONTEXT_SPECIFIC), idx++, ci->dataSz) != 0) { + 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, @@ -1171,8 +1206,10 @@ int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, { WC_DerCertList* node; WOLFSSL_MSG("PKCS12 Cert Bag found"); - if (CheckASNTag(data, (ASN_CONSTRUCTED | - ASN_CONTEXT_SPECIFIC), idx++, ci->dataSz) != 0) { + 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) { @@ -1193,16 +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 (CheckASNTag(data, (ASN_CONSTRUCTED | - ASN_CONTEXT_SPECIFIC), idx++, ci->dataSz) != 0) { + 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 (CheckASNTag(data, ASN_OCTET_STRING, idx++, - ci->dataSz) != 0) { + 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); } diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index b399c5858..cc3c9d34c 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -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 (CheckASNTag(list->oid, ASN_OBJECT_ID, idx++, list->oidSz) != 0) { + 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 && CheckASNTag(in, (ASN_CONSTRUCTED | - ASN_CONTEXT_SPECIFIC | 0), idx, inSz) == 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,8 +3935,10 @@ static int wc_PKCS7_ParseSignerInfo(PKCS7* pkcs7, byte* in, word32 inSz, if (idx + 1 > inSz) ret = BUFFER_E; - if (ret == 0 && CheckASNTag(in, ASN_OCTET_STRING, idx++, inSz) - != 0) + 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) @@ -3939,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 (CheckASNTag(in, ASN_CONTEXT_SPECIFIC, idx, inSz) == 0) { + 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; @@ -3972,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 && CheckASNTag(in, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC - | 0), idx, inSz) == 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) @@ -4043,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 @@ -4166,8 +4178,10 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, } /* get the ContentInfo content */ - if (ret == 0 && CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | - ASN_CONTEXT_SPECIFIC | 0), idx++, totalSz) != 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, @@ -4267,8 +4281,10 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, break; } - if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | - 0), localIdx++, pkiMsgSz) != 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, @@ -4280,11 +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 && CheckASNTag(pkiMsg, (ASN_OCTET_STRING | - ASN_CONSTRUCTED), localIdx, pkiMsgSz) == 0) { + 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) @@ -4296,8 +4313,11 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, ret = BUFFER_E; } - if (ret == 0 && CheckASNTag(pkiMsg, ASN_OCTET_STRING, - localIdx++, pkiMsgSz) != 0) + 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, @@ -4314,8 +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 (CheckASNTag(pkiMsg, ASN_OCTET_STRING, localIdx++, pkiMsgSz) - != 0) + if (ret == 0 && tag != ASN_OCTET_STRING) ret = ASN_PARSE_E; if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, @@ -4442,8 +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 (CheckASNTag(pkiMsg, ASN_OCTET_STRING, localIdx++, - totalSz) != 0) + 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) @@ -4550,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 && CheckASNTag(pkiMsg2, (ASN_CONSTRUCTED | - ASN_CONTEXT_SPECIFIC | 0), idx, pkiMsg2Sz) == 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) @@ -4633,8 +4654,10 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, if (length < MAX_LENGTH_SZ + ASN_TAG_SZ) ret = BUFFER_E; - if (CheckASNTag(pkiMsg2, (ASN_CONSTRUCTED | ASN_SEQUENCE), - certIdx++, pkiMsg2Sz) == 0) { + 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; @@ -4685,8 +4708,14 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, certIdx + 1 < (word32)length; i++) { localIdx = certIdx; - if (CheckASNTag(pkiMsg2, (ASN_CONSTRUCTED | - ASN_SEQUENCE), certIdx++, pkiMsg2Sz) == 0) { + 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; @@ -4800,8 +4829,9 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, if (ret == 0 && idx >= maxIdx) ret = BUFFER_E; - if (ret == 0 && CheckASNTag(pkiMsg2, (ASN_CONSTRUCTED | - ASN_CONTEXT_SPECIFIC | 1), idx, pkiMsg2Sz) == 0) { + 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; @@ -4871,8 +4901,9 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, ret = BUFFER_E; /* Get the signature */ - if (ret == 0 && CheckASNTag(pkiMsg2, ASN_OCTET_STRING, idx, - pkiMsg2Sz) == 0) { + localIdx = idx; + if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag, + pkiMsg2Sz) == 0 && tag == ASN_OCTET_STRING) { idx++; if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0) @@ -7878,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; @@ -8020,17 +8053,20 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, #endif } else { - /* remove SubjectKeyIdentifier */ - if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC - | 0), (*idx)++, pkiMsgSz) != 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 (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) - != 0) + 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) @@ -8052,9 +8088,11 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, return ALGO_ID_E; /* read encryptedKey */ - if (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) != 0){ + 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; @@ -8192,14 +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 (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0), - *idx, pkiMsgSz) == 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; @@ -8208,9 +8246,8 @@ static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari, } /* remove OriginatorPublicKey */ - if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1), *idx, - pkiMsgSz) == 0) { - (*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; @@ -8235,15 +8272,19 @@ static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari, } /* remove ECPoint BIT STRING */ - if ((pkiMsgSz > (*idx + 1)) && (CheckASNTag(pkiMsg, ASN_BIT_STRING, (*idx)++, - pkiMsgSz) != 0)) + 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)) || (CheckASNTag(pkiMsg, ASN_OTHER_TYPE, - (*idx)++, pkiMsgSz) != 0)) + 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 */ @@ -8276,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; @@ -8283,8 +8325,11 @@ static int wc_PKCS7_KariGetUserKeyingMaterial(WC_PKCS7_KARI* kari, savedIdx = *idx; /* starts with EXPLICIT [1] */ - if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1), - (*idx)++, pkiMsgSz) != 0) { + if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) { + *idx = savedIdx; + return 0; + } + if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) { *idx = savedIdx; return 0; } @@ -8295,8 +8340,11 @@ static int wc_PKCS7_KariGetUserKeyingMaterial(WC_PKCS7_KARI* kari, } /* get OCTET STRING */ - if ( (pkiMsgSz > ((*idx) + 1)) && - (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) != 0)) { + if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) { + *idx = savedIdx; + return 0; + } + if (tag != ASN_OCTET_STRING) { *idx = savedIdx; return 0; } @@ -8364,16 +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)) && - (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0), - (*idx)++, pkiMsgSz) == 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; @@ -8382,8 +8432,11 @@ static int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari, } /* remove SubjectKeyIdentifier */ - if ( (pkiMsgSz > (*idx + 1)) && - (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) != 0)) + 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) @@ -8500,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) @@ -8515,10 +8570,11 @@ static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari, /* KeyAgreeRecipientIdentifier is CHOICE of IssuerAndSerialNumber * or [0] IMMPLICIT RecipientKeyIdentifier */ - if ( (pkiMsgSz > (*idx + 1)) && - (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0), - *idx, pkiMsgSz) == 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); @@ -8533,8 +8589,10 @@ static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari, return ret; /* remove EncryptedKey */ - if ( (pkiMsgSz > (*idx + 1)) && - (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) != 0)) + 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) @@ -8724,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; @@ -8748,8 +8807,10 @@ static int wc_PKCS7_DecryptPwri(PKCS7* pkcs7, byte* in, word32 inSz, pkiMsgSz = (word32)rc; #endif /* remove KeyDerivationAlgorithmIdentifier */ - if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | - 0), (*idx)++, pkiMsgSz) != 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) @@ -8764,11 +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)) && - (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) - != 0)) { + 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; @@ -8818,9 +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)) && - (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) - != 0)) { + 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; } @@ -8840,8 +8904,12 @@ static int wc_PKCS7_DecryptPwri(PKCS7* pkcs7, byte* in, word32 inSz, *idx += length; /* get EncryptedKey */ - if ( (pkiMsgSz < ((*idx) + 1)) || - (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) != 0)) { + 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; } @@ -8935,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; @@ -8971,7 +9039,10 @@ static int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz, kekIdSz = length; - if (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) != 0) + 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) @@ -8983,8 +9054,9 @@ static int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz, *idx += keyIdSz; /* may have OPTIONAL GeneralizedTime */ - if ((*idx < kekIdSz) && (CheckASNTag(pkiMsg, ASN_GENERALIZED_TIME, - *idx, pkiMsgSz) == 0)) { + 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; @@ -8993,9 +9065,10 @@ static int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz, } /* may have OPTIONAL OtherKeyAttribute */ - if ((*idx < kekIdSz) && (CheckASNTag(pkiMsg, (ASN_SEQUENCE | - ASN_CONSTRUCTED), *idx, pkiMsgSz) == 0)) { - + 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; @@ -9008,7 +9081,10 @@ static int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz, return ASN_PARSE_E; /* get EncryptedKey */ - if (CheckASNTag(pkiMsg, ASN_OCTET_STRING, (*idx)++, pkiMsgSz) != 0) + 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) @@ -9337,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; @@ -9436,13 +9513,18 @@ static int wc_PKCS7_DecryptRecipientInfos(PKCS7* pkcs7, byte* in, #endif } else { + word32 localIdx; /* kari is IMPLICIT[1] */ *idx = savedIdx; - if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | - 1), *idx, pkiMsgSz) == 0) { + 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; @@ -9468,8 +9550,7 @@ static int wc_PKCS7_DecryptRecipientInfos(PKCS7* pkcs7, byte* in, return ret; /* kekri is IMPLICIT[2] */ - } else if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | - ASN_CONTEXT_SPECIFIC | 2), *idx, pkiMsgSz) == 0) { + } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2)) { (*idx)++; if (GetLength(pkiMsg, idx, &version, pkiMsgSz) < 0) @@ -9497,8 +9578,7 @@ static int wc_PKCS7_DecryptRecipientInfos(PKCS7* pkcs7, byte* in, return ret; /* pwri is IMPLICIT[3] */ - } else if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | - ASN_CONTEXT_SPECIFIC | 3), *idx, pkiMsgSz) == 0) { + } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 3)) { #if !defined(NO_PWDBASED) && !defined(NO_SHA) (*idx)++; @@ -9530,8 +9610,7 @@ static int wc_PKCS7_DecryptRecipientInfos(PKCS7* pkcs7, byte* in, #endif /* ori is IMPLICIT[4] */ - } else if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | - ASN_CONTEXT_SPECIFIC | 4), *idx, pkiMsgSz) == 0) { + } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 4)) { (*idx)++; /* found ori */ @@ -9573,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; @@ -9708,8 +9788,11 @@ static int wc_PKCS7_ParseToRecipientInfoSet(PKCS7* pkcs7, byte* in, } } - if (ret == 0 && CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | - ASN_CONTEXT_SPECIFIC | 0), (*idx)++, pkiMsgSz) != 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, @@ -9873,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; @@ -10006,8 +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 && CheckASNTag(pkiMsg, ASN_OCTET_STRING, idx++, - pkiMsgSz) != 0) { + if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) != 0) { + ret = ASN_PARSE_E; + } + + if (ret == 0 && tag != ASN_OCTET_STRING) { ret = ASN_PARSE_E; } @@ -10065,16 +10153,15 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, idx += length; explicitOctet = 0; - if (CheckASNTag(pkiMsg, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | - 0), idx, pkiMsgSz) == 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 && CheckASNTag(pkiMsg, (ASN_CONTEXT_SPECIFIC | 0), idx, - pkiMsgSz) != 0 && - CheckASNTag(pkiMsg, (ASN_CONTEXT_SPECIFIC | - ASN_CONSTRUCTED | 0), idx, pkiMsgSz) != 0) { + if (ret == 0 && tag != (ASN_CONTEXT_SPECIFIC | 0) && + tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) { ret = ASN_PARSE_E; } idx++; @@ -10085,8 +10172,12 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, } if (ret == 0 && explicitOctet) { - if (ret == 0 && CheckASNTag(pkiMsg, ASN_OCTET_STRING, idx++, - pkiMsgSz) != 0) { + if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) { + ret = ASN_PARSE_E; + break; + } + + if (tag != ASN_OCTET_STRING) { ret = ASN_PARSE_E; break; } @@ -10744,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; @@ -10873,8 +10966,11 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in, } /* get nonce, stored in OPTIONAL parameter of AlgoID */ - if (ret == 0 && CheckASNTag(pkiMsg, ASN_OCTET_STRING, idx++, - pkiMsgSz) != 0) { + if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) { + ret = ASN_PARSE_E; + } + + if (ret == 0 && tag != ASN_OCTET_STRING) { ret = ASN_PARSE_E; } @@ -10928,20 +11024,22 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in, if (ret == 0) { explicitOctet = 0; - if (CheckASNTag(pkiMsg, (ASN_CONTEXT_SPECIFIC | - ASN_CONSTRUCTED | 0), idx, pkiMsgSz) == 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) { + ret = GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz); + } + if (ret == 0 && - CheckASNTag(pkiMsg, (ASN_CONTEXT_SPECIFIC | 0), idx, - pkiMsgSz) != 0 && - CheckASNTag(pkiMsg, (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED - | 0), idx, pkiMsgSz) != 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) { @@ -10949,8 +11047,10 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in, } if (explicitOctet) { - if (ret == 0 && CheckASNTag(pkiMsg, ASN_OCTET_STRING, idx++, - pkiMsgSz) != 0) { + if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) { + ret = ASN_PARSE_E; + } + if (ret == 0 && tag != ASN_OCTET_STRING) { ret = ASN_PARSE_E; } @@ -11024,8 +11124,9 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in, #endif /* may have IMPLICIT [1] authenticatedAttributes */ - if (ret == 0 && CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | - ASN_CONTEXT_SPECIFIC | 1), idx, pkiMsgSz) == 0) { + localIdx = idx; + if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 && + tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) { encodedAttribIdx = idx; encodedAttribs = pkiMsg + idx; idx++; @@ -11133,8 +11234,10 @@ authenv_atrbend: /* get authTag OCTET STRING */ - if (ret == 0 && CheckASNTag(pkiMsg, ASN_OCTET_STRING, idx++, - pkiMsgSz) != 0) { + if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) { + ret = ASN_PARSE_E; + } + if (ret == 0 && tag != ASN_OCTET_STRING) { ret = ASN_PARSE_E; } @@ -11565,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) @@ -11572,10 +11676,11 @@ static int wc_PKCS7_DecodeUnprotectedAttributes(PKCS7* pkcs7, byte* pkiMsg, idx = *inOutIdx; - if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1), idx, - pkiMsgSz) != 0) + 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; @@ -11614,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) && @@ -11690,8 +11796,10 @@ int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* in, word32 inSz, pkiMsgSz = (word32)rc; #endif if (pkcs7->version != 3) { - if (ret == 0 && CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | - ASN_CONTEXT_SPECIFIC | 0), idx++, pkiMsgSz) != 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) @@ -11783,8 +11891,9 @@ int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* in, word32 inSz, /* restore saved variables */ expBlockSz = pkcs7->stream->varOne; #endif - if (ret == 0 && CheckASNTag(pkiMsg, ASN_OCTET_STRING, idx++, - pkiMsgSz) != 0) + 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) @@ -11831,8 +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 && CheckASNTag(pkiMsg, (ASN_CONTEXT_SPECIFIC | 0), - idx++, pkiMsgSz) != 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, @@ -12183,8 +12293,10 @@ int wc_PKCS7_DecodeCompressedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz, } /* get ContentInfo content EXPLICIT SEQUENCE */ - if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0), idx++, - pkiMsgSz) != 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) @@ -12225,15 +12337,20 @@ int wc_PKCS7_DecodeCompressedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz, pkcs7->contentOID = contentType; /* get eContent EXPLICIT SEQUENCE */ - if (CheckASNTag(pkiMsg, (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0), idx++, - pkiMsgSz) != 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 (CheckASNTag(pkiMsg, ASN_OCTET_STRING, idx++, pkiMsgSz) != 0) + 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) diff --git a/wolfcrypt/src/wc_pkcs11.c b/wolfcrypt/src/wc_pkcs11.c index 742bfb1d9..cfdd4743c 100644 --- a/wolfcrypt/src/wc_pkcs11.c +++ b/wolfcrypt/src/wc_pkcs11.c @@ -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 && CheckASNTag(point, ASN_OCTET_STRING, i++, pointSz) != 0) + 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 && CheckASNTag(in, ASN_INTGER, i++, inSz) != 0) + 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 && CheckASNTag(in, ASN_INTGER, i++, inSz) != 0) + 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; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 4d3f8e142..96a2e4c7f 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1052,8 +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 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);