mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-08-12 18:01:29 +02:00
Addressed Skoll comments
one more
This commit is contained in:
+195
-40
@@ -6234,6 +6234,64 @@ int test_wc_PKCS7_VerifySignedData_IndefLenOOB(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if defined(HAVE_PKCS7) && !defined(NO_PKCS7_STREAM)
|
||||
/*
|
||||
* Feeds der to wc_PKCS7_VerifySignedData at every chunk size from
|
||||
* minChunkSz to derSz. If expectContentSz > 0, every chunk size must
|
||||
* decode successfully and produce that content size; otherwise every
|
||||
* chunk size must fail with a real parse error and never leave the
|
||||
* result at WC_PKCS7_WANT_READ_E once the whole buffer has been fed.
|
||||
*/
|
||||
static int test_wc_PKCS7_VerifySignedData_ChunkSweep_once(const byte* der,
|
||||
word32 derSz, word32 minChunkSz, word32 expectContentSz)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
PKCS7* pkcs7 = NULL;
|
||||
int ret;
|
||||
word32 chunkSz;
|
||||
word32 off;
|
||||
word32 thisSz;
|
||||
word32 fed;
|
||||
|
||||
for (chunkSz = minChunkSz; chunkSz <= derSz; chunkSz++) {
|
||||
ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
|
||||
ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);
|
||||
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
||||
|
||||
fed = 0;
|
||||
ret = WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E);
|
||||
for (off = 0; off < derSz && ret != 0; off += chunkSz) {
|
||||
thisSz = min(chunkSz, derSz - off);
|
||||
ret = wc_PKCS7_VerifySignedData(pkcs7, (byte*)der + off, thisSz);
|
||||
fed = off + thisSz;
|
||||
if (ret < 0 && ret != WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (expectContentSz > 0) {
|
||||
ExpectIntEQ(ret, 0);
|
||||
/* a genuine success must only happen once every byte of the
|
||||
* bundle has actually been fed in; an early success here
|
||||
* means the parser accepted a truncated prefix */
|
||||
ExpectIntEQ(fed, derSz);
|
||||
if (pkcs7 != NULL) {
|
||||
ExpectIntEQ(pkcs7->contentSz, expectContentSz);
|
||||
ExpectNotNull(pkcs7->content);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ExpectIntNE(ret, 0);
|
||||
ExpectIntNE(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
|
||||
}
|
||||
wc_PKCS7_Free(pkcs7);
|
||||
pkcs7 = NULL;
|
||||
}
|
||||
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
#endif /* HAVE_PKCS7 && !NO_PKCS7_STREAM */
|
||||
|
||||
/*
|
||||
* SignedData bundle truncated at the eContent [0] EXPLICIT tag in
|
||||
* encapContentInfo. Verifies that the parser rejects the malformed
|
||||
@@ -6278,6 +6336,11 @@ int test_wc_PKCS7_VerifySignedData_TruncEContentTag(void)
|
||||
ExpectIntNE(wc_PKCS7_VerifySignedData(pkcs7, der, derSz), 0);
|
||||
wc_PKCS7_Free(pkcs7);
|
||||
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
EXPECT_TEST(test_wc_PKCS7_VerifySignedData_ChunkSweep_once(der, derSz,
|
||||
1, 0));
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_PKCS7 */
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
@@ -6333,6 +6396,11 @@ int test_wc_PKCS7_VerifySignedData_TruncCertSetTag(void)
|
||||
ExpectIntNE(wc_PKCS7_VerifySignedData(pkcs7, der, derSz), 0);
|
||||
wc_PKCS7_Free(pkcs7);
|
||||
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
EXPECT_TEST(test_wc_PKCS7_VerifySignedData_ChunkSweep_once(der, derSz,
|
||||
1, 0));
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_PKCS7 */
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
@@ -6350,10 +6418,6 @@ int test_wc_PKCS7_VerifySignedData_DegenerateMinimal(void)
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_PKCS7)
|
||||
PKCS7* pkcs7 = NULL;
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
int ret;
|
||||
word32 idx;
|
||||
#endif
|
||||
|
||||
WOLFSSL_SMALL_STACK_STATIC byte der[] = {
|
||||
/* outer ContentInfo SEQUENCE (99 bytes content) */
|
||||
@@ -6402,24 +6466,92 @@ int test_wc_PKCS7_VerifySignedData_DegenerateMinimal(void)
|
||||
pkcs7 = NULL;
|
||||
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
/* same bundle fed one byte at a time */
|
||||
/* same bundle fed at every chunk size, including one byte at a time:
|
||||
* chunk boundaries that land mid-octet-string used to leave the
|
||||
* stream's totalRd tracking out of sync, capping stage 4's expected
|
||||
* read to less than the signerInfos SET tag/length needs and
|
||||
* stalling on WC_PKCS7_WANT_READ_E forever. */
|
||||
EXPECT_TEST(test_wc_PKCS7_VerifySignedData_ChunkSweep_once(der, derSz,
|
||||
1, 60));
|
||||
#endif /* !NO_PKCS7_STREAM */
|
||||
|
||||
#endif /* HAVE_PKCS7 */
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/*
|
||||
* Same shape as test_wc_PKCS7_VerifySignedData_DegenerateMinimal, but with
|
||||
* an empty certificates [0] SET and empty crls [1] SET both present ahead
|
||||
* of the empty signerInfos SET ("A0 00 A1 00 31 00" footer). Structurally
|
||||
* valid, and must verify the same way whether fed in one shot or in small
|
||||
* chunks that land the footer partway into the stream's internal buffer.
|
||||
*/
|
||||
int test_wc_PKCS7_VerifySignedData_DegenerateEmptyCertsCrls(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_PKCS7)
|
||||
PKCS7* pkcs7 = NULL;
|
||||
|
||||
WOLFSSL_SMALL_STACK_STATIC byte der[] = {
|
||||
/* outer ContentInfo SEQUENCE (103 bytes content) */
|
||||
0x30, 0x67,
|
||||
/* contentType OID signedData */
|
||||
0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02,
|
||||
/* [0] EXPLICIT (90 bytes content) */
|
||||
0xA0, 0x5A,
|
||||
/* SignedData SEQUENCE (88 bytes content) */
|
||||
0x30, 0x58,
|
||||
/* version INTEGER 1 */
|
||||
0x02, 0x01, 0x01,
|
||||
/* digestAlgorithms SET (empty - degenerate) */
|
||||
0x31, 0x00,
|
||||
/* encapContentInfo SEQUENCE (75 bytes content) */
|
||||
0x30, 0x4B,
|
||||
/* eContentType OID 1.2.840.113549.1.7.1 (data) */
|
||||
0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01,
|
||||
/* eContent [0] EXPLICIT (62 bytes content) */
|
||||
0xA0, 0x3E,
|
||||
/* OCTET STRING (60 bytes content) */
|
||||
0x04, 0x3C,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
||||
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x3A, 0x3B,
|
||||
/* certificates [0] (empty) */
|
||||
0xA0, 0x00,
|
||||
/* crls [1] (empty) */
|
||||
0xA1, 0x00,
|
||||
/* signerInfos SET (empty - degenerate end) */
|
||||
0x31, 0x00
|
||||
};
|
||||
word32 derSz = (word32)sizeof(der);
|
||||
|
||||
/* single-shot call */
|
||||
ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
|
||||
ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);
|
||||
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
||||
|
||||
ret = WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E);
|
||||
for (idx = 0; idx < derSz && ret != 0; idx++) {
|
||||
ret = wc_PKCS7_VerifySignedData(pkcs7, der + idx, 1);
|
||||
if (ret < 0 && ret != WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ExpectIntEQ(ret, 0);
|
||||
ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, der, derSz), 0);
|
||||
if (pkcs7 != NULL) {
|
||||
ExpectIntEQ(pkcs7->contentSz, 60);
|
||||
ExpectNotNull(pkcs7->content);
|
||||
}
|
||||
wc_PKCS7_Free(pkcs7);
|
||||
pkcs7 = NULL;
|
||||
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
/* same bundle fed at every chunk size: chunk boundaries that leave the
|
||||
* "A0 00 A1 00 31 00" footer partly in the stream's internal buffer
|
||||
* used to make stage 3 undercount the bytes still available (its cap
|
||||
* dropped the buffered-but-unparsed count instead of adding it in),
|
||||
* and separately left HandleOctetStrings' totalRd baseline stale
|
||||
* across a buffered-to-direct read transition, double-counting the
|
||||
* last content byte and starving stage 6 of the final length byte. */
|
||||
EXPECT_TEST(test_wc_PKCS7_VerifySignedData_ChunkSweep_once(der, derSz,
|
||||
1, 60));
|
||||
#endif /* !NO_PKCS7_STREAM */
|
||||
|
||||
#endif /* HAVE_PKCS7 */
|
||||
@@ -6437,6 +6569,7 @@ int test_wc_PKCS7_VerifySignedData_TruncSignerInfosTag(void)
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_PKCS7)
|
||||
PKCS7* pkcs7 = NULL;
|
||||
int ret;
|
||||
|
||||
WOLFSSL_SMALL_STACK_STATIC byte der[] = {
|
||||
0x30, 0x63,
|
||||
@@ -6465,11 +6598,16 @@ int test_wc_PKCS7_VerifySignedData_TruncSignerInfosTag(void)
|
||||
ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
|
||||
ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);
|
||||
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
||||
ExpectIntNE(wc_PKCS7_VerifySignedData(pkcs7, der, derSz), 0);
|
||||
ExpectIntNE(wc_PKCS7_VerifySignedData(pkcs7, der, derSz),
|
||||
WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
|
||||
ret = wc_PKCS7_VerifySignedData(pkcs7, der, derSz);
|
||||
ExpectIntNE(ret, 0);
|
||||
ExpectIntNE(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
|
||||
wc_PKCS7_Free(pkcs7);
|
||||
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
EXPECT_TEST(test_wc_PKCS7_VerifySignedData_ChunkSweep_once(der, derSz,
|
||||
1, 0));
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_PKCS7 */
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
@@ -6485,10 +6623,7 @@ int test_wc_PKCS7_VerifySignedData_NoSignerInfosTag(void)
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_PKCS7)
|
||||
PKCS7* pkcs7 = NULL;
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
int ret;
|
||||
word32 idx;
|
||||
#endif
|
||||
|
||||
WOLFSSL_SMALL_STACK_STATIC byte der[] = {
|
||||
0x30, 0x61,
|
||||
@@ -6518,29 +6653,18 @@ int test_wc_PKCS7_VerifySignedData_NoSignerInfosTag(void)
|
||||
ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
|
||||
ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);
|
||||
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
||||
ExpectIntNE(wc_PKCS7_VerifySignedData(pkcs7, der, derSz), 0);
|
||||
ExpectIntNE(wc_PKCS7_VerifySignedData(pkcs7, der, derSz),
|
||||
WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
|
||||
ret = wc_PKCS7_VerifySignedData(pkcs7, der, derSz);
|
||||
ExpectIntNE(ret, 0);
|
||||
ExpectIntNE(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
|
||||
wc_PKCS7_Free(pkcs7);
|
||||
pkcs7 = NULL;
|
||||
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
/* same bundle fed one byte at a time: must not end stuck on
|
||||
* WANT_READ_E once all available bytes are consumed */
|
||||
ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
|
||||
ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);
|
||||
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
||||
|
||||
ret = WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E);
|
||||
for (idx = 0; idx < derSz && ret != 0; idx++) {
|
||||
ret = wc_PKCS7_VerifySignedData(pkcs7, der + idx, 1);
|
||||
if (ret < 0 && ret != WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ExpectIntNE(ret, 0);
|
||||
ExpectIntNE(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E));
|
||||
wc_PKCS7_Free(pkcs7);
|
||||
/* same bundle fed at every chunk size, including one byte at a time:
|
||||
* must not end stuck on WANT_READ_E once all available bytes are
|
||||
* consumed */
|
||||
EXPECT_TEST(test_wc_PKCS7_VerifySignedData_ChunkSweep_once(der, derSz,
|
||||
1, 0));
|
||||
#endif /* !NO_PKCS7_STREAM */
|
||||
|
||||
#endif /* HAVE_PKCS7 */
|
||||
@@ -6605,13 +6729,44 @@ int test_wc_PKCS7_VerifySignedData_DegenerateNonEmptyDigestAlgos(void)
|
||||
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
||||
wc_PKCS7_AllowDegenerate(pkcs7, 0);
|
||||
ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, der, derSz),
|
||||
PKCS7_NO_SIGNER_E);
|
||||
WC_NO_ERR_TRACE(PKCS7_NO_SIGNER_E));
|
||||
wc_PKCS7_Free(pkcs7);
|
||||
|
||||
#endif /* HAVE_PKCS7 */
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/*
|
||||
* A genuine, non-degenerate SignedData bundle with a real RSA signerInfos
|
||||
* entry must still verify successfully when the caller has called
|
||||
* wc_PKCS7_AllowDegenerate(pkcs7, 0). The degenerate flag computed from
|
||||
* the signerInfos SET length is also used to reject degenerate bundles
|
||||
* under that setting, so this confirms a real signer does not get
|
||||
* misclassified as degenerate and rejected along with them.
|
||||
*/
|
||||
int test_wc_PKCS7_VerifySignedData_NoDegenerateAcceptsRealSigner(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM) && !defined(NO_RSA)
|
||||
PKCS7* pkcs7 = NULL;
|
||||
byte output[6000];
|
||||
word32 outputSz = sizeof(output);
|
||||
byte data[] = "Test data to encode.";
|
||||
|
||||
ExpectIntGT((outputSz = (word32)CreatePKCS7SignedData(output,
|
||||
(int)outputSz, data, (word32)sizeof(data), 0, 0, 0, RSA_TYPE)), 0);
|
||||
|
||||
ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
|
||||
ExpectIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);
|
||||
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
||||
wc_PKCS7_AllowDegenerate(pkcs7, 0);
|
||||
ExpectIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, outputSz), 0);
|
||||
wc_PKCS7_Free(pkcs7);
|
||||
|
||||
#endif /* HAVE_PKCS7 && !NO_FILESYSTEM && !NO_RSA */
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if defined(HAVE_PKCS7) && !defined(NO_RSA) && !defined(NO_SHA256) && \
|
||||
defined(USE_CERT_BUFFERS_2048)
|
||||
/*
|
||||
|
||||
@@ -79,9 +79,11 @@ int test_wc_PKCS7_VerifySignedData_IndefLenOOB(void);
|
||||
int test_wc_PKCS7_VerifySignedData_TruncEContentTag(void);
|
||||
int test_wc_PKCS7_VerifySignedData_TruncCertSetTag(void);
|
||||
int test_wc_PKCS7_VerifySignedData_DegenerateMinimal(void);
|
||||
int test_wc_PKCS7_VerifySignedData_DegenerateEmptyCertsCrls(void);
|
||||
int test_wc_PKCS7_VerifySignedData_TruncSignerInfosTag(void);
|
||||
int test_wc_PKCS7_VerifySignedData_NoSignerInfosTag(void);
|
||||
int test_wc_PKCS7_VerifySignedData_DegenerateNonEmptyDigestAlgos(void);
|
||||
int test_wc_PKCS7_VerifySignedData_NoDegenerateAcceptsRealSigner(void);
|
||||
int test_wc_PKCS7_VerifySignedData_NoDigestParams(void);
|
||||
|
||||
|
||||
@@ -138,9 +140,11 @@ int test_wc_PKCS7_VerifySignedData_NoDigestParams(void);
|
||||
TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_VerifySignedData_TruncEContentTag), \
|
||||
TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_VerifySignedData_TruncCertSetTag), \
|
||||
TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_VerifySignedData_DegenerateMinimal), \
|
||||
TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_VerifySignedData_DegenerateEmptyCertsCrls), \
|
||||
TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_VerifySignedData_TruncSignerInfosTag), \
|
||||
TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_VerifySignedData_NoSignerInfosTag), \
|
||||
TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_VerifySignedData_DegenerateNonEmptyDigestAlgos), \
|
||||
TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_VerifySignedData_NoDegenerateAcceptsRealSigner), \
|
||||
TEST_DECL_GROUP("pkcs7_sd", test_wc_PKCS7_VerifySignedData_NoDigestParams)
|
||||
|
||||
#define TEST_PKCS7_ENCRYPTED_DATA_DECLS \
|
||||
|
||||
+61
-27
@@ -6662,6 +6662,13 @@ static int wc_PKCS7_HandleOctetStrings(wc_PKCS7* pkcs7, byte* in, word32 inSz,
|
||||
pkcs7->stream->expected, &msg, idx)) != 0) {
|
||||
break;
|
||||
}
|
||||
/* re-sync totalRd baseline to the fresh idx. Without this, a byte
|
||||
* that wc_PKCS7_AddDataToStream() already charged to totalRd while
|
||||
* buffering (growing stream->length) gets charged again below when
|
||||
* this loop switches to reading directly from "in" starting at
|
||||
* that same position, since *tmpIdx would still hold a position
|
||||
* from before the buffered run started. */
|
||||
*tmpIdx = *idx;
|
||||
|
||||
msgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length:inSz;
|
||||
|
||||
@@ -7517,21 +7524,26 @@ static int PKCS7_VerifySignedData(wc_PKCS7* pkcs7, const byte* hashBuf,
|
||||
* malformed fails there with a real parse error.
|
||||
*/
|
||||
pkcs7->stream->expected = (ASN_TAG_SZ + MAX_LENGTH_SZ) * 2;
|
||||
if (!pkcs7->stream->indefLen &&
|
||||
pkcs7->stream->totalRd >= pkcs7->stream->maxLen) {
|
||||
/* definite-length bundle with no bytes left per the outer
|
||||
* length: force stage 4's bounds check to fail now instead
|
||||
* of requesting bytes that will never arrive. For
|
||||
* indefinite-length (BER) bundles maxLen is only a running
|
||||
* estimate, so totalRd catching up to it does not mean the
|
||||
* bundle is actually exhausted. */
|
||||
pkcs7->stream->expected = 0;
|
||||
}
|
||||
else if (pkcs7->stream->totalRd < pkcs7->stream->maxLen &&
|
||||
pkcs7->stream->expected >
|
||||
pkcs7->stream->maxLen - pkcs7->stream->totalRd) {
|
||||
pkcs7->stream->expected =
|
||||
pkcs7->stream->maxLen - pkcs7->stream->totalRd;
|
||||
if (!pkcs7->stream->indefLen) {
|
||||
/* cap to what can actually still show up: bytes already
|
||||
* buffered (stream->length) plus whatever the outer
|
||||
* length still allows past totalRd. Matches the same
|
||||
* (maxLen - totalRd) + length expression used at every
|
||||
* other stage in this function. For indefinite-length
|
||||
* (BER) bundles maxLen is only a running estimate, so
|
||||
* this cap does not apply. */
|
||||
if (pkcs7->stream->totalRd >= pkcs7->stream->maxLen) {
|
||||
if (pkcs7->stream->expected > pkcs7->stream->length) {
|
||||
pkcs7->stream->expected = pkcs7->stream->length;
|
||||
}
|
||||
}
|
||||
else if (pkcs7->stream->expected >
|
||||
(pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
|
||||
pkcs7->stream->length) {
|
||||
pkcs7->stream->expected =
|
||||
(pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
|
||||
pkcs7->stream->length;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -7673,6 +7685,11 @@ static int PKCS7_VerifySignedData(wc_PKCS7* pkcs7, const byte* hashBuf,
|
||||
}
|
||||
|
||||
maxIdx = idx + pkcs7->stream->expected;
|
||||
|
||||
/* re-sync totalRd baseline to the fresh idx, same as STAGE6
|
||||
* does; otherwise it can still hold a stale position left
|
||||
* over from stage 3's internal stream buffer. */
|
||||
stateIdx = idx;
|
||||
#endif /* !NO_PKCS7_STREAM */
|
||||
|
||||
if (pkiMsg2 == NULL || pkiMsg2Sz == 0) {
|
||||
@@ -7782,6 +7799,11 @@ static int PKCS7_VerifySignedData(wc_PKCS7* pkcs7, const byte* hashBuf,
|
||||
pkiMsg2Sz = (pkcs7->stream->length > 0)? pkcs7->stream->length:
|
||||
srcSz;
|
||||
|
||||
/* re-sync totalRd baseline to the fresh idx, same as STAGE4
|
||||
* and STAGE6 do; otherwise it can still hold a stale position
|
||||
* left over from STAGE4's internal stream buffer. */
|
||||
stateIdx = idx;
|
||||
|
||||
wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
|
||||
|
||||
/* restore content */
|
||||
@@ -8086,6 +8108,30 @@ static int PKCS7_VerifySignedData(wc_PKCS7* pkcs7, const byte* hashBuf,
|
||||
NO_USER_CHECK) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
/* claimed signerInfos content must fit in what can still
|
||||
* arrive, or stage 7 stalls on WANT_READ_E forever */
|
||||
if (ret == 0 && !pkcs7->stream->indefLen) {
|
||||
word32 avail;
|
||||
if (pkcs7->stream->length > 0) {
|
||||
avail = pkcs7->stream->length - idx;
|
||||
if (pkcs7->stream->totalRd < pkcs7->stream->maxLen) {
|
||||
avail += pkcs7->stream->maxLen -
|
||||
pkcs7->stream->totalRd;
|
||||
}
|
||||
}
|
||||
else {
|
||||
word32 used = pkcs7->stream->totalRd +
|
||||
(idx - stateIdx);
|
||||
avail = (used < pkcs7->stream->maxLen) ?
|
||||
pkcs7->stream->maxLen - used : 0;
|
||||
}
|
||||
if ((word32)length > avail) {
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Update degenerate flag based on if signerInfos SET is empty.
|
||||
* The earlier degenerate check at digestAlgorithms is an early
|
||||
* optimization, but depending on degenerate case may not be
|
||||
@@ -8129,18 +8175,6 @@ static int PKCS7_VerifySignedData(wc_PKCS7* pkcs7, const byte* hashBuf,
|
||||
}
|
||||
else {
|
||||
pkcs7->stream->expected = (word32)length;
|
||||
if (pkcs7->stream->totalRd >= pkcs7->stream->maxLen) {
|
||||
/* definite-length bundle with no bytes left per the
|
||||
* outer length: force stage 7's bounds check to fail
|
||||
* now instead of requesting bytes that will never
|
||||
* arrive. Do NOT cap expected down further than that
|
||||
* when bytes may still remain -- expected here is the
|
||||
* full signerInfo content size that stage 7 needs
|
||||
* buffered at once, not just header lookahead, so
|
||||
* shrinking it while genuinely more data is still due
|
||||
* from a future call would corrupt the parse window. */
|
||||
pkcs7->stream->expected = 0;
|
||||
}
|
||||
}
|
||||
|
||||
wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE7);
|
||||
|
||||
Reference in New Issue
Block a user