Skip to content

Commit 6721bde

Browse files
committed
Add bounds check in PKCS7 streaming indefinite-length end-of-content parsing
1 parent 0f41e99 commit 6721bde

4 files changed

Lines changed: 51 additions & 1 deletion

File tree

1.82 KB
Binary file not shown.

tests/api/test_pkcs7.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4856,3 +4856,47 @@ int test_wc_PKCS7_VerifySignedData_PKCS7ContentSeq(void)
48564856
return EXPECT_RESULT();
48574857
}
48584858

4859+
/*
4860+
* Test PKCS7 VerifySignedData with indefinite-length BER-encoded SignedData
4861+
* containing mismatched nesting depth. Verifies bounds checking in the
4862+
* end-of-content octet verification loop in streaming mode.
4863+
*/
4864+
int test_wc_PKCS7_VerifySignedData_IndefLenOOB(void)
4865+
{
4866+
EXPECT_DECLS;
4867+
#if defined(HAVE_PKCS7) && !defined(NO_PKCS7_STREAM) && !defined(NO_FILESYSTEM)
4868+
PKCS7* pkcs7 = NULL;
4869+
char fName[] = "./certs/pkcs7-indef-len-signed-data.bin";
4870+
XFILE f = XBADFILE;
4871+
byte* der = NULL;
4872+
word32 derSz = 0;
4873+
4874+
/* PKCS#7 SignedData with indefinite-length BER encoding where the
4875+
* nesting depth exceeds the available end-of-content octets. */
4876+
ExpectTrue((f = XFOPEN(fName, "rb")) != XBADFILE);
4877+
if (f != XBADFILE) {
4878+
ExpectIntEQ(XFSEEK(f, 0, XSEEK_END), 0);
4879+
ExpectIntGT(derSz = (word32)XFTELL(f), 0);;
4880+
ExpectIntEQ(XFSEEK(f, 0, XSEEK_SET), 0);
4881+
ExpectNotNull(der = (byte*)XMALLOC(derSz, HEAP_HINT,
4882+
DYNAMIC_TYPE_TMP_BUFFER));
4883+
if (der != NULL) {
4884+
ExpectTrue(XFREAD(der, 1, derSz, f) == derSz);
4885+
}
4886+
XFCLOSE(f);
4887+
}
4888+
4889+
if (der != NULL) {
4890+
/* Should return a parse error for malformed input */
4891+
ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
4892+
ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);
4893+
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
4894+
ExpectIntNE(wc_PKCS7_VerifySignedData(pkcs7, der, derSz), 0);
4895+
wc_PKCS7_Free(pkcs7);
4896+
}
4897+
4898+
XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
4899+
4900+
#endif /* HAVE_PKCS7 && !NO_PKCS7_STREAM && !NO_FILESYSTEM */
4901+
return EXPECT_RESULT();
4902+
}

tests/api/test_pkcs7.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ int test_wc_PKCS7_SetOriDecryptCtx(void);
5858
int test_wc_PKCS7_DecodeCompressedData(void);
5959
int test_wc_PKCS7_DecodeEnvelopedData_multiple_recipients(void);
6060
int test_wc_PKCS7_VerifySignedData_PKCS7ContentSeq(void);
61+
int test_wc_PKCS7_VerifySignedData_IndefLenOOB(void);
6162

6263

6364
#define TEST_PKCS7_DECLS \
@@ -92,7 +93,8 @@ int test_wc_PKCS7_VerifySignedData_PKCS7ContentSeq(void);
9293
TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_Degenerate), \
9394
TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_BER), \
9495
TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_NoDefaultSignedAttribs), \
95-
TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_VerifySignedData_PKCS7ContentSeq)
96+
TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_VerifySignedData_PKCS7ContentSeq), \
97+
TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_VerifySignedData_IndefLenOOB)
9698

9799
#define TEST_PKCS7_ENCRYPTED_DATA_DECLS \
98100
TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_DecodeEnvelopedData_stream), \

wolfcrypt/src/pkcs7.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6897,6 +6897,10 @@ static int PKCS7_VerifySignedData(wc_PKCS7* pkcs7, const byte* hashBuf,
68976897
word32 sz = (word32)pkcs7->stream->cntIdfCnt * ASN_INDEF_END_SZ;
68986898
localIdx = idx;
68996899
for (i = 0; i < sz; i++) {
6900+
if (localIdx + i >= pkiMsg2Sz) {
6901+
ret = ASN_PARSE_E;
6902+
break;
6903+
}
69006904
if (pkiMsg2[localIdx + i] == 0)
69016905
continue;
69026906
else {

0 commit comments

Comments
 (0)