From 06d86af67cfde1f6ce164126f8faac100f63b2e3 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sat, 19 Jul 2025 16:59:15 -0400 Subject: [PATCH 01/10] Add API to decode SymmetricKeyPackage and OneSymmetricKey CMS objects --- doc/dox_comments/header_files/pkcs7.h | 94 +++++++++ tests/api.c | 264 ++++++++++++++++++++++++++ tests/api/test_asn.c | 44 +++++ tests/api/test_asn.h | 4 +- wolfcrypt/src/asn.c | 55 ++++++ wolfcrypt/src/error.c | 3 + wolfcrypt/src/pkcs7.c | 107 ++++++++++- wolfssl/wolfcrypt/asn.h | 2 + wolfssl/wolfcrypt/error-crypt.h | 11 +- wolfssl/wolfcrypt/pkcs7.h | 10 +- 10 files changed, 585 insertions(+), 9 deletions(-) diff --git a/doc/dox_comments/header_files/pkcs7.h b/doc/dox_comments/header_files/pkcs7.h index be5a75c43..801f96627 100644 --- a/doc/dox_comments/header_files/pkcs7.h +++ b/doc/dox_comments/header_files/pkcs7.h @@ -712,3 +712,97 @@ int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* pkiMsg, */ int wc_PKCS7_DecodeEncryptedKeyPackage(wc_PKCS7 * pkcs7, byte * pkiMsg, word32 pkiMsgSz, byte * output, word32 outputSz); + +/*! + \ingroup PKCS7 + + \brief This function provides access to a SymmetricKeyPackage attribute. + + \param[in] skp Input buffer containing the SymmetricKeyPackage object. + \param[in] skpSz Size of the SymmetricKeyPackage object. + \param[in] index Index of the attribute to access. + \param[out] attr Buffer in which to store the pointer to the requested + attribute object. + \param[out] attrSz Buffer in which to store the size of the requested + attribute object. + + \retval 0 The requested attribute has been successfully located. + attr and attrSz output variables are populated with the address and size of + the attribute. The attribute will be in the same buffer passed in via the + skp input pointer. + \retval BAD_FUNC_ARG One of the input parameters is invalid. + \retval ASN_PARSE_E An error was encountered parsing the input object. + \retval BAD_INDEX_E The requested attribute index was invalid. +*/ +int wc_PKCS7_DecodeSymmetricKeyPackageAttribute(byte const * skp, + word32 skpSz, size_t index, byte const ** attr, word32 * attrSz); + +/*! + \ingroup PKCS7 + + \brief This function provides access to a SymmetricKeyPackage key. + + \param[in] skp Input buffer containing the SymmetricKeyPackage object. + \param[in] skpSz Size of the SymmetricKeyPackage object. + \param[in] index Index of the key to access. + \param[out] key Buffer in which to store the pointer to the requested + key object. + \param[out] keySz Buffer in which to store the size of the requested + key object. + + \retval 0 The requested key has been successfully located. + key and keySz output variables are populated with the address and size of + the key. The key will be in the same buffer passed in via the + skp input pointer. + \retval BAD_FUNC_ARG One of the input parameters is invalid. + \retval ASN_PARSE_E An error was encountered parsing the input object. + \retval BAD_INDEX_E The requested key index was invalid. +*/ +int wc_PKCS7_DecodeSymmetricKeyPackageKey(byte const * skp, + word32 skpSz, size_t index, byte const ** key, word32 * keySz); + +/*! + \ingroup PKCS7 + + \brief This function provides access to a OneSymmetricKey attribute. + + \param[in] osk Input buffer containing the OneSymmetricKey object. + \param[in] oskSz Size of the OneSymmetricKey object. + \param[in] index Index of the attribute to access. + \param[out] attr Buffer in which to store the pointer to the requested + attribute object. + \param[out] attrSz Buffer in which to store the size of the requested + attribute object. + + \retval 0 The requested attribute has been successfully located. + attr and attrSz output variables are populated with the address and size of + the attribute. The attribute will be in the same buffer passed in via the + osk input pointer. + \retval BAD_FUNC_ARG One of the input parameters is invalid. + \retval ASN_PARSE_E An error was encountered parsing the input object. + \retval BAD_INDEX_E The requested attribute index was invalid. +*/ +int wc_PKCS7_DecodeOneSymmetricKeyAttribute(byte const * osk, + word32 oskSz, size_t index, byte const ** attr, word32 * attrSz); + +/*! + \ingroup PKCS7 + + \brief This function provides access to a OneSymmetricKey key. + + \param[in] osk Input buffer containing the OneSymmetricKey object. + \param[in] oskSz Size of the OneSymmetricKey object. + \param[out] key Buffer in which to store the pointer to the requested + key object. + \param[out] keySz Buffer in which to store the size of the requested + key object. + + \retval 0 The requested key has been successfully located. + key and keySz output variables are populated with the address and size of + the key. The key will be in the same buffer passed in via the + osk input pointer. + \retval BAD_FUNC_ARG One of the input parameters is invalid. + \retval ASN_PARSE_E An error was encountered parsing the input object. +*/ +int wc_PKCS7_DecodeOneSymmetricKeyKey(byte const * osk, + word32 oskSz, byte const ** key, word32 * keySz); diff --git a/tests/api.c b/tests/api.c index 92272d02e..5a5bef57a 100644 --- a/tests/api.c +++ b/tests/api.c @@ -18461,6 +18461,268 @@ static int test_wc_PKCS7_DecodeEncryptedKeyPackage(void) } /* END test_wc_PKCS7_DecodeEncryptedKeyPackage() */ +/* + * Test wc_PKCS7_DecodeSymmetricKeyPackage(). + */ +static int test_wc_PKCS7_DecodeSymmetricKeyPackage(void) +{ + EXPECT_DECLS; +#if defined(HAVE_PKCS7) + byte const * item; + word32 itemSz; + int ret; + + { + static const byte one_key[] = { + 0x30, 0x08, + 0x02, 0x01, 0x01, + 0x30, 0x03, + 0x02, 0x01, 0x01, + }; + /* NULL input data pointer */ + ret = wc_PKCS7_DecodeSymmetricKeyPackageKey( + NULL, sizeof(one_key), 0, &item, &itemSz); + ExpectIntEQ(ret, WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + + /* NULL output item pointer */ + ret = wc_PKCS7_DecodeSymmetricKeyPackageKey( + one_key, sizeof(one_key), 0, NULL, &itemSz); + ExpectIntEQ(ret, WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + + /* NULL output size pointer */ + ret = wc_PKCS7_DecodeSymmetricKeyPackageKey( + one_key, sizeof(one_key), 0, &item, NULL); + ExpectIntEQ(ret, WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + + /* Valid key index 0 extraction */ + ret = wc_PKCS7_DecodeSymmetricKeyPackageKey( + one_key, sizeof(one_key), 0, &item, &itemSz); + ExpectIntEQ(ret, 0); + ExpectPtrEq(item, &one_key[7]); + ExpectIntEQ(itemSz, 3); + + /* Key index 1 out of range */ + ret = wc_PKCS7_DecodeSymmetricKeyPackageKey( + one_key, sizeof(one_key), 1, &item, &itemSz); + ExpectIntEQ(ret, WC_NO_ERR_TRACE(BAD_INDEX_E)); + + /* Attribute index 0 out of range */ + ret = wc_PKCS7_DecodeSymmetricKeyPackageAttribute( + one_key, sizeof(one_key), 0, &item, &itemSz); + ExpectIntEQ(ret, WC_NO_ERR_TRACE(BAD_INDEX_E)); + + /* Attribute index 1 out of range */ + ret = wc_PKCS7_DecodeSymmetricKeyPackageAttribute( + one_key, sizeof(one_key), 1, &item, &itemSz); + ExpectIntEQ(ret, WC_NO_ERR_TRACE(BAD_INDEX_E)); + } + + /* Invalid SKP SEQUENCE header. */ + { + static const byte bad_seq_header[] = { + 0x02, 0x01, 0x42, + }; + ret = wc_PKCS7_DecodeSymmetricKeyPackageKey( + bad_seq_header, sizeof(bad_seq_header), 0, &item, &itemSz); + ExpectIntEQ(ret, WC_NO_ERR_TRACE(ASN_PARSE_E)); + } + + /* Missing version object */ + { + static const byte missing_version[] = { + 0x30, 0x05, + 0x30, 0x03, + 0x02, 0x01, 0x01, + }; + ret = wc_PKCS7_DecodeSymmetricKeyPackageKey( + missing_version, sizeof(missing_version), 0, &item, &itemSz); + ExpectIntEQ(ret, WC_NO_ERR_TRACE(ASN_PARSE_E)); + } + + /* Invalid version number */ + { + static const byte bad_version[] = { + 0x30, 0x08, + 0x02, 0x01, 0x00, + 0x30, 0x03, + 0x02, 0x01, 0x01, + }; + ret = wc_PKCS7_DecodeSymmetricKeyPackageKey( + bad_version, sizeof(bad_version), 0, &item, &itemSz); + ExpectIntEQ(ret, WC_NO_ERR_TRACE(ASN_PARSE_E)); + } + + { + static const byte key3_attr2[] = { + 0x30, 0x18, + 0x02, 0x01, 0x01, + 0xA0, 0x08, + 0x30, 0x06, + 0x02, 0x01, 0x40, + 0x02, 0x01, 0x41, + 0x30, 0x09, + 0x02, 0x01, 0x0A, + 0x02, 0x01, 0x0B, + 0x02, 0x01, 0x0C, + }; + + /* Valid attribute index 0 extraction */ + ret = wc_PKCS7_DecodeSymmetricKeyPackageAttribute( + key3_attr2, sizeof(key3_attr2), 0, &item, &itemSz); + ExpectIntEQ(ret, 0); + ExpectPtrEq(item, &key3_attr2[9]); + ExpectIntEQ(itemSz, 3); + + /* Valid attribute index 1 extraction */ + ret = wc_PKCS7_DecodeSymmetricKeyPackageAttribute( + key3_attr2, sizeof(key3_attr2), 1, &item, &itemSz); + ExpectIntEQ(ret, 0); + ExpectPtrEq(item, &key3_attr2[12]); + ExpectIntEQ(itemSz, 3); + + /* Attribute index 2 out of range */ + ret = wc_PKCS7_DecodeSymmetricKeyPackageAttribute( + key3_attr2, sizeof(key3_attr2), 2, &item, &itemSz); + ExpectIntEQ(ret, WC_NO_ERR_TRACE(BAD_INDEX_E)); + + /* Valid key index 0 extraction */ + ret = wc_PKCS7_DecodeSymmetricKeyPackageKey( + key3_attr2, sizeof(key3_attr2), 0, &item, &itemSz); + ExpectIntEQ(ret, 0); + ExpectPtrEq(item, &key3_attr2[17]); + ExpectIntEQ(itemSz, 3); + + /* Valid key index 1 extraction */ + ret = wc_PKCS7_DecodeSymmetricKeyPackageKey( + key3_attr2, sizeof(key3_attr2), 1, &item, &itemSz); + ExpectIntEQ(ret, 0); + ExpectPtrEq(item, &key3_attr2[20]); + ExpectIntEQ(itemSz, 3); + + /* Valid key index 2 extraction */ + ret = wc_PKCS7_DecodeSymmetricKeyPackageKey( + key3_attr2, sizeof(key3_attr2), 2, &item, &itemSz); + ExpectIntEQ(ret, 0); + ExpectPtrEq(item, &key3_attr2[23]); + ExpectIntEQ(itemSz, 3); + + /* Key index 3 out of range */ + ret = wc_PKCS7_DecodeSymmetricKeyPackageKey( + key3_attr2, sizeof(key3_attr2), 3, &item, &itemSz); + ExpectIntEQ(ret, WC_NO_ERR_TRACE(BAD_INDEX_E)); + } +#endif + return EXPECT_RESULT(); +} /* END test_wc_PKCS7_DecodeSymmetricKeyPackage() */ + + +/* + * Test wc_PKCS7_DecodeOneSymmetricKey(). + */ +static int test_wc_PKCS7_DecodeOneSymmetricKey(void) +{ + EXPECT_DECLS; +#if defined(HAVE_PKCS7) + byte const * item; + word32 itemSz; + int ret; + + { + static const byte key1_attr2[] = { + 0x30, 0x0E, + 0x30, 0x06, + 0x02, 0x01, 0x0A, + 0x02, 0x01, 0x0B, + 0x04, 0x04, 0xAA, 0xBB, 0xCC, 0xDD + }; + + /* NULL input data pointer */ + ret = wc_PKCS7_DecodeOneSymmetricKeyAttribute( + NULL, sizeof(key1_attr2), 0, &item, &itemSz); + ExpectIntEQ(ret, WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + + /* NULL output pointer */ + ret = wc_PKCS7_DecodeOneSymmetricKeyAttribute( + key1_attr2, sizeof(key1_attr2), 0, NULL, &itemSz); + ExpectIntEQ(ret, WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + + /* NULL output size pointer */ + ret = wc_PKCS7_DecodeOneSymmetricKeyAttribute( + key1_attr2, sizeof(key1_attr2), 0, &item, NULL); + ExpectIntEQ(ret, WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + + /* Valid attribute 0 access */ + ret = wc_PKCS7_DecodeOneSymmetricKeyAttribute( + key1_attr2, sizeof(key1_attr2), 0, &item, &itemSz); + ExpectIntEQ(ret, 0); + ExpectPtrEq(item, &key1_attr2[4]); + ExpectIntEQ(itemSz, 3); + + /* Valid attribute 1 access */ + ret = wc_PKCS7_DecodeOneSymmetricKeyAttribute( + key1_attr2, sizeof(key1_attr2), 1, &item, &itemSz); + ExpectIntEQ(ret, 0); + ExpectPtrEq(item, &key1_attr2[7]); + ExpectIntEQ(itemSz, 3); + + /* Attribute index 2 out of range */ + ret = wc_PKCS7_DecodeOneSymmetricKeyAttribute( + key1_attr2, sizeof(key1_attr2), 2, &item, &itemSz); + ExpectIntEQ(ret, WC_NO_ERR_TRACE(BAD_INDEX_E)); + + /* Valid key access */ + ret = wc_PKCS7_DecodeOneSymmetricKeyKey( + key1_attr2, sizeof(key1_attr2), &item, &itemSz); + ExpectIntEQ(ret, 0); + ExpectPtrEq(item, &key1_attr2[12]); + ExpectIntEQ(itemSz, 4); + } + + { + static const byte no_attrs[] = { + 0x30, 0x06, + 0x04, 0x04, 0xAA, 0xBB, 0xCC, 0xDD + }; + + /* Attribute index 0 out of range */ + ret = wc_PKCS7_DecodeOneSymmetricKeyAttribute( + no_attrs, sizeof(no_attrs), 0, &item, &itemSz); + ExpectIntEQ(ret, WC_NO_ERR_TRACE(BAD_INDEX_E)); + + /* Valid key access */ + ret = wc_PKCS7_DecodeOneSymmetricKeyKey( + no_attrs, sizeof(no_attrs), &item, &itemSz); + ExpectIntEQ(ret, 0); + ExpectPtrEq(item, &no_attrs[4]); + ExpectIntEQ(itemSz, 4); + } + + { + static const byte key0_attr2[] = { + 0x30, 0x08, + 0x30, 0x06, + 0x02, 0x01, 0x0A, + 0x02, 0x01, 0x0B, + }; + + /* Valid attribute 0 access */ + ret = wc_PKCS7_DecodeOneSymmetricKeyAttribute( + key0_attr2, sizeof(key0_attr2), 0, &item, &itemSz); + ExpectIntEQ(ret, 0); + ExpectPtrEq(item, &key0_attr2[4]); + ExpectIntEQ(itemSz, 3); + + /* Invalid key access */ + ret = wc_PKCS7_DecodeOneSymmetricKeyKey( + key0_attr2, sizeof(key0_attr2), &item, &itemSz); + ExpectIntEQ(ret, WC_NO_ERR_TRACE(ASN_PARSE_E)); + } + +#endif + return EXPECT_RESULT(); +} /* END test_wc_PKCS7_DecodeOneSymmetricKey() */ + + /* * Testing wc_PKCS7_Degenerate() */ @@ -67937,6 +68199,8 @@ TEST_CASE testCases[] = { TEST_DECL(test_wc_PKCS7_EncodeDecodeEnvelopedData), TEST_DECL(test_wc_PKCS7_EncodeEncryptedData), TEST_DECL(test_wc_PKCS7_DecodeEncryptedKeyPackage), + TEST_DECL(test_wc_PKCS7_DecodeSymmetricKeyPackage), + TEST_DECL(test_wc_PKCS7_DecodeOneSymmetricKey), TEST_DECL(test_wc_PKCS7_Degenerate), TEST_DECL(test_wc_PKCS7_BER), TEST_DECL(test_wc_PKCS7_signed_enveloped), diff --git a/tests/api/test_asn.c b/tests/api/test_asn.c index afd1fdfe2..2c36989c0 100644 --- a/tests/api/test_asn.c +++ b/tests/api/test_asn.c @@ -177,3 +177,47 @@ int test_SetShortInt(void) return EXPECT_RESULT(); } + + +int test_IndexSequenceOf(void) +{ + EXPECT_DECLS; + +#ifndef NO_ASN + static const byte int_seq[] = { + 0x30, 0x0A, + 0x02, 0x01, 0x0A, + 0x02, 0x02, 0x00, 0xF0, + 0x02, 0x01, 0x7F, + }; + static const byte bad_seq[] = { + 0xA0, 0x01, 0x01, + }; + static const byte empty_seq[] = { + 0x30, 0x00, + }; + + byte const * element; + word32 elementSz; + + ExpectIntEQ(IndexSequenceOf(int_seq, sizeof(int_seq), 0U, &element, &elementSz), 0); + ExpectPtrEq(element, &int_seq[2]); + ExpectIntEQ(elementSz, 3); + + ExpectIntEQ(IndexSequenceOf(int_seq, sizeof(int_seq), 1U, &element, &elementSz), 0); + ExpectPtrEq(element, &int_seq[5]); + ExpectIntEQ(elementSz, 4); + + ExpectIntEQ(IndexSequenceOf(int_seq, sizeof(int_seq), 2U, &element, &elementSz), 0); + ExpectPtrEq(element, &int_seq[9]); + ExpectIntEQ(elementSz, 3); + + ExpectIntEQ(IndexSequenceOf(int_seq, sizeof(int_seq), 3U, &element, &elementSz), WC_NO_ERR_TRACE(BAD_INDEX_E)); + + ExpectIntEQ(IndexSequenceOf(bad_seq, sizeof(bad_seq), 0U, &element, &elementSz), WC_NO_ERR_TRACE(ASN_PARSE_E)); + + ExpectIntEQ(IndexSequenceOf(empty_seq, sizeof(empty_seq), 0U, &element, &elementSz), WC_NO_ERR_TRACE(BAD_INDEX_E)); +#endif + + return EXPECT_RESULT(); +} diff --git a/tests/api/test_asn.h b/tests/api/test_asn.h index 2fad6d644..b73da7bb2 100644 --- a/tests/api/test_asn.h +++ b/tests/api/test_asn.h @@ -25,8 +25,10 @@ #include int test_SetShortInt(void); +int test_IndexSequenceOf(void); #define TEST_ASN_DECLS \ - TEST_DECL_GROUP("asn", test_SetShortInt) \ + TEST_DECL_GROUP("asn", test_SetShortInt), \ + TEST_DECL_GROUP("asn", test_IndexSequenceOf) #endif /* WOLFCRYPT_TEST_ASN_H */ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index ec34c9535..c5767aca5 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -2570,6 +2570,61 @@ int GetSequence_ex(const byte* input, word32* inOutIdx, int* len, maxIdx, check); } +/** + * Index a SEQUENCE OF object to get to a specific element. + * + * @param[in] seqOf Buffer holding DER/BER SEQUENCE OF object. + * @param[in] seqOfSz Size of the seqOf SEQUENCE OF object. + * @param[in] seqIndex Index of the SEQUENCE OF element being requested. + * @param[out] out Buffer in which to store pointer to the th element + * of the SEQUENCE OF object. + * @param[out] outSz Buffer in which to store the length of the th + * element of the SEQUENCE OF object. + * + * @retval 0 on success. + * @retval BUFFER_E when there is not enough data to parse. + * @retval BAD_INDEX_E when the given seqIndex is out of range. + * @retval ASN_PARSE_E when the seqOf is not in the expected format. + */ +int IndexSequenceOf(byte const * seqOf, word32 seqOfSz, size_t seqIndex, + byte const ** out, word32 * outSz) +{ + int length; + word32 seqOfIdx = 0U; + byte tagFound; + size_t i; + word32 elementIdx = 0U; + + /* Validate the SEQUENCE OF header. */ + if (GetSequence(seqOf, &seqOfIdx, &length, seqOfSz) < 0) + return ASN_PARSE_E; + + seqOfSz = seqOfIdx + (word32)length; + + for (i = 0U; i <= seqIndex; i++) { + if (seqOfIdx >= seqOfSz) + return BAD_INDEX_E; + + elementIdx = seqOfIdx; + + /* Validate the element tag. */ + if (GetASNTag(seqOf, &seqOfIdx, &tagFound, seqOfSz) != 0) + return ASN_PARSE_E; + + /* Validate and get the element's encoded length. */ + if (GetLength(seqOf, &seqOfIdx, &length, seqOfSz) < 0) + return ASN_PARSE_E; + + seqOfIdx += (word32)length; + } + + /* If the tag and length checks above passed then we've found the requested + * element and validated it fits within seqOfSz. */ + *out = &seqOf[elementIdx]; + *outSz = (seqOfIdx - elementIdx); + return 0; +} + /* Decode the header of a BER/DER encoded SET. * * @param [in] input Buffer holding DER/BER encoded data. diff --git a/wolfcrypt/src/error.c b/wolfcrypt/src/error.c index 014345a1a..3713dbaed 100644 --- a/wolfcrypt/src/error.c +++ b/wolfcrypt/src/error.c @@ -650,6 +650,9 @@ const char* wc_GetErrorString(int error) case WC_ACCEL_INHIBIT_E: return "Crypto acceleration is currently inhibited"; + case BAD_INDEX_E: + return "Bad index"; + case MAX_CODE_E: case WC_SPAN1_MIN_CODE_E: case MIN_CODE_E: diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 1b4fcf687..16f9b7927 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -15305,6 +15305,112 @@ int wc_PKCS7_DecodeCompressedData(wc_PKCS7* pkcs7, byte* pkiMsg, #endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */ +static int wc_PKCS7_DecodeSymmetricKeyPackage(byte const * skp, word32 skpSz, + size_t index, byte const ** out, word32 * outSz, int getKey) +{ + word32 skpIndex = 0; + int length = 0; + int version = 0; + + if (skp == NULL || out == NULL || outSz == NULL) + return BAD_FUNC_ARG; + + /* Expect a SEQUENCE header to start the SymmetricKeyPackage object. */ + if (GetSequence(skp, &skpIndex, &length, skpSz) < 0) + return ASN_PARSE_E; + + /* Expect version v1 */ + if (GetMyVersion(skp, &skpIndex, &version, skpSz) < 0) + return ASN_PARSE_E; + + if (version != 1) + return ASN_PARSE_E; + + if (GetASNHeader(skp, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED, + &skpIndex, &length, skpSz) >= 0) { + /* sKeyPkgAttrs [0] tag found so there are attributes present. */ + if (getKey != 0) { + /* Key was requested, not attribute, so skip the attributes. */ + skpIndex += (word32)length; + } + else { + /* sKeyPkgAttrs is present at &skp[skpIndex], length in length */ + return IndexSequenceOf(&skp[skpIndex], (word32)length, index, out, outSz); + } + } + + if (getKey == 0) { + /* An attribute was requested, but none are present. */ + return BAD_INDEX_E; + } + + /* sKeys is present at &skp[skpIndex]. */ + return IndexSequenceOf(&skp[skpIndex], skpSz - skpIndex, index, out, outSz); +} + +int wc_PKCS7_DecodeSymmetricKeyPackageAttribute(byte const * skp, + word32 skpSz, size_t index, byte const ** attr, word32 * attrSz) +{ + return wc_PKCS7_DecodeSymmetricKeyPackage(skp, skpSz, index, attr, attrSz, 0); +} + +int wc_PKCS7_DecodeSymmetricKeyPackageKey(byte const * skp, + word32 skpSz, size_t index, byte const ** key, word32 * keySz) +{ + return wc_PKCS7_DecodeSymmetricKeyPackage(skp, skpSz, index, key, keySz, 1); +} + +int wc_PKCS7_DecodeOneSymmetricKeyAttribute(byte const * osk, + word32 oskSz, size_t index, byte const ** attr, word32 * attrSz) +{ + word32 oskIndex = 0; + word32 tmpIndex; + int length = 0; + + if (osk == NULL || attr == NULL || attrSz == NULL) + return BAD_FUNC_ARG; + + /* Expect a SEQUENCE header to start the OneSymmetricKey object. */ + if (GetSequence(osk, &oskIndex, &length, oskSz) < 0) + return ASN_PARSE_E; + + tmpIndex = oskIndex; + + if (GetSequence(osk, &tmpIndex, &length, oskSz) < 0) { + /* sKeyAttrs is not present. */ + return BAD_INDEX_E; + } + + /* Index the sKeyAttrs SEQUENCE OF object with the given index. */ + return IndexSequenceOf(&osk[oskIndex], oskSz - oskIndex, index, attr, attrSz); +} + +int wc_PKCS7_DecodeOneSymmetricKeyKey(byte const * osk, + word32 oskSz, byte const ** key, word32 * keySz) +{ + word32 oskIndex = 0; + int length = 0; + + if (osk == NULL || key == NULL || keySz == NULL) + return BAD_FUNC_ARG; + + /* Expect a SEQUENCE header to start the OneSymmetricKey object. */ + if (GetSequence(osk, &oskIndex, &length, oskSz) < 0) + return ASN_PARSE_E; + + if (GetSequence(osk, &oskIndex, &length, oskSz) >= 0) { + /* sKeyAttrs is present. Skip it. */ + oskIndex += (word32)length; + } + + if (GetASNHeader(osk, ASN_OCTET_STRING, &oskIndex, &length, oskSz) < 0) + return ASN_PARSE_E; + + *key = &osk[oskIndex]; + *keySz = (word32)length; + return 0; +} + #else /* HAVE_PKCS7 */ @@ -15315,4 +15421,3 @@ int wc_PKCS7_DecodeCompressedData(wc_PKCS7* pkcs7, byte* pkiMsg, #endif /* HAVE_PKCS7 */ - diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 03ebfd31d..79089227a 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -2219,6 +2219,8 @@ WOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len, word32 maxIdx); WOLFSSL_LOCAL int GetSequence_ex(const byte* input, word32* inOutIdx, int* len, word32 maxIdx, int check); +WOLFSSL_TEST_VIS int IndexSequenceOf(byte const * seqOf, word32 seqOfSz, + size_t seqIndex, byte const ** out, word32 * outSz); WOLFSSL_LOCAL int GetOctetString(const byte* input, word32* inOutIdx, int* len, word32 maxIdx); WOLFSSL_LOCAL int CheckBitString(const byte* input, word32* inOutIdx, int* len, diff --git a/wolfssl/wolfcrypt/error-crypt.h b/wolfssl/wolfcrypt/error-crypt.h index d95e5277a..87692ddce 100644 --- a/wolfssl/wolfcrypt/error-crypt.h +++ b/wolfssl/wolfcrypt/error-crypt.h @@ -305,14 +305,13 @@ enum wolfCrypt_ErrorCodes { DEADLOCK_AVERTED_E = -1000, /* Deadlock averted -- retry the call */ ASCON_AUTH_E = -1001, /* ASCON Authentication check failure */ WC_ACCEL_INHIBIT_E = -1002, /* Crypto acceleration is currently inhibited */ + BAD_INDEX_E = -1003, /* Bad index */ + + WC_SPAN2_LAST_E = -1003, /* Update to indicate last used error code */ + WC_LAST_E = -1003, /* the last code used either here or in + * error-ssl.h */ - WC_SPAN2_LAST_E = -1002, /* Update to indicate last used error code */ WC_SPAN2_MIN_CODE_E = -1999, /* Last usable code in span 2 */ - - WC_LAST_E = -1002, /* the last code used either here or in - * error-ssl.h - */ - MIN_CODE_E = -1999 /* the last code allocated either here or in * error-ssl.h */ diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 011fec9a3..8a8eed11f 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -552,10 +552,18 @@ WOLFSSL_API int wc_PKCS7_DecodeCompressedData(wc_PKCS7* pkcs7, byte* pkiMsg, word32 outputSz); #endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */ +WOLFSSL_API int wc_PKCS7_DecodeSymmetricKeyPackageAttribute(byte const * skp, + word32 skpSz, size_t index, byte const ** attr, word32 * attrSz); +WOLFSSL_API int wc_PKCS7_DecodeSymmetricKeyPackageKey(byte const * skp, + word32 skpSz, size_t index, byte const ** key, word32 * keySz); +WOLFSSL_API int wc_PKCS7_DecodeOneSymmetricKeyAttribute(byte const * osk, + word32 oskSz, size_t index, byte const ** attr, word32 * attrSz); +WOLFSSL_API int wc_PKCS7_DecodeOneSymmetricKeyKey(byte const * osk, + word32 oskSz, byte const ** key, word32 * keySz); + #ifdef __cplusplus } /* extern "C" */ #endif #endif /* HAVE_PKCS7 */ #endif /* WOLF_CRYPT_PKCS7_H */ - From e03fc6858b09abb1b017f15bbd53aa70b5221e49 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 22 Jul 2025 08:24:22 -0400 Subject: [PATCH 02/10] Update Doxygen comment style per code review comments --- doc/dox_comments/header_files/pkcs7.h | 62 +++++++++++++-------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/doc/dox_comments/header_files/pkcs7.h b/doc/dox_comments/header_files/pkcs7.h index 801f96627..60b2cc698 100644 --- a/doc/dox_comments/header_files/pkcs7.h +++ b/doc/dox_comments/header_files/pkcs7.h @@ -718,6 +718,14 @@ int wc_PKCS7_DecodeEncryptedKeyPackage(wc_PKCS7 * pkcs7, \brief This function provides access to a SymmetricKeyPackage attribute. + \return 0 The requested attribute has been successfully located. + attr and attrSz output variables are populated with the address and size of + the attribute. The attribute will be in the same buffer passed in via the + skp input pointer. + \return BAD_FUNC_ARG One of the input parameters is invalid. + \return ASN_PARSE_E An error was encountered parsing the input object. + \return BAD_INDEX_E The requested attribute index was invalid. + \param[in] skp Input buffer containing the SymmetricKeyPackage object. \param[in] skpSz Size of the SymmetricKeyPackage object. \param[in] index Index of the attribute to access. @@ -725,14 +733,6 @@ int wc_PKCS7_DecodeEncryptedKeyPackage(wc_PKCS7 * pkcs7, attribute object. \param[out] attrSz Buffer in which to store the size of the requested attribute object. - - \retval 0 The requested attribute has been successfully located. - attr and attrSz output variables are populated with the address and size of - the attribute. The attribute will be in the same buffer passed in via the - skp input pointer. - \retval BAD_FUNC_ARG One of the input parameters is invalid. - \retval ASN_PARSE_E An error was encountered parsing the input object. - \retval BAD_INDEX_E The requested attribute index was invalid. */ int wc_PKCS7_DecodeSymmetricKeyPackageAttribute(byte const * skp, word32 skpSz, size_t index, byte const ** attr, word32 * attrSz); @@ -742,6 +742,14 @@ int wc_PKCS7_DecodeSymmetricKeyPackageAttribute(byte const * skp, \brief This function provides access to a SymmetricKeyPackage key. + \return 0 The requested key has been successfully located. + key and keySz output variables are populated with the address and size of + the key. The key will be in the same buffer passed in via the + skp input pointer. + \return BAD_FUNC_ARG One of the input parameters is invalid. + \return ASN_PARSE_E An error was encountered parsing the input object. + \return BAD_INDEX_E The requested key index was invalid. + \param[in] skp Input buffer containing the SymmetricKeyPackage object. \param[in] skpSz Size of the SymmetricKeyPackage object. \param[in] index Index of the key to access. @@ -749,14 +757,6 @@ int wc_PKCS7_DecodeSymmetricKeyPackageAttribute(byte const * skp, key object. \param[out] keySz Buffer in which to store the size of the requested key object. - - \retval 0 The requested key has been successfully located. - key and keySz output variables are populated with the address and size of - the key. The key will be in the same buffer passed in via the - skp input pointer. - \retval BAD_FUNC_ARG One of the input parameters is invalid. - \retval ASN_PARSE_E An error was encountered parsing the input object. - \retval BAD_INDEX_E The requested key index was invalid. */ int wc_PKCS7_DecodeSymmetricKeyPackageKey(byte const * skp, word32 skpSz, size_t index, byte const ** key, word32 * keySz); @@ -766,6 +766,14 @@ int wc_PKCS7_DecodeSymmetricKeyPackageKey(byte const * skp, \brief This function provides access to a OneSymmetricKey attribute. + \return 0 The requested attribute has been successfully located. + attr and attrSz output variables are populated with the address and size of + the attribute. The attribute will be in the same buffer passed in via the + osk input pointer. + \return BAD_FUNC_ARG One of the input parameters is invalid. + \return ASN_PARSE_E An error was encountered parsing the input object. + \return BAD_INDEX_E The requested attribute index was invalid. + \param[in] osk Input buffer containing the OneSymmetricKey object. \param[in] oskSz Size of the OneSymmetricKey object. \param[in] index Index of the attribute to access. @@ -773,14 +781,6 @@ int wc_PKCS7_DecodeSymmetricKeyPackageKey(byte const * skp, attribute object. \param[out] attrSz Buffer in which to store the size of the requested attribute object. - - \retval 0 The requested attribute has been successfully located. - attr and attrSz output variables are populated with the address and size of - the attribute. The attribute will be in the same buffer passed in via the - osk input pointer. - \retval BAD_FUNC_ARG One of the input parameters is invalid. - \retval ASN_PARSE_E An error was encountered parsing the input object. - \retval BAD_INDEX_E The requested attribute index was invalid. */ int wc_PKCS7_DecodeOneSymmetricKeyAttribute(byte const * osk, word32 oskSz, size_t index, byte const ** attr, word32 * attrSz); @@ -790,19 +790,19 @@ int wc_PKCS7_DecodeOneSymmetricKeyAttribute(byte const * osk, \brief This function provides access to a OneSymmetricKey key. + \return 0 The requested key has been successfully located. + key and keySz output variables are populated with the address and size of + the key. The key will be in the same buffer passed in via the + osk input pointer. + \return BAD_FUNC_ARG One of the input parameters is invalid. + \return ASN_PARSE_E An error was encountered parsing the input object. + \param[in] osk Input buffer containing the OneSymmetricKey object. \param[in] oskSz Size of the OneSymmetricKey object. \param[out] key Buffer in which to store the pointer to the requested key object. \param[out] keySz Buffer in which to store the size of the requested key object. - - \retval 0 The requested key has been successfully located. - key and keySz output variables are populated with the address and size of - the key. The key will be in the same buffer passed in via the - osk input pointer. - \retval BAD_FUNC_ARG One of the input parameters is invalid. - \retval ASN_PARSE_E An error was encountered parsing the input object. */ int wc_PKCS7_DecodeOneSymmetricKeyKey(byte const * osk, word32 oskSz, byte const ** key, word32 * keySz); From aa986a2b241a8670c610af5188520532e96f933e Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 22 Jul 2025 08:27:00 -0400 Subject: [PATCH 03/10] Update doxygen comment style per code review comments --- wolfcrypt/src/asn.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index c5767aca5..1e9d3369e 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -2581,10 +2581,10 @@ int GetSequence_ex(const byte* input, word32* inOutIdx, int* len, * @param[out] outSz Buffer in which to store the length of the th * element of the SEQUENCE OF object. * - * @retval 0 on success. - * @retval BUFFER_E when there is not enough data to parse. - * @retval BAD_INDEX_E when the given seqIndex is out of range. - * @retval ASN_PARSE_E when the seqOf is not in the expected format. + * @return 0 on success. + * @return BUFFER_E when there is not enough data to parse. + * @return BAD_INDEX_E when the given seqIndex is out of range. + * @return ASN_PARSE_E when the seqOf is not in the expected format. */ int IndexSequenceOf(byte const * seqOf, word32 seqOfSz, size_t seqIndex, byte const ** out, word32 * outSz) From 77bace5010ba3fd1a28b42a7131dc28d90b08dcb Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 22 Jul 2025 14:47:22 -0400 Subject: [PATCH 04/10] Update style per code review comments --- doc/dox_comments/header_files/pkcs7.h | 16 +++++++-------- tests/api/test_asn.c | 8 ++++---- wolfcrypt/src/pkcs7.c | 29 +++++++++++++++------------ wolfssl/wolfcrypt/pkcs7.h | 16 +++++++-------- 4 files changed, 36 insertions(+), 33 deletions(-) diff --git a/doc/dox_comments/header_files/pkcs7.h b/doc/dox_comments/header_files/pkcs7.h index 60b2cc698..3923aec68 100644 --- a/doc/dox_comments/header_files/pkcs7.h +++ b/doc/dox_comments/header_files/pkcs7.h @@ -734,8 +734,8 @@ int wc_PKCS7_DecodeEncryptedKeyPackage(wc_PKCS7 * pkcs7, \param[out] attrSz Buffer in which to store the size of the requested attribute object. */ -int wc_PKCS7_DecodeSymmetricKeyPackageAttribute(byte const * skp, - word32 skpSz, size_t index, byte const ** attr, word32 * attrSz); +int wc_PKCS7_DecodeSymmetricKeyPackageAttribute(const byte * skp, + word32 skpSz, size_t index, const byte ** attr, word32 * attrSz); /*! \ingroup PKCS7 @@ -758,8 +758,8 @@ int wc_PKCS7_DecodeSymmetricKeyPackageAttribute(byte const * skp, \param[out] keySz Buffer in which to store the size of the requested key object. */ -int wc_PKCS7_DecodeSymmetricKeyPackageKey(byte const * skp, - word32 skpSz, size_t index, byte const ** key, word32 * keySz); +int wc_PKCS7_DecodeSymmetricKeyPackageKey(const byte * skp, + word32 skpSz, size_t index, const byte ** key, word32 * keySz); /*! \ingroup PKCS7 @@ -782,8 +782,8 @@ int wc_PKCS7_DecodeSymmetricKeyPackageKey(byte const * skp, \param[out] attrSz Buffer in which to store the size of the requested attribute object. */ -int wc_PKCS7_DecodeOneSymmetricKeyAttribute(byte const * osk, - word32 oskSz, size_t index, byte const ** attr, word32 * attrSz); +int wc_PKCS7_DecodeOneSymmetricKeyAttribute(const byte * osk, + word32 oskSz, size_t index, const byte ** attr, word32 * attrSz); /*! \ingroup PKCS7 @@ -804,5 +804,5 @@ int wc_PKCS7_DecodeOneSymmetricKeyAttribute(byte const * osk, \param[out] keySz Buffer in which to store the size of the requested key object. */ -int wc_PKCS7_DecodeOneSymmetricKeyKey(byte const * osk, - word32 oskSz, byte const ** key, word32 * keySz); +int wc_PKCS7_DecodeOneSymmetricKeyKey(const byte * osk, + word32 oskSz, const byte ** key, word32 * keySz); diff --git a/tests/api/test_asn.c b/tests/api/test_asn.c index 2c36989c0..520150a8f 100644 --- a/tests/api/test_asn.c +++ b/tests/api/test_asn.c @@ -184,20 +184,20 @@ int test_IndexSequenceOf(void) EXPECT_DECLS; #ifndef NO_ASN - static const byte int_seq[] = { + const byte int_seq[] = { 0x30, 0x0A, 0x02, 0x01, 0x0A, 0x02, 0x02, 0x00, 0xF0, 0x02, 0x01, 0x7F, }; - static const byte bad_seq[] = { + const byte bad_seq[] = { 0xA0, 0x01, 0x01, }; - static const byte empty_seq[] = { + const byte empty_seq[] = { 0x30, 0x00, }; - byte const * element; + const byte * element; word32 elementSz; ExpectIntEQ(IndexSequenceOf(int_seq, sizeof(int_seq), 0U, &element, &elementSz), 0); diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 16f9b7927..6866ac152 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -15305,8 +15305,8 @@ int wc_PKCS7_DecodeCompressedData(wc_PKCS7* pkcs7, byte* pkiMsg, #endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */ -static int wc_PKCS7_DecodeSymmetricKeyPackage(byte const * skp, word32 skpSz, - size_t index, byte const ** out, word32 * outSz, int getKey) +static int wc_PKCS7_DecodeSymmetricKeyPackage(const byte * skp, word32 skpSz, + size_t index, const byte ** out, word32 * outSz, int getKey) { word32 skpIndex = 0; int length = 0; @@ -15335,7 +15335,8 @@ static int wc_PKCS7_DecodeSymmetricKeyPackage(byte const * skp, word32 skpSz, } else { /* sKeyPkgAttrs is present at &skp[skpIndex], length in length */ - return IndexSequenceOf(&skp[skpIndex], (word32)length, index, out, outSz); + return IndexSequenceOf(&skp[skpIndex], (word32)length, index, out, + outSz); } } @@ -15348,20 +15349,21 @@ static int wc_PKCS7_DecodeSymmetricKeyPackage(byte const * skp, word32 skpSz, return IndexSequenceOf(&skp[skpIndex], skpSz - skpIndex, index, out, outSz); } -int wc_PKCS7_DecodeSymmetricKeyPackageAttribute(byte const * skp, - word32 skpSz, size_t index, byte const ** attr, word32 * attrSz) +int wc_PKCS7_DecodeSymmetricKeyPackageAttribute(const byte * skp, + word32 skpSz, size_t index, const byte ** attr, word32 * attrSz) { - return wc_PKCS7_DecodeSymmetricKeyPackage(skp, skpSz, index, attr, attrSz, 0); + return wc_PKCS7_DecodeSymmetricKeyPackage(skp, skpSz, index, attr, attrSz, + 0); } -int wc_PKCS7_DecodeSymmetricKeyPackageKey(byte const * skp, - word32 skpSz, size_t index, byte const ** key, word32 * keySz) +int wc_PKCS7_DecodeSymmetricKeyPackageKey(const byte * skp, + word32 skpSz, size_t index, const byte ** key, word32 * keySz) { return wc_PKCS7_DecodeSymmetricKeyPackage(skp, skpSz, index, key, keySz, 1); } -int wc_PKCS7_DecodeOneSymmetricKeyAttribute(byte const * osk, - word32 oskSz, size_t index, byte const ** attr, word32 * attrSz) +int wc_PKCS7_DecodeOneSymmetricKeyAttribute(const byte * osk, + word32 oskSz, size_t index, const byte ** attr, word32 * attrSz) { word32 oskIndex = 0; word32 tmpIndex; @@ -15382,11 +15384,12 @@ int wc_PKCS7_DecodeOneSymmetricKeyAttribute(byte const * osk, } /* Index the sKeyAttrs SEQUENCE OF object with the given index. */ - return IndexSequenceOf(&osk[oskIndex], oskSz - oskIndex, index, attr, attrSz); + return IndexSequenceOf(&osk[oskIndex], oskSz - oskIndex, index, attr, + attrSz); } -int wc_PKCS7_DecodeOneSymmetricKeyKey(byte const * osk, - word32 oskSz, byte const ** key, word32 * keySz) +int wc_PKCS7_DecodeOneSymmetricKeyKey(const byte * osk, + word32 oskSz, const byte ** key, word32 * keySz) { word32 oskIndex = 0; int length = 0; diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 8a8eed11f..617ff5177 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -552,14 +552,14 @@ WOLFSSL_API int wc_PKCS7_DecodeCompressedData(wc_PKCS7* pkcs7, byte* pkiMsg, word32 outputSz); #endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */ -WOLFSSL_API int wc_PKCS7_DecodeSymmetricKeyPackageAttribute(byte const * skp, - word32 skpSz, size_t index, byte const ** attr, word32 * attrSz); -WOLFSSL_API int wc_PKCS7_DecodeSymmetricKeyPackageKey(byte const * skp, - word32 skpSz, size_t index, byte const ** key, word32 * keySz); -WOLFSSL_API int wc_PKCS7_DecodeOneSymmetricKeyAttribute(byte const * osk, - word32 oskSz, size_t index, byte const ** attr, word32 * attrSz); -WOLFSSL_API int wc_PKCS7_DecodeOneSymmetricKeyKey(byte const * osk, - word32 oskSz, byte const ** key, word32 * keySz); +WOLFSSL_API int wc_PKCS7_DecodeSymmetricKeyPackageAttribute(const byte * skp, + word32 skpSz, size_t index, const byte ** attr, word32 * attrSz); +WOLFSSL_API int wc_PKCS7_DecodeSymmetricKeyPackageKey(const byte * skp, + word32 skpSz, size_t index, const byte ** key, word32 * keySz); +WOLFSSL_API int wc_PKCS7_DecodeOneSymmetricKeyAttribute(const byte * osk, + word32 oskSz, size_t index, const byte ** attr, word32 * attrSz); +WOLFSSL_API int wc_PKCS7_DecodeOneSymmetricKeyKey(const byte * osk, + word32 oskSz, const byte ** key, word32 * keySz); #ifdef __cplusplus } /* extern "C" */ From 15c8730ef7ababf2237f378499e13f2e8ecd84f3 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 22 Jul 2025 14:50:42 -0400 Subject: [PATCH 05/10] Use wc_ prefix for IndexSequenceOf() --- tests/api/test_asn.c | 14 +++++++------- tests/api/test_asn.h | 4 ++-- wolfcrypt/src/asn.c | 2 +- wolfcrypt/src/pkcs7.c | 9 +++++---- wolfssl/wolfcrypt/asn.h | 2 +- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/tests/api/test_asn.c b/tests/api/test_asn.c index 520150a8f..9bc236e19 100644 --- a/tests/api/test_asn.c +++ b/tests/api/test_asn.c @@ -179,7 +179,7 @@ int test_SetShortInt(void) } -int test_IndexSequenceOf(void) +int test_wc_IndexSequenceOf(void) { EXPECT_DECLS; @@ -200,23 +200,23 @@ int test_IndexSequenceOf(void) const byte * element; word32 elementSz; - ExpectIntEQ(IndexSequenceOf(int_seq, sizeof(int_seq), 0U, &element, &elementSz), 0); + ExpectIntEQ(wc_IndexSequenceOf(int_seq, sizeof(int_seq), 0U, &element, &elementSz), 0); ExpectPtrEq(element, &int_seq[2]); ExpectIntEQ(elementSz, 3); - ExpectIntEQ(IndexSequenceOf(int_seq, sizeof(int_seq), 1U, &element, &elementSz), 0); + ExpectIntEQ(wc_IndexSequenceOf(int_seq, sizeof(int_seq), 1U, &element, &elementSz), 0); ExpectPtrEq(element, &int_seq[5]); ExpectIntEQ(elementSz, 4); - ExpectIntEQ(IndexSequenceOf(int_seq, sizeof(int_seq), 2U, &element, &elementSz), 0); + ExpectIntEQ(wc_IndexSequenceOf(int_seq, sizeof(int_seq), 2U, &element, &elementSz), 0); ExpectPtrEq(element, &int_seq[9]); ExpectIntEQ(elementSz, 3); - ExpectIntEQ(IndexSequenceOf(int_seq, sizeof(int_seq), 3U, &element, &elementSz), WC_NO_ERR_TRACE(BAD_INDEX_E)); + ExpectIntEQ(wc_IndexSequenceOf(int_seq, sizeof(int_seq), 3U, &element, &elementSz), WC_NO_ERR_TRACE(BAD_INDEX_E)); - ExpectIntEQ(IndexSequenceOf(bad_seq, sizeof(bad_seq), 0U, &element, &elementSz), WC_NO_ERR_TRACE(ASN_PARSE_E)); + ExpectIntEQ(wc_IndexSequenceOf(bad_seq, sizeof(bad_seq), 0U, &element, &elementSz), WC_NO_ERR_TRACE(ASN_PARSE_E)); - ExpectIntEQ(IndexSequenceOf(empty_seq, sizeof(empty_seq), 0U, &element, &elementSz), WC_NO_ERR_TRACE(BAD_INDEX_E)); + ExpectIntEQ(wc_IndexSequenceOf(empty_seq, sizeof(empty_seq), 0U, &element, &elementSz), WC_NO_ERR_TRACE(BAD_INDEX_E)); #endif return EXPECT_RESULT(); diff --git a/tests/api/test_asn.h b/tests/api/test_asn.h index b73da7bb2..aeea0f735 100644 --- a/tests/api/test_asn.h +++ b/tests/api/test_asn.h @@ -25,10 +25,10 @@ #include int test_SetShortInt(void); -int test_IndexSequenceOf(void); +int test_wc_IndexSequenceOf(void); #define TEST_ASN_DECLS \ TEST_DECL_GROUP("asn", test_SetShortInt), \ - TEST_DECL_GROUP("asn", test_IndexSequenceOf) + TEST_DECL_GROUP("asn", test_wc_IndexSequenceOf) #endif /* WOLFCRYPT_TEST_ASN_H */ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 1e9d3369e..000c8923a 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -2586,7 +2586,7 @@ int GetSequence_ex(const byte* input, word32* inOutIdx, int* len, * @return BAD_INDEX_E when the given seqIndex is out of range. * @return ASN_PARSE_E when the seqOf is not in the expected format. */ -int IndexSequenceOf(byte const * seqOf, word32 seqOfSz, size_t seqIndex, +int wc_IndexSequenceOf(byte const * seqOf, word32 seqOfSz, size_t seqIndex, byte const ** out, word32 * outSz) { int length; diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 6866ac152..ad5918597 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -15335,8 +15335,8 @@ static int wc_PKCS7_DecodeSymmetricKeyPackage(const byte * skp, word32 skpSz, } else { /* sKeyPkgAttrs is present at &skp[skpIndex], length in length */ - return IndexSequenceOf(&skp[skpIndex], (word32)length, index, out, - outSz); + return wc_IndexSequenceOf(&skp[skpIndex], (word32)length, index, + out, outSz); } } @@ -15346,7 +15346,8 @@ static int wc_PKCS7_DecodeSymmetricKeyPackage(const byte * skp, word32 skpSz, } /* sKeys is present at &skp[skpIndex]. */ - return IndexSequenceOf(&skp[skpIndex], skpSz - skpIndex, index, out, outSz); + return wc_IndexSequenceOf(&skp[skpIndex], skpSz - skpIndex, index, + out, outSz); } int wc_PKCS7_DecodeSymmetricKeyPackageAttribute(const byte * skp, @@ -15384,7 +15385,7 @@ int wc_PKCS7_DecodeOneSymmetricKeyAttribute(const byte * osk, } /* Index the sKeyAttrs SEQUENCE OF object with the given index. */ - return IndexSequenceOf(&osk[oskIndex], oskSz - oskIndex, index, attr, + return wc_IndexSequenceOf(&osk[oskIndex], oskSz - oskIndex, index, attr, attrSz); } diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 79089227a..cb335e57a 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -2219,7 +2219,7 @@ WOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len, word32 maxIdx); WOLFSSL_LOCAL int GetSequence_ex(const byte* input, word32* inOutIdx, int* len, word32 maxIdx, int check); -WOLFSSL_TEST_VIS int IndexSequenceOf(byte const * seqOf, word32 seqOfSz, +WOLFSSL_TEST_VIS int wc_IndexSequenceOf(byte const * seqOf, word32 seqOfSz, size_t seqIndex, byte const ** out, word32 * outSz); WOLFSSL_LOCAL int GetOctetString(const byte* input, word32* inOutIdx, int* len, word32 maxIdx); From 7bcb346dd7d5052f9fdb2a1be2c85b9b5e346daf Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 22 Jul 2025 14:58:26 -0400 Subject: [PATCH 06/10] Remove early function returns per code review comments --- wolfcrypt/src/pkcs7.c | 73 +++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index ad5918597..5861656b0 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -15311,22 +15311,23 @@ static int wc_PKCS7_DecodeSymmetricKeyPackage(const byte * skp, word32 skpSz, word32 skpIndex = 0; int length = 0; int version = 0; + int ret = 0; if (skp == NULL || out == NULL || outSz == NULL) - return BAD_FUNC_ARG; + ret = BAD_FUNC_ARG; /* Expect a SEQUENCE header to start the SymmetricKeyPackage object. */ - if (GetSequence(skp, &skpIndex, &length, skpSz) < 0) - return ASN_PARSE_E; + if (ret == 0 && GetSequence(skp, &skpIndex, &length, skpSz) < 0) + ret = ASN_PARSE_E; /* Expect version v1 */ - if (GetMyVersion(skp, &skpIndex, &version, skpSz) < 0) - return ASN_PARSE_E; + if (ret == 0 && GetMyVersion(skp, &skpIndex, &version, skpSz) < 0) + ret = ASN_PARSE_E; - if (version != 1) - return ASN_PARSE_E; + if (ret == 0 && version != 1) + ret = ASN_PARSE_E; - if (GetASNHeader(skp, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED, + if (ret == 0 && GetASNHeader(skp, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED, &skpIndex, &length, skpSz) >= 0) { /* sKeyPkgAttrs [0] tag found so there are attributes present. */ if (getKey != 0) { @@ -15335,19 +15336,22 @@ static int wc_PKCS7_DecodeSymmetricKeyPackage(const byte * skp, word32 skpSz, } else { /* sKeyPkgAttrs is present at &skp[skpIndex], length in length */ - return wc_IndexSequenceOf(&skp[skpIndex], (word32)length, index, + ret = wc_IndexSequenceOf(&skp[skpIndex], (word32)length, index, out, outSz); } } - - if (getKey == 0) { + else if (ret == 0 && getKey == 0) { /* An attribute was requested, but none are present. */ - return BAD_INDEX_E; + ret = BAD_INDEX_E; } - /* sKeys is present at &skp[skpIndex]. */ - return wc_IndexSequenceOf(&skp[skpIndex], skpSz - skpIndex, index, - out, outSz); + if (ret == 0 && getKey != 0) { + /* sKeys is present at &skp[skpIndex]. */ + ret = wc_IndexSequenceOf(&skp[skpIndex], skpSz - skpIndex, index, + out, outSz); + } + + return ret; } int wc_PKCS7_DecodeSymmetricKeyPackageAttribute(const byte * skp, @@ -15369,24 +15373,28 @@ int wc_PKCS7_DecodeOneSymmetricKeyAttribute(const byte * osk, word32 oskIndex = 0; word32 tmpIndex; int length = 0; + int ret = 0; if (osk == NULL || attr == NULL || attrSz == NULL) - return BAD_FUNC_ARG; + ret = BAD_FUNC_ARG; /* Expect a SEQUENCE header to start the OneSymmetricKey object. */ - if (GetSequence(osk, &oskIndex, &length, oskSz) < 0) - return ASN_PARSE_E; + if (ret == 0 && GetSequence(osk, &oskIndex, &length, oskSz) < 0) + ret = ASN_PARSE_E; tmpIndex = oskIndex; - if (GetSequence(osk, &tmpIndex, &length, oskSz) < 0) { + if (ret == 0 && GetSequence(osk, &tmpIndex, &length, oskSz) < 0) { /* sKeyAttrs is not present. */ - return BAD_INDEX_E; + ret = BAD_INDEX_E; } /* Index the sKeyAttrs SEQUENCE OF object with the given index. */ - return wc_IndexSequenceOf(&osk[oskIndex], oskSz - oskIndex, index, attr, + if (ret == 0) + ret = wc_IndexSequenceOf(&osk[oskIndex], oskSz - oskIndex, index, attr, attrSz); + + return ret; } int wc_PKCS7_DecodeOneSymmetricKeyKey(const byte * osk, @@ -15394,25 +15402,30 @@ int wc_PKCS7_DecodeOneSymmetricKeyKey(const byte * osk, { word32 oskIndex = 0; int length = 0; + int ret = 0; if (osk == NULL || key == NULL || keySz == NULL) - return BAD_FUNC_ARG; + ret = BAD_FUNC_ARG; /* Expect a SEQUENCE header to start the OneSymmetricKey object. */ - if (GetSequence(osk, &oskIndex, &length, oskSz) < 0) - return ASN_PARSE_E; + if (ret == 0 && GetSequence(osk, &oskIndex, &length, oskSz) < 0) + ret = ASN_PARSE_E; - if (GetSequence(osk, &oskIndex, &length, oskSz) >= 0) { + if (ret == 0 && GetSequence(osk, &oskIndex, &length, oskSz) >= 0) { /* sKeyAttrs is present. Skip it. */ oskIndex += (word32)length; } - if (GetASNHeader(osk, ASN_OCTET_STRING, &oskIndex, &length, oskSz) < 0) - return ASN_PARSE_E; + if (ret == 0 && GetASNHeader(osk, ASN_OCTET_STRING, &oskIndex, &length, + oskSz) < 0) + ret = ASN_PARSE_E; - *key = &osk[oskIndex]; - *keySz = (word32)length; - return 0; + if (ret == 0) { + *key = &osk[oskIndex]; + *keySz = (word32)length; + } + + return ret; } #else /* HAVE_PKCS7 */ From 7762fa9b14e9ffc62c322380fdc77a850e2cb5b9 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 22 Jul 2025 20:09:55 -0400 Subject: [PATCH 07/10] Update style per code review comments --- tests/api.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/api.c b/tests/api.c index 5a5bef57a..1a4233ace 100644 --- a/tests/api.c +++ b/tests/api.c @@ -18468,12 +18468,12 @@ static int test_wc_PKCS7_DecodeSymmetricKeyPackage(void) { EXPECT_DECLS; #if defined(HAVE_PKCS7) - byte const * item; + const byte * item; word32 itemSz; int ret; { - static const byte one_key[] = { + const byte one_key[] = { 0x30, 0x08, 0x02, 0x01, 0x01, 0x30, 0x03, @@ -18519,7 +18519,7 @@ static int test_wc_PKCS7_DecodeSymmetricKeyPackage(void) /* Invalid SKP SEQUENCE header. */ { - static const byte bad_seq_header[] = { + const byte bad_seq_header[] = { 0x02, 0x01, 0x42, }; ret = wc_PKCS7_DecodeSymmetricKeyPackageKey( @@ -18529,7 +18529,7 @@ static int test_wc_PKCS7_DecodeSymmetricKeyPackage(void) /* Missing version object */ { - static const byte missing_version[] = { + const byte missing_version[] = { 0x30, 0x05, 0x30, 0x03, 0x02, 0x01, 0x01, @@ -18541,7 +18541,7 @@ static int test_wc_PKCS7_DecodeSymmetricKeyPackage(void) /* Invalid version number */ { - static const byte bad_version[] = { + const byte bad_version[] = { 0x30, 0x08, 0x02, 0x01, 0x00, 0x30, 0x03, @@ -18553,7 +18553,7 @@ static int test_wc_PKCS7_DecodeSymmetricKeyPackage(void) } { - static const byte key3_attr2[] = { + const byte key3_attr2[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0xA0, 0x08, @@ -18623,12 +18623,12 @@ static int test_wc_PKCS7_DecodeOneSymmetricKey(void) { EXPECT_DECLS; #if defined(HAVE_PKCS7) - byte const * item; + const byte * item; word32 itemSz; int ret; { - static const byte key1_attr2[] = { + const byte key1_attr2[] = { 0x30, 0x0E, 0x30, 0x06, 0x02, 0x01, 0x0A, @@ -18679,7 +18679,7 @@ static int test_wc_PKCS7_DecodeOneSymmetricKey(void) } { - static const byte no_attrs[] = { + const byte no_attrs[] = { 0x30, 0x06, 0x04, 0x04, 0xAA, 0xBB, 0xCC, 0xDD }; @@ -18698,7 +18698,7 @@ static int test_wc_PKCS7_DecodeOneSymmetricKey(void) } { - static const byte key0_attr2[] = { + const byte key0_attr2[] = { 0x30, 0x08, 0x30, 0x06, 0x02, 0x01, 0x0A, From 86d7d42eb60204f1f45a04bf5b6875ea727d6b03 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 22 Jul 2025 20:29:44 -0400 Subject: [PATCH 08/10] Comment test ASN DER sequences --- tests/api.c | 66 ++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/tests/api.c b/tests/api.c index 1a4233ace..430fb5aec 100644 --- a/tests/api.c +++ b/tests/api.c @@ -18474,10 +18474,10 @@ static int test_wc_PKCS7_DecodeSymmetricKeyPackage(void) { const byte one_key[] = { - 0x30, 0x08, - 0x02, 0x01, 0x01, - 0x30, 0x03, - 0x02, 0x01, 0x01, + 0x30, 0x08, /* SymmetricKeyPackage SEQUENCE header */ + 0x02, 0x01, 0x01, /* version v1 */ + 0x30, 0x03, /* sKeys SEQUENCE OF */ + 0x02, 0x01, 0x01, /* INTEGER standin for OneSymmetricKey */ }; /* NULL input data pointer */ ret = wc_PKCS7_DecodeSymmetricKeyPackageKey( @@ -18520,7 +18520,7 @@ static int test_wc_PKCS7_DecodeSymmetricKeyPackage(void) /* Invalid SKP SEQUENCE header. */ { const byte bad_seq_header[] = { - 0x02, 0x01, 0x42, + 0x02, 0x01, 0x42, /* Invalid SymmetricKeyPackage SEQUENCE header */ }; ret = wc_PKCS7_DecodeSymmetricKeyPackageKey( bad_seq_header, sizeof(bad_seq_header), 0, &item, &itemSz); @@ -18530,9 +18530,9 @@ static int test_wc_PKCS7_DecodeSymmetricKeyPackage(void) /* Missing version object */ { const byte missing_version[] = { - 0x30, 0x05, - 0x30, 0x03, - 0x02, 0x01, 0x01, + 0x30, 0x05, /* SymmetricKeyPackage SEQUENCE header */ + 0x30, 0x03, /* sKeys SEQUENCE OF */ + 0x02, 0x01, 0x01, /* INTEGER standin for OneSymmetricKey */ }; ret = wc_PKCS7_DecodeSymmetricKeyPackageKey( missing_version, sizeof(missing_version), 0, &item, &itemSz); @@ -18542,10 +18542,10 @@ static int test_wc_PKCS7_DecodeSymmetricKeyPackage(void) /* Invalid version number */ { const byte bad_version[] = { - 0x30, 0x08, - 0x02, 0x01, 0x00, - 0x30, 0x03, - 0x02, 0x01, 0x01, + 0x30, 0x08, /* SymmetricKeyPackage SEQUENCE header */ + 0x02, 0x01, 0x00, /* version 0 (invalid) */ + 0x30, 0x03, /* sKeys SEQUENCE OF */ + 0x02, 0x01, 0x01, /* INTEGER standin for OneSymmetricKey */ }; ret = wc_PKCS7_DecodeSymmetricKeyPackageKey( bad_version, sizeof(bad_version), 0, &item, &itemSz); @@ -18554,16 +18554,16 @@ static int test_wc_PKCS7_DecodeSymmetricKeyPackage(void) { const byte key3_attr2[] = { - 0x30, 0x18, - 0x02, 0x01, 0x01, - 0xA0, 0x08, - 0x30, 0x06, - 0x02, 0x01, 0x40, - 0x02, 0x01, 0x41, - 0x30, 0x09, - 0x02, 0x01, 0x0A, - 0x02, 0x01, 0x0B, - 0x02, 0x01, 0x0C, + 0x30, 0x18, /* SymmetricKeyPackage SEQUENCE header */ + 0x02, 0x01, 0x01, /* version v1 */ + 0xA0, 0x08, /* sKeyPkgAttrs EXPLICIT [0] header */ + 0x30, 0x06, /* sKeyPkgAttrs SEQUENCE OF header */ + 0x02, 0x01, 0x40, /* INTEGER standin for Attribute 0 */ + 0x02, 0x01, 0x41, /* INTEGER standin for Attribute 1 */ + 0x30, 0x09, /* sKeys SEQUENCE OF header */ + 0x02, 0x01, 0x0A, /* INTEGER standin for OneSymmetricKey 0 */ + 0x02, 0x01, 0x0B, /* INTEGER standin for OneSymmetricKey 1 */ + 0x02, 0x01, 0x0C, /* INTEGER standin for OneSymmetricKey 2 */ }; /* Valid attribute index 0 extraction */ @@ -18629,11 +18629,11 @@ static int test_wc_PKCS7_DecodeOneSymmetricKey(void) { const byte key1_attr2[] = { - 0x30, 0x0E, - 0x30, 0x06, - 0x02, 0x01, 0x0A, - 0x02, 0x01, 0x0B, - 0x04, 0x04, 0xAA, 0xBB, 0xCC, 0xDD + 0x30, 0x0E, /* OneSymmetricKey SEQUENCE header */ + 0x30, 0x06, /* sKeyAttrs SEQUENCE OF header */ + 0x02, 0x01, 0x0A, /* INTEGER standin for Attribute 0 */ + 0x02, 0x01, 0x0B, /* INTEGER standin for Attribute 1 */ + 0x04, 0x04, 0xAA, 0xBB, 0xCC, 0xDD /* sKey OCTET STRING */ }; /* NULL input data pointer */ @@ -18680,8 +18680,8 @@ static int test_wc_PKCS7_DecodeOneSymmetricKey(void) { const byte no_attrs[] = { - 0x30, 0x06, - 0x04, 0x04, 0xAA, 0xBB, 0xCC, 0xDD + 0x30, 0x06, /* OneSymmetricKey SEQUENCE header */ + 0x04, 0x04, 0xAA, 0xBB, 0xCC, 0xDD /* sKey OCTET STRING */ }; /* Attribute index 0 out of range */ @@ -18699,10 +18699,10 @@ static int test_wc_PKCS7_DecodeOneSymmetricKey(void) { const byte key0_attr2[] = { - 0x30, 0x08, - 0x30, 0x06, - 0x02, 0x01, 0x0A, - 0x02, 0x01, 0x0B, + 0x30, 0x08, /* OneSymmetricKey SEQUENCE header */ + 0x30, 0x06, /* sKeyAttrs SEQUENCE OF header */ + 0x02, 0x01, 0x0A, /* INTEGER standin for Attribute 0 */ + 0x02, 0x01, 0x0B, /* INTEGER standin for Attribute 1 */ }; /* Valid attribute 0 access */ From 0d48911ae4038156e1799f859e023a83a9b244bf Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 22 Jul 2025 20:30:44 -0400 Subject: [PATCH 09/10] Update style per code review comments --- wolfcrypt/src/asn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 000c8923a..a03c99a04 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -2586,8 +2586,8 @@ int GetSequence_ex(const byte* input, word32* inOutIdx, int* len, * @return BAD_INDEX_E when the given seqIndex is out of range. * @return ASN_PARSE_E when the seqOf is not in the expected format. */ -int wc_IndexSequenceOf(byte const * seqOf, word32 seqOfSz, size_t seqIndex, - byte const ** out, word32 * outSz) +int wc_IndexSequenceOf(const byte * seqOf, word32 seqOfSz, size_t seqIndex, + const byte ** out, word32 * outSz) { int length; word32 seqOfIdx = 0U; From 2f2f999657fd19f362c5eebe4f92e4e925152917 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 22 Jul 2025 20:35:28 -0400 Subject: [PATCH 10/10] Rework to remove early function returns --- wolfcrypt/src/asn.c | 48 ++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index a03c99a04..52bcd5153 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -2594,35 +2594,47 @@ int wc_IndexSequenceOf(const byte * seqOf, word32 seqOfSz, size_t seqIndex, byte tagFound; size_t i; word32 elementIdx = 0U; + int ret = 0; /* Validate the SEQUENCE OF header. */ - if (GetSequence(seqOf, &seqOfIdx, &length, seqOfSz) < 0) - return ASN_PARSE_E; + if (GetSequence(seqOf, &seqOfIdx, &length, seqOfSz) < 0) { + ret = ASN_PARSE_E; + } + else { + seqOfSz = seqOfIdx + (word32)length; - seqOfSz = seqOfIdx + (word32)length; + for (i = 0U; i <= seqIndex; i++) { + if (seqOfIdx >= seqOfSz) { + ret = BAD_INDEX_E; + break; + } - for (i = 0U; i <= seqIndex; i++) { - if (seqOfIdx >= seqOfSz) - return BAD_INDEX_E; + elementIdx = seqOfIdx; - elementIdx = seqOfIdx; + /* Validate the element tag. */ + if (GetASNTag(seqOf, &seqOfIdx, &tagFound, seqOfSz) != 0) { + ret = ASN_PARSE_E; + break; + } - /* Validate the element tag. */ - if (GetASNTag(seqOf, &seqOfIdx, &tagFound, seqOfSz) != 0) - return ASN_PARSE_E; + /* Validate and get the element's encoded length. */ + if (GetLength(seqOf, &seqOfIdx, &length, seqOfSz) < 0) { + ret = ASN_PARSE_E; + break; + } - /* Validate and get the element's encoded length. */ - if (GetLength(seqOf, &seqOfIdx, &length, seqOfSz) < 0) - return ASN_PARSE_E; - - seqOfIdx += (word32)length; + seqOfIdx += (word32)length; + } } /* If the tag and length checks above passed then we've found the requested * element and validated it fits within seqOfSz. */ - *out = &seqOf[elementIdx]; - *outSz = (seqOfIdx - elementIdx); - return 0; + if (ret == 0) { + *out = &seqOf[elementIdx]; + *outSz = (seqOfIdx - elementIdx); + } + + return ret; } /* Decode the header of a BER/DER encoded SET.