diff --git a/certs/include.am b/certs/include.am index 53bcb581c..c159b8e38 100644 --- a/certs/include.am +++ b/certs/include.am @@ -41,6 +41,7 @@ EXTRA_DIST += \ certs/server-revoked-key.pem \ certs/wolfssl-website-ca.pem \ certs/test-degenerate.p7b \ + certs/test-ber-exp02-05-2022.p7b \ certs/test-servercert.p12 \ certs/ecc-rsa-server.p12 \ certs/dsaparams.pem \ diff --git a/tests/api.c b/tests/api.c index 6d10feb04..98acf7456 100644 --- a/tests/api.c +++ b/tests/api.c @@ -16215,6 +16215,37 @@ static void test_wc_PKCS7_Degenerate(void) #endif } /* END test_wc_PKCS7_Degenerate() */ +/* + * Testing wc_PKCS7_BER() + */ +static void test_wc_PKCS7_BER(void) +{ +#if defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM) && \ + defined(ASN_BER_TO_DER) + PKCS7* pkcs7; + char fName[] = "./certs/test-ber-exp02-05-2022.p7b"; + XFILE f; + byte der[4096]; + word32 derSz; + int ret; + + printf(testingFmt, "wc_PKCS7_BER()"); + + AssertNotNull(f = XFOPEN(fName, "rb")); + AssertIntGT((ret = (int)fread(der, 1, sizeof(der), f)), 0); + derSz = (word32)ret; + XFCLOSE(f); + + AssertNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, devId)); + AssertIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0); + AssertIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0); + AssertIntEQ(wc_PKCS7_VerifySignedData(pkcs7, der, derSz), 0); + wc_PKCS7_Free(pkcs7); + + printf(resultFmt, passed); +#endif +} /* END test_wc_PKCS7_BER() */ + /* Testing wc_SignatureGetSize() for signature type ECC */ static int test_wc_SignatureGetSize_ecc(void) @@ -23587,6 +23618,7 @@ void ApiTest(void) test_wc_PKCS7_EncodeDecodeEnvelopedData(); test_wc_PKCS7_EncodeEncryptedData(); test_wc_PKCS7_Degenerate(); + test_wc_PKCS7_BER(); test_wolfSSL_CTX_LoadCRL(); diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 2daf2f5d0..ee14b38c2 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -265,6 +265,11 @@ static int wc_PKCS7_AddDataToStream(PKCS7* pkcs7, byte* in, word32 inSz, if (inSz - rdSz > 0 && pkcs7->stream->length < expected) { int len = min(inSz - rdSz, expected - pkcs7->stream->length); + /* sanity check that the input buffer is not internal buffer */ + if (in == pkcs7->stream->buffer) { + return WC_PKCS7_WANT_READ_E; + } + /* check if internal buffer size needs to be increased */ if (len + pkcs7->stream->length > pkcs7->stream->bufferSz) { int ret = wc_PKCS7_GrowStream(pkcs7, expected); @@ -3412,6 +3417,12 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, } idx = 0; +#ifdef ASN_BER_TO_DER + if (pkcs7->derSz > 0 && pkcs7->der) { + pkiMsg = in = pkcs7->der; + } +#endif + #ifndef NO_PKCS7_STREAM if (pkcs7->stream == NULL) { if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) { @@ -3463,8 +3474,8 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, if (ret < 0) return ret; - pkiMsg = pkcs7->der; - pkiMsgSz = len; + pkiMsg = in = pkcs7->der; + pkiMsgSz = pkcs7->derSz = len; idx = 0; if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz, NO_USER_CHECK) < 0) @@ -3546,7 +3557,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, case WC_PKCS7_VERIFY_STAGE2: #ifndef NO_PKCS7_STREAM - if ((ret = wc_PKCS7_AddDataToStream(pkcs7, pkiMsg, inSz + in2Sz, + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz, MAX_SEQ_SZ + MAX_OID_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) { break; @@ -3555,6 +3566,13 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, wc_PKCS7_StreamGetVar(pkcs7, &totalSz, 0, 0); if (pkcs7->stream->length > 0) pkiMsgSz = pkcs7->stream->length; + #ifdef ASN_BER_TO_DER + else if (pkcs7->der) + pkiMsgSz = pkcs7->derSz; + #endif + else + pkiMsgSz = inSz; + #endif /* Get the inner ContentInfo sequence */ if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz, @@ -3692,7 +3710,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, case WC_PKCS7_VERIFY_STAGE3: #ifndef NO_PKCS7_STREAM - if ((ret = wc_PKCS7_AddDataToStream(pkcs7, pkiMsg, inSz + in2Sz, + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz, pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { break; } @@ -3703,7 +3721,11 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, ret = (int)rc; break; } - if (pkcs7->stream->length > 0) + #ifdef ASN_BER_TO_DER + if (pkcs7->derSz != 0) + pkiMsgSz = pkcs7->derSz; + else + #endif pkiMsgSz = (word32)rc; wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, (int*)&localIdx, &length); @@ -3867,7 +3889,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, case WC_PKCS7_VERIFY_STAGE4: #ifndef NO_PKCS7_STREAM - if ((ret = wc_PKCS7_AddDataToStream(pkcs7, pkiMsg, inSz + in2Sz, + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz, pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { break; } @@ -4048,7 +4070,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, case WC_PKCS7_VERIFY_STAGE5: #ifndef NO_PKCS7_STREAM - if ((ret = wc_PKCS7_AddDataToStream(pkcs7, pkiMsg, inSz + in2Sz, + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz, pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { break; } @@ -4108,7 +4130,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, case WC_PKCS7_VERIFY_STAGE6: #ifndef NO_PKCS7_STREAM - if ((ret = wc_PKCS7_AddDataToStream(pkcs7, pkiMsg, inSz + in2Sz, + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz, pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { break; } diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 316116241..15461dc32 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -214,6 +214,7 @@ struct PKCS7 { void* heap; /* heap hint for dynamic memory */ #ifdef ASN_BER_TO_DER byte* der; /* DER encoded version of message */ + word32 derSz; #endif byte* cert[MAX_PKCS7_CERTS];