From 06d86af67cfde1f6ce164126f8faac100f63b2e3 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sat, 19 Jul 2025 16:59:15 -0400 Subject: [PATCH] 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 */ -