@@ -106,6 +106,7 @@ struct PKCS7State {
106106 word32 currContSz; /* size of current content */
107107 word32 currContRmnSz; /* remaining size of current content */
108108 word32 accumContSz; /* size of accumulated content size */
109+ int recipientSz; /* size of recipient set */
109110 byte tmpIv[MAX_CONTENT_IV_SIZE]; /* store IV if needed */
110111#ifdef WC_PKCS7_STREAM_DEBUG
111112 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,
1048710488 XMEMCPY(encryptedKey, &pkiMsg[*idx], (word32)encryptedKeySz);
1048810489 *idx += (word32)encryptedKeySz;
1048910490
10491+ /* If this is not the correct recipient then do not try to decode
10492+ * the encrypted key */
10493+ if (*recipFound == 0) {
10494+ XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_WOLF_BIGINT);
10495+ ret = PKCS7_RECIP_E;
10496+ break;
10497+ }
10498+
1049010499 /* load private key */
1049110500 #ifdef WOLFSSL_SMALL_STACK
1049210501 privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,
@@ -11973,8 +11982,15 @@ static int wc_PKCS7_DecryptRecipientInfos(wc_PKCS7* pkcs7, byte* in,
1197311982 ret = wc_PKCS7_DecryptKtri(pkcs7, in, inSz, idx,
1197411983 decryptedKey, decryptedKeySz,
1197511984 recipFound);
11976- if (ret != 0)
11977- return ret;
11985+ if (ret != 0) {
11986+ if (ret != WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E) &&
11987+ *recipFound == 0) {
11988+ continue; /* try next recipient */
11989+ }
11990+ else {
11991+ return ret; /* found recipient and failed decrypt */
11992+ }
11993+ }
1197811994 #else
1197911995 return NOT_COMPILED_IN;
1198011996 #endif
@@ -12095,8 +12111,8 @@ static int wc_PKCS7_DecryptRecipientInfos(wc_PKCS7* pkcs7, byte* in,
1209512111 recipFound);
1209612112 if (ret != 0)
1209712113 return ret;
12098-
12099- } else {
12114+ }
12115+ else {
1210012116 /* failed to find RecipientInfo, restore idx and continue */
1210112117 *idx = savedIdx;
1210212118 break;
@@ -12315,9 +12331,17 @@ static int wc_PKCS7_ParseToRecipientInfoSet(wc_PKCS7* pkcs7, byte* in,
1231512331
1231612332 #ifndef NO_PKCS7_STREAM
1231712333 pkcs7->stream->expected = (word32)length;
12334+
1231812335 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
1231912336 break;
1232012337 }
12338+
12339+ /* update the stored max length */
12340+ if (pkcs7->stream->totalRd + pkcs7->stream->expected >
12341+ pkcs7->stream->maxLen) {
12342+ pkcs7->stream->maxLen = pkcs7->stream->totalRd +
12343+ pkcs7->stream->expected;
12344+ }
1232112345 #endif
1232212346
1232312347 if (ret == 0)
@@ -12396,9 +12420,8 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in,
1239612420 int recipFound = 0;
1239712421 int ret, length = 0;
1239812422 word32 idx = 0;
12399- #ifndef NO_PKCS7_STREAM
1240012423 word32 tmpIdx = 0;
12401- #endif
12424+ word32 recipientSetSz = 0;
1240212425 word32 contentType = 0, encOID = 0;
1240312426 word32 decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
1240412427
@@ -12457,17 +12480,21 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in,
1245712480 if (decryptedKey == NULL)
1245812481 return MEMORY_E;
1245912482 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_2);
12460- #ifndef NO_PKCS7_STREAM
1246112483 tmpIdx = idx;
12484+ recipientSetSz = (word32)ret;
12485+ #ifndef NO_PKCS7_STREAM
1246212486 pkcs7->stream->aad = decryptedKey;
12487+ /* get the full recipient set */
12488+ pkcs7->stream->expected = recipientSetSz;
12489+ pkcs7->stream->recipientSz = ret;
1246312490 #endif
1246412491 FALL_THROUGH;
1246512492
1246612493 case WC_PKCS7_ENV_2:
1246712494 #ifndef NO_PKCS7_STREAM
1246812495 /* store up enough buffer for initial info set decode */
12469- if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
12470- MAX_VERSION_SZ + ASN_TAG_SZ , &pkiMsg, &idx)) != 0) {
12496+ if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
12497+ pkcs7->stream->expected , &pkiMsg, &idx)) != 0) {
1247112498 return ret;
1247212499 }
1247312500 #endif
@@ -12483,8 +12510,8 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in,
1248312510 #ifndef NO_PKCS7_STREAM
1248412511 decryptedKey = pkcs7->stream->aad;
1248512512 decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
12513+ tmpIdx = idx;
1248612514 #endif
12487-
1248812515 ret = wc_PKCS7_DecryptRecipientInfos(pkcs7, in, inSz, &idx,
1248912516 decryptedKey, &decryptedKeySz,
1249012517 &recipFound);
@@ -12497,10 +12524,24 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in,
1249712524 if (ret != 0)
1249812525 break;
1249912526 #ifndef NO_PKCS7_STREAM
12527+ /* advance idx past recipient info set if not all recipients
12528+ * parsed */
12529+ if (pkcs7->stream->totalRd < ((word32)pkcs7->stream->recipientSz +
12530+ tmpIdx)) {
12531+ idx = tmpIdx + (word32)pkcs7->stream->recipientSz;
12532+
12533+ /* process additional recipients as read */
12534+ if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
12535+ break;
12536+ }
12537+ }
12538+
1250012539 tmpIdx = idx;
1250112540 pkcs7->stream->aadSz = decryptedKeySz;
1250212541 pkcs7->stream->expected = MAX_LENGTH_SZ + MAX_VERSION_SZ +
1250312542 ASN_TAG_SZ + MAX_LENGTH_SZ;
12543+ #else
12544+ idx = tmpIdx + recipientSetSz;
1250412545 #endif
1250512546 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_3);
1250612547 FALL_THROUGH;
0 commit comments