Skip to content

Commit fa053be

Browse files
authored
Merge pull request #6496 from JacobBarthelmeh/PKCS7
parse ASN1 only with SMIME_read_PKCS7
2 parents f2809c5 + 9d3a95a commit fa053be

3 files changed

Lines changed: 99 additions & 50 deletions

File tree

src/ssl.c

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37036,19 +37036,14 @@ PKCS7* wolfSSL_d2i_PKCS7(PKCS7** p7, const unsigned char** in, int len)
3703637036
return wolfSSL_d2i_PKCS7_ex(p7, in, len, NULL, 0);
3703737037
}
3703837038

37039-
/*****************************************************************************
37040-
* wolfSSL_d2i_PKCS7_ex - Converts the given unsigned char buffer of size len
37041-
* into a PKCS7 object. Optionally, accepts a byte buffer of content which
37042-
* is stored as the PKCS7 object's content, to support detached signatures.
37043-
* @param content The content which is signed, in case the signature is
37044-
* detached. Ignored if NULL.
37045-
* @param contentSz The size of the passed in content.
37039+
/* This internal function is only decoding and setting up the PKCS7 struct. It
37040+
* does not verify the PKCS7 signature.
3704637041
*
3704737042
* RETURNS:
3704837043
* returns pointer to a PKCS7 structure on success, otherwise returns NULL
3704937044
*/
37050-
PKCS7* wolfSSL_d2i_PKCS7_ex(PKCS7** p7, const unsigned char** in, int len,
37051-
byte* content, word32 contentSz)
37045+
static PKCS7* wolfSSL_d2i_PKCS7_only(PKCS7** p7, const unsigned char** in,
37046+
int len, byte* content, word32 contentSz)
3705237047
{
3705337048
WOLFSSL_PKCS7* pkcs7 = NULL;
3705437049

@@ -37072,19 +37067,50 @@ PKCS7* wolfSSL_d2i_PKCS7_ex(PKCS7** p7, const unsigned char** in, int len,
3707237067
pkcs7->pkcs7.content = content;
3707337068
pkcs7->pkcs7.contentSz = contentSz;
3707437069
}
37075-
if (wc_PKCS7_VerifySignedData(&pkcs7->pkcs7, pkcs7->data, pkcs7->len)
37076-
!= 0) {
37077-
WOLFSSL_MSG("wc_PKCS7_VerifySignedData failed");
37078-
wolfSSL_PKCS7_free((PKCS7*)pkcs7);
37079-
return NULL;
37080-
}
3708137070

3708237071
if (p7 != NULL)
3708337072
*p7 = (PKCS7*)pkcs7;
3708437073
*in += pkcs7->len;
3708537074
return (PKCS7*)pkcs7;
3708637075
}
3708737076

37077+
37078+
/*****************************************************************************
37079+
* wolfSSL_d2i_PKCS7_ex - Converts the given unsigned char buffer of size len
37080+
* into a PKCS7 object. Optionally, accepts a byte buffer of content which
37081+
* is stored as the PKCS7 object's content, to support detached signatures.
37082+
* @param content The content which is signed, in case the signature is
37083+
* detached. Ignored if NULL.
37084+
* @param contentSz The size of the passed in content.
37085+
*
37086+
* RETURNS:
37087+
* returns pointer to a PKCS7 structure on success, otherwise returns NULL
37088+
*/
37089+
PKCS7* wolfSSL_d2i_PKCS7_ex(PKCS7** p7, const unsigned char** in, int len,
37090+
byte* content, word32 contentSz)
37091+
{
37092+
WOLFSSL_PKCS7* pkcs7 = NULL;
37093+
37094+
WOLFSSL_ENTER("wolfSSL_d2i_PKCS7_ex");
37095+
37096+
if (in == NULL || *in == NULL || len < 0)
37097+
return NULL;
37098+
37099+
pkcs7 = (WOLFSSL_PKCS7*)wolfSSL_d2i_PKCS7_only(p7, in, len, content,
37100+
contentSz);
37101+
if (pkcs7 != NULL) {
37102+
if (wc_PKCS7_VerifySignedData(&pkcs7->pkcs7, pkcs7->data, pkcs7->len)
37103+
!= 0) {
37104+
WOLFSSL_MSG("wc_PKCS7_VerifySignedData failed");
37105+
wolfSSL_PKCS7_free((PKCS7*)pkcs7);
37106+
return NULL;
37107+
}
37108+
}
37109+
37110+
return (PKCS7*)pkcs7;
37111+
}
37112+
37113+
3708837114
/**
3708937115
* This API was added as a helper function for libest. It
3709037116
* extracts a stack of certificates from the pkcs7 object.
@@ -38256,7 +38282,7 @@ PKCS7* wolfSSL_SMIME_read_PKCS7(WOLFSSL_BIO* in,
3825638282
WOLFSSL_MSG("Error base64 decoding S/MIME message.");
3825738283
goto error;
3825838284
}
38259-
pkcs7 = wolfSSL_d2i_PKCS7_ex(NULL, (const unsigned char**)&out, outLen,
38285+
pkcs7 = wolfSSL_d2i_PKCS7_only(NULL, (const unsigned char**)&out, outLen,
3826038286
bcontMem, bcontMemSz);
3826138287

3826238288
wc_MIME_free_hdrs(allHdrs);

tests/api.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25656,18 +25656,32 @@ static int test_wc_PKCS7_EncodeDecodeEnvelopedData(void)
2565625656
tempWrd32 = pkcs7->singleCertSz;
2565725657
pkcs7->singleCertSz = 0;
2565825658
}
25659+
#if defined(WOLFSSL_ASN_TEMPLATE)
2565925660
ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
2566025661
(word32)sizeof(output), decoded, (word32)sizeof(decoded)),
25661-
BAD_FUNC_ARG);
25662+
BUFFER_E);
25663+
#else
25664+
ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
25665+
(word32)sizeof(output), decoded, (word32)sizeof(decoded)),
25666+
ASN_PARSE_E);
25667+
#endif
2566225668
if (pkcs7 != NULL) {
2566325669
pkcs7->singleCertSz = tempWrd32;
2566425670

2566525671
tmpBytePtr = pkcs7->singleCert;
2566625672
pkcs7->singleCert = NULL;
2566725673
}
25674+
#if defined(NO_PKCS7_STREAM)
25675+
/* when none streaming mode is used and PKCS7 is in bad state buffer error
25676+
* is returned from kari parse which gets set to bad func arg */
2566825677
ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
2566925678
(word32)sizeof(output), decoded, (word32)sizeof(decoded)),
2567025679
BAD_FUNC_ARG);
25680+
#else
25681+
ExpectIntEQ(wc_PKCS7_DecodeEnvelopedData(pkcs7, output,
25682+
(word32)sizeof(output), decoded, (word32)sizeof(decoded)),
25683+
ASN_PARSE_E);
25684+
#endif
2567125685
if (pkcs7 != NULL) {
2567225686
pkcs7->singleCert = tmpBytePtr;
2567325687
}
@@ -48860,7 +48874,7 @@ static int test_wolfSSL_SMIME_read_PKCS7(void)
4886048874
smimeTestFile = XFOPEN("./certs/test/smime-test-multipart-badsig.p7s", "r");
4886148875
ExpectIntEQ(wolfSSL_BIO_set_fp(bio, smimeTestFile, BIO_CLOSE), SSL_SUCCESS);
4886248876
pkcs7 = wolfSSL_SMIME_read_PKCS7(bio, &bcont);
48863-
ExpectNull(pkcs7);
48877+
ExpectNotNull(pkcs7); /* can read in the unverified smime bundle */
4886448878
ExpectIntEQ(wolfSSL_PKCS7_verify(pkcs7, NULL, NULL, bcont, NULL,
4886548879
PKCS7_NOVERIFY), SSL_FAILURE);
4886648880
XFCLOSE(smimeTestFile);

wolfcrypt/src/pkcs7.c

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5771,29 +5771,30 @@ static int wc_PKCS7_KariParseRecipCert(WC_PKCS7_KARI* kari, const byte* cert,
57715771
int ret;
57725772
word32 idx;
57735773

5774-
if (kari == NULL || kari->decoded == NULL ||
5775-
cert == NULL || certSz == 0)
5774+
if (kari == NULL || kari->decoded == NULL) {
57765775
return BAD_FUNC_ARG;
5776+
}
57775777

57785778
/* decode certificate */
5779-
InitDecodedCert(kari->decoded, (byte*)cert, certSz, kari->heap);
5780-
kari->decodedInit = 1;
5781-
ret = ParseCert(kari->decoded, CA_TYPE, NO_VERIFY, 0);
5782-
if (ret < 0)
5783-
return ret;
5779+
if (cert != NULL) {
5780+
InitDecodedCert(kari->decoded, (byte*)cert, certSz, kari->heap);
5781+
kari->decodedInit = 1;
5782+
ret = ParseCert(kari->decoded, CA_TYPE, NO_VERIFY, 0);
5783+
if (ret < 0)
5784+
return ret;
57845785

5785-
/* only supports ECDSA for now */
5786-
if (kari->decoded->keyOID != ECDSAk) {
5787-
WOLFSSL_MSG("CMS KARI only supports ECDSA key types");
5788-
return BAD_FUNC_ARG;
5789-
}
5786+
/* only supports ECDSA for now */
5787+
if (kari->decoded->keyOID != ECDSAk) {
5788+
WOLFSSL_MSG("CMS KARI only supports ECDSA key types");
5789+
return BAD_FUNC_ARG;
5790+
}
57905791

5791-
/* make sure subject key id was read from cert */
5792-
if (kari->decoded->extSubjKeyIdSet == 0) {
5793-
WOLFSSL_MSG("Failed to read subject key ID from recipient cert");
5794-
return BAD_FUNC_ARG;
5792+
/* make sure subject key id was read from cert */
5793+
if (kari->decoded->extSubjKeyIdSet == 0) {
5794+
WOLFSSL_MSG("Failed to read subject key ID from recipient cert");
5795+
return BAD_FUNC_ARG;
5796+
}
57955797
}
5796-
57975798
ret = wc_ecc_init_ex(kari->recipKey, kari->heap, kari->devId);
57985799
if (ret != 0)
57995800
return ret;
@@ -5802,6 +5803,10 @@ static int wc_PKCS7_KariParseRecipCert(WC_PKCS7_KARI* kari, const byte* cert,
58025803

58035804
/* get recip public key */
58045805
if (kari->direction == WC_PKCS7_ENCODE) {
5806+
if (cert == NULL) {
5807+
WOLFSSL_MSG("Error recipient cert can not be null with encode");
5808+
return BAD_FUNC_ARG;
5809+
}
58055810

58065811
idx = 0;
58075812
ret = wc_EccPublicKeyDecode(kari->decoded->publicKey, &idx,
@@ -9270,7 +9275,14 @@ static int wc_PKCS7_KariGetIssuerAndSerialNumber(WC_PKCS7_KARI* kari,
92709275
}
92719276

92729277
/* if we found correct recipient, issuer hashes will match */
9273-
if (XMEMCMP(rid, kari->decoded->issuerHash, keyIdSize) == 0) {
9278+
if (kari->decodedInit == 1) {
9279+
if (XMEMCMP(rid, kari->decoded->issuerHash, keyIdSize) == 0) {
9280+
*recipFound = 1;
9281+
}
9282+
}
9283+
else {
9284+
/* can not confirm recipient serial number with no cert provided */
9285+
WOLFSSL_MSG("No recipient cert loaded to match with CMS serial number");
92749286
*recipFound = 1;
92759287
}
92769288

@@ -9308,7 +9320,8 @@ static int wc_PKCS7_KariGetIssuerAndSerialNumber(WC_PKCS7_KARI* kari,
93089320
return ret;
93099321
}
93109322

9311-
if (mp_cmp(recipSerial, serial) != MP_EQ) {
9323+
if (kari->decodedInit == 1 &&
9324+
mp_cmp(recipSerial, serial) != MP_EQ) {
93129325
mp_clear(serial);
93139326
mp_clear(recipSerial);
93149327
WOLFSSL_MSG("CMS serial number does not match recipient");
@@ -9944,8 +9957,6 @@ static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz,
99449957

99459958
WOLFSSL_ENTER("wc_PKCS7_DecryptKari");
99469959
if (pkcs7 == NULL || pkiMsg == NULL ||
9947-
((pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0) &&
9948-
pkcs7->wrapCEKCb == NULL) ||
99499960
idx == NULL || decryptedKey == NULL || decryptedKeySz == NULL) {
99509961
return BAD_FUNC_ARG;
99519962
}
@@ -9986,17 +9997,15 @@ static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz,
99869997
encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
99879998

99889999
/* parse cert and key */
9989-
if (pkcs7->singleCert != NULL) {
9990-
ret = wc_PKCS7_KariParseRecipCert(kari, (byte*)pkcs7->singleCert,
9991-
pkcs7->singleCertSz, pkcs7->privateKey,
9992-
pkcs7->privateKeySz);
9993-
if (ret != 0) {
9994-
wc_PKCS7_KariFree(kari);
9995-
#ifdef WOLFSSL_SMALL_STACK
9996-
XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
9997-
#endif
9998-
return ret;
9999-
}
10000+
ret = wc_PKCS7_KariParseRecipCert(kari, (byte*)pkcs7->singleCert,
10001+
pkcs7->singleCertSz, pkcs7->privateKey,
10002+
pkcs7->privateKeySz);
10003+
if (ret != 0) {
10004+
wc_PKCS7_KariFree(kari);
10005+
#ifdef WOLFSSL_SMALL_STACK
10006+
XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
10007+
#endif
10008+
return ret;
1000010009
}
1000110010

1000210011
/* remove OriginatorIdentifierOrKey */

0 commit comments

Comments
 (0)