mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-01-26 20:42:20 +01:00
Merge pull request #8674 from JacobBarthelmeh/pkcs7_stream
Fix to advance past multiple recipients
This commit is contained in:
@@ -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 \
|
||||
|
||||
@@ -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 "---------------------------------------------------------------------"
|
||||
|
||||
|
||||
BIN
certs/test-multiple-recipients.p7b
Normal file
BIN
certs/test-multiple-recipients.p7b
Normal file
Binary file not shown.
@@ -2145,6 +2145,91 @@ 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));
|
||||
#if defined(NO_AES) || defined(NO_AES_256)
|
||||
ExpectIntEQ(ret, ALGO_ID_E);
|
||||
#else
|
||||
ExpectIntGT(ret, 0);
|
||||
#endif
|
||||
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));
|
||||
#if defined(NO_AES) || defined(NO_AES_256)
|
||||
ExpectIntEQ(ret, ALGO_ID_E);
|
||||
#else
|
||||
ExpectIntGT(ret, 0);
|
||||
#endif
|
||||
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()
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
@@ -10487,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,
|
||||
@@ -11973,8 +11982,15 @@ 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_NO_ERR_TRACE(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
|
||||
@@ -12095,8 +12111,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;
|
||||
@@ -12315,9 +12331,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)
|
||||
@@ -12396,9 +12420,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;
|
||||
|
||||
@@ -12457,17 +12480,21 @@ 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 = recipientSetSz;
|
||||
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,8 +12510,8 @@ 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,
|
||||
decryptedKey, &decryptedKeySz,
|
||||
&recipFound);
|
||||
@@ -12497,10 +12524,24 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in,
|
||||
if (ret != 0)
|
||||
break;
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
/* advance idx past recipient info set if not all recipients
|
||||
* parsed */
|
||||
if (pkcs7->stream->totalRd < ((word32)pkcs7->stream->recipientSz +
|
||||
tmpIdx)) {
|
||||
idx = tmpIdx + (word32)pkcs7->stream->recipientSz;
|
||||
|
||||
/* process additional 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 +
|
||||
ASN_TAG_SZ + MAX_LENGTH_SZ;
|
||||
#else
|
||||
idx = tmpIdx + recipientSetSz;
|
||||
#endif
|
||||
wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_3);
|
||||
FALL_THROUGH;
|
||||
|
||||
Reference in New Issue
Block a user