From 6987304f4267d1e1d2a269dbb877a8f225eb8012 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Tue, 15 Apr 2025 14:35:39 -0600 Subject: [PATCH 1/7] Fix to advance past multiple recipients --- wolfcrypt/src/pkcs7.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 686d06856..faf2bd4f3 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -106,6 +106,7 @@ struct PKCS7State { word32 currContSz; /* size of current content */ word32 currContRmnSz; /* remaining size of current content */ word32 accumContSz; /* size of accumulated content size */ + int recipientSz; /* size of recipient set */ byte tmpIv[MAX_CONTENT_IV_SIZE]; /* store IV if needed */ #ifdef WC_PKCS7_STREAM_DEBUG word32 peakUsed; /* most bytes used for struct at any one time */ @@ -12460,14 +12461,16 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, #ifndef NO_PKCS7_STREAM tmpIdx = idx; pkcs7->stream->aad = decryptedKey; + pkcs7->stream->expected = (word32)ret; /* get the full recipient set */ + pkcs7->stream->recipientSz = ret; #endif FALL_THROUGH; case WC_PKCS7_ENV_2: #ifndef NO_PKCS7_STREAM /* store up enough buffer for initial info set decode */ - if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ + - MAX_VERSION_SZ + ASN_TAG_SZ, &pkiMsg, &idx)) != 0) { + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, + pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { return ret; } #endif @@ -12483,6 +12486,7 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, #ifndef NO_PKCS7_STREAM decryptedKey = pkcs7->stream->aad; decryptedKeySz = MAX_ENCRYPTED_KEY_SZ; + tmpIdx = idx; #endif ret = wc_PKCS7_DecryptRecipientInfos(pkcs7, in, inSz, &idx, @@ -12497,6 +12501,14 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, if (ret != 0) break; #ifndef NO_PKCS7_STREAM + /* advance idx past recipient info set */ + idx = tmpIdx + (word32)pkcs7->stream->recipientSz; + + /* process aditional recipients as read */ + if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) { + break; + } + tmpIdx = idx; pkcs7->stream->aadSz = decryptedKeySz; pkcs7->stream->expected = MAX_LENGTH_SZ + MAX_VERSION_SZ + From 7a5e97e30e44be80cfd1244c9279c8364e38f8ce Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Wed, 16 Apr 2025 11:39:45 -0600 Subject: [PATCH 2/7] adjustment for recipient index advancement --- wolfcrypt/src/pkcs7.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index faf2bd4f3..3c31d1136 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -12316,9 +12316,17 @@ static int wc_PKCS7_ParseToRecipientInfoSet(wc_PKCS7* pkcs7, byte* in, #ifndef NO_PKCS7_STREAM pkcs7->stream->expected = (word32)length; + if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) { break; } + + /* update the stored max length */ + if (pkcs7->stream->totalRd + pkcs7->stream->expected > + pkcs7->stream->maxLen) { + pkcs7->stream->maxLen = pkcs7->stream->totalRd + + pkcs7->stream->expected; + } #endif if (ret == 0) @@ -12461,7 +12469,8 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, #ifndef NO_PKCS7_STREAM tmpIdx = idx; pkcs7->stream->aad = decryptedKey; - pkcs7->stream->expected = (word32)ret; /* get the full recipient set */ + /* get the full recipient set */ + pkcs7->stream->expected = (word32)ret; pkcs7->stream->recipientSz = ret; #endif FALL_THROUGH; @@ -12488,6 +12497,7 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, decryptedKeySz = MAX_ENCRYPTED_KEY_SZ; tmpIdx = idx; #endif + pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz; ret = wc_PKCS7_DecryptRecipientInfos(pkcs7, in, inSz, &idx, decryptedKey, &decryptedKeySz, @@ -12501,12 +12511,16 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, if (ret != 0) break; #ifndef NO_PKCS7_STREAM - /* advance idx past recipient info set */ - idx = tmpIdx + (word32)pkcs7->stream->recipientSz; + /* advance idx past recipient info set if not all recipients + * parsed */ + if (pkcs7->stream->totalRd < (pkcs7->stream->recipientSz + + tmpIdx)) { + idx = tmpIdx + (word32)pkcs7->stream->recipientSz; - /* process aditional recipients as read */ - if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) { - break; + /* process additional recipients as read */ + if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) { + break; + } } tmpIdx = idx; From 328f50570283b011f34908b0caae945e9aab9fa7 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Mon, 29 Sep 2025 17:58:15 -0600 Subject: [PATCH 3/7] add pkcs7 test with multiple recipients --- certs/include.am | 1 + certs/renewcerts.sh | 5 ++ certs/test-multiple-recipients.p7b | Bin 0 -> 6443 bytes tests/api/test_pkcs7.c | 77 +++++++++++++++++++++++++++++ tests/api/test_pkcs7.h | 4 +- wolfcrypt/src/pkcs7.c | 16 +++--- 6 files changed, 96 insertions(+), 7 deletions(-) create mode 100644 certs/test-multiple-recipients.p7b diff --git a/certs/include.am b/certs/include.am index e4f6a0e6c..68fcd1e2e 100644 --- a/certs/include.am +++ b/certs/include.am @@ -53,6 +53,7 @@ EXTRA_DIST += \ certs/server-revoked-key.pem \ certs/wolfssl-website-ca.pem \ certs/test-degenerate.p7b \ + certs/test-multiple-recipients.p7b \ certs/test-stream-sign.p7b \ certs/test-stream-dec.p7b \ certs/test-ber-exp02-05-2022.p7b \ diff --git a/certs/renewcerts.sh b/certs/renewcerts.sh index 609726cc1..5aed64881 100755 --- a/certs/renewcerts.sh +++ b/certs/renewcerts.sh @@ -888,6 +888,11 @@ run_renewcerts(){ openssl cms -encrypt -in ca-cert.pem -recip client-cert.pem -out test-stream-dec.p7b -outform DER -stream check_result $? "" + echo "Creating test-multiple-recipients.p7b..." + echo "" + openssl smime -encrypt -binary -aes-256-cbc -in ./client-key.pem -out ./test-multiple-recipients.p7b -outform DER ./client-cert.pem ./server-cert.pem + check_result $? "" + echo "End of section" echo "---------------------------------------------------------------------" diff --git a/certs/test-multiple-recipients.p7b b/certs/test-multiple-recipients.p7b new file mode 100644 index 0000000000000000000000000000000000000000..34915f216a1c35ac1046b685898c4be4496dab5a GIT binary patch literal 6443 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 literal 0 HcmV?d00001 diff --git a/tests/api/test_pkcs7.c b/tests/api/test_pkcs7.c index aeb4f630c..332bc3b03 100644 --- a/tests/api/test_pkcs7.c +++ b/tests/api/test_pkcs7.c @@ -2145,6 +2145,83 @@ int test_wc_PKCS7_DecodeEnvelopedData_stream(void) #endif } /* END test_wc_PKCS7_DecodeEnvelopedData_stream() */ + +/* + * Testing wc_PKCS7_DecodeEnvelopedData with streaming + */ +int test_wc_PKCS7_DecodeEnvelopedData_multiple_recipients(void) +{ +#if defined(HAVE_PKCS7) + EXPECT_DECLS; + PKCS7* pkcs7 = NULL; + int ret = 0; + XFILE f = XBADFILE; + const char* testFile = "./certs/test-multiple-recipients.p7b"; + byte testDerBuffer[8192]; /* test-multiple-recipients is currently 6433 + bytes */ + size_t testDerBufferSz = 0; + byte decodedData[8192]; + + ExpectTrue((f = XFOPEN(testFile, "rb")) != XBADFILE); + testDerBufferSz = XFREAD(testDerBuffer, 1, + sizeof(testDerBuffer), f); + ExpectIntNE(testDerBufferSz, 0); + if (f != XBADFILE) { + XFCLOSE(f); + f = XBADFILE; + } + + /* test with server cert recipient */ + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); + if (pkcs7) { + ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (byte*)server_cert_der_2048, + sizeof_server_cert_der_2048), 0); + + ExpectIntEQ(wc_PKCS7_SetKey(pkcs7, (byte*)server_key_der_2048, + sizeof_server_key_der_2048), 0); + + ret = wc_PKCS7_DecodeEnvelopedData(pkcs7, testDerBuffer, + (word32)testDerBufferSz, decodedData, sizeof(decodedData)); + ExpectIntGT(ret, 0); + wc_PKCS7_Free(pkcs7); + } + + /* test with client cert recipient */ + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); + if (pkcs7) { + ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (byte*)client_cert_der_2048, + sizeof_client_cert_der_2048), 0); + + ExpectIntEQ(wc_PKCS7_SetKey(pkcs7, (byte*)client_key_der_2048, + sizeof_client_key_der_2048), 0); + + ret = wc_PKCS7_DecodeEnvelopedData(pkcs7, testDerBuffer, + (word32)testDerBufferSz, decodedData, sizeof(decodedData)); + ExpectIntGT(ret, 0); + wc_PKCS7_Free(pkcs7); + } + + /* test with ca cert recipient (which should fail) */ + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); + if (pkcs7) { + ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (byte*)ca_cert_der_2048, + sizeof_ca_cert_der_2048), 0); + + ExpectIntEQ(wc_PKCS7_SetKey(pkcs7, (byte*)ca_key_der_2048, + sizeof_ca_key_der_2048), 0); + + ret = wc_PKCS7_DecodeEnvelopedData(pkcs7, testDerBuffer, + (word32)testDerBufferSz, decodedData, sizeof(decodedData)); + ExpectIntLT(ret, 0); + wc_PKCS7_Free(pkcs7); + } + + return EXPECT_RESULT(); +#else + return TEST_SKIPPED; +#endif +} /* END test_wc_PKCS7_DecodeEnvelopedData_multiple_recipients() */ + /* * Testing wc_PKCS7_EncodeEnvelopedData(), wc_PKCS7_DecodeEnvelopedData() */ diff --git a/tests/api/test_pkcs7.h b/tests/api/test_pkcs7.h index b07825e92..054eda248 100644 --- a/tests/api/test_pkcs7.h +++ b/tests/api/test_pkcs7.h @@ -47,6 +47,7 @@ int test_wc_PKCS7_NoDefaultSignedAttribs(void); int test_wc_PKCS7_SetOriEncryptCtx(void); int test_wc_PKCS7_SetOriDecryptCtx(void); int test_wc_PKCS7_DecodeCompressedData(void); +int test_wc_PKCS7_DecodeEnvelopedData_multiple_recipients(void); #define TEST_PKCS7_DECLS \ @@ -74,7 +75,8 @@ int test_wc_PKCS7_DecodeCompressedData(void); TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_DecodeSymmetricKeyPackage), \ TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_DecodeOneSymmetricKey), \ TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_SetOriEncryptCtx), \ - TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_SetOriDecryptCtx) + TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_SetOriDecryptCtx), \ + TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_DecodeEnvelopedData_multiple_recipients) #define TEST_PKCS7_SIGNED_ENCRYPTED_DATA_DECLS \ TEST_DECL_GROUP("pkcs7_sed", test_wc_PKCS7_signed_enveloped) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 3c31d1136..25ed7295f 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -11974,8 +11974,14 @@ static int wc_PKCS7_DecryptRecipientInfos(wc_PKCS7* pkcs7, byte* in, ret = wc_PKCS7_DecryptKtri(pkcs7, in, inSz, idx, decryptedKey, decryptedKeySz, recipFound); - if (ret != 0) - return ret; + if (ret != 0) { + if (ret != WC_PKCS7_WANT_READ_E && *recipFound == 0) { + continue; /* try next recipient */ + } + else { + return ret; /* found recipient and failed decrypt */ + } + } #else return NOT_COMPILED_IN; #endif @@ -12096,8 +12102,8 @@ static int wc_PKCS7_DecryptRecipientInfos(wc_PKCS7* pkcs7, byte* in, recipFound); if (ret != 0) return ret; - - } else { + } + else { /* failed to find RecipientInfo, restore idx and continue */ *idx = savedIdx; break; @@ -12497,8 +12503,6 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, decryptedKeySz = MAX_ENCRYPTED_KEY_SZ; tmpIdx = idx; #endif - pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz; - ret = wc_PKCS7_DecryptRecipientInfos(pkcs7, in, inSz, &idx, decryptedKey, &decryptedKeySz, &recipFound); From 12cfca4060b52ce0f3cd49f1a0213102c6f30c7c Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Tue, 30 Sep 2025 09:48:16 -0600 Subject: [PATCH 4/7] account for no AES build and add err trace macro --- tests/api/test_pkcs7.c | 8 ++++++++ wolfcrypt/src/pkcs7.c | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/api/test_pkcs7.c b/tests/api/test_pkcs7.c index 332bc3b03..ec4f7f333 100644 --- a/tests/api/test_pkcs7.c +++ b/tests/api/test_pkcs7.c @@ -2182,7 +2182,11 @@ int test_wc_PKCS7_DecodeEnvelopedData_multiple_recipients(void) ret = wc_PKCS7_DecodeEnvelopedData(pkcs7, testDerBuffer, (word32)testDerBufferSz, decodedData, sizeof(decodedData)); + #if defined(NO_AES) || defined(NO_AES_256) + ExpectIntEQ(ret, ALGO_ID_E); + #else ExpectIntGT(ret, 0); + #endif wc_PKCS7_Free(pkcs7); } @@ -2197,7 +2201,11 @@ int test_wc_PKCS7_DecodeEnvelopedData_multiple_recipients(void) ret = wc_PKCS7_DecodeEnvelopedData(pkcs7, testDerBuffer, (word32)testDerBufferSz, decodedData, sizeof(decodedData)); + #if defined(NO_AES) || defined(NO_AES_256) + ExpectIntEQ(ret, ALGO_ID_E); + #else ExpectIntGT(ret, 0); + #endif wc_PKCS7_Free(pkcs7); } diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 25ed7295f..cce0c6b08 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -11975,7 +11975,8 @@ static int wc_PKCS7_DecryptRecipientInfos(wc_PKCS7* pkcs7, byte* in, decryptedKey, decryptedKeySz, recipFound); if (ret != 0) { - if (ret != WC_PKCS7_WANT_READ_E && *recipFound == 0) { + if (ret != WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E) && + *recipFound == 0) { continue; /* try next recipient */ } else { From 4e92920a7f5f9511db0b06e0a1e6c41e672a8530 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Tue, 30 Sep 2025 10:00:12 -0600 Subject: [PATCH 5/7] cast variable to word32 for compare --- wolfcrypt/src/pkcs7.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index cce0c6b08..b8ceb3ce9 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -12518,7 +12518,7 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, #ifndef NO_PKCS7_STREAM /* advance idx past recipient info set if not all recipients * parsed */ - if (pkcs7->stream->totalRd < (pkcs7->stream->recipientSz + + if (pkcs7->stream->totalRd < ((word32)pkcs7->stream->recipientSz + tmpIdx)) { idx = tmpIdx + (word32)pkcs7->stream->recipientSz; From fca302839501cd793ebd0b4252827bcb62af3486 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Fri, 3 Oct 2025 15:52:30 -0600 Subject: [PATCH 6/7] advance index past recipent set in non stream case too --- wolfcrypt/src/pkcs7.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index b8ceb3ce9..2ca132181 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -12412,9 +12412,8 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, int recipFound = 0; int ret, length = 0; word32 idx = 0; -#ifndef NO_PKCS7_STREAM word32 tmpIdx = 0; -#endif + word32 recipientSetSz = 0; word32 contentType = 0, encOID = 0; word32 decryptedKeySz = MAX_ENCRYPTED_KEY_SZ; @@ -12473,11 +12472,12 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, if (decryptedKey == NULL) return MEMORY_E; wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_2); - #ifndef NO_PKCS7_STREAM tmpIdx = idx; + recipientSetSz = (word32)ret; + #ifndef NO_PKCS7_STREAM pkcs7->stream->aad = decryptedKey; /* get the full recipient set */ - pkcs7->stream->expected = (word32)ret; + pkcs7->stream->expected = recipientSetSz; pkcs7->stream->recipientSz = ret; #endif FALL_THROUGH; @@ -12532,6 +12532,8 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, pkcs7->stream->aadSz = decryptedKeySz; pkcs7->stream->expected = MAX_LENGTH_SZ + MAX_VERSION_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ; + #else + idx = tmpIdx + recipientSetSz; #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_3); FALL_THROUGH; From 7128932eff9d26a921848c6e65fcd380feeb727d Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Mon, 6 Oct 2025 10:48:59 -0600 Subject: [PATCH 7/7] avoid attempt of key decode and free buffer if incorrect recipient found --- wolfcrypt/src/pkcs7.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 2ca132181..3ba2e8bfd 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -10488,6 +10488,14 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, XMEMCPY(encryptedKey, &pkiMsg[*idx], (word32)encryptedKeySz); *idx += (word32)encryptedKeySz; + /* If this is not the correct recipient then do not try to decode + * the encrypted key */ + if (*recipFound == 0) { + XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT); + ret = PKCS7_RECIP_E; + break; + } + /* load private key */ #ifdef WOLFSSL_SMALL_STACK privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,