diff --git a/tests/api.c b/tests/api.c index f52200e40..5383d4352 100644 --- a/tests/api.c +++ b/tests/api.c @@ -16616,6 +16616,80 @@ static void test_wc_PKCS7_BER(void) #endif } /* END test_wc_PKCS7_BER() */ +static void test_PKCS7_signed_enveloped(void) +{ +#if defined(HAVE_PKCS7) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) + XFILE f; + PKCS7* pkcs7; + void* pt; + WC_RNG rng; + unsigned char key[FOURK_BUF/2]; + unsigned char cert[FOURK_BUF/2]; + unsigned char env[FOURK_BUF/2]; + int envSz = FOURK_BUF/2; + int keySz; + int certSz; + + unsigned char sig[FOURK_BUF]; + int sigSz = FOURK_BUF; + + printf(testingFmt, "PKCS7_signed_enveloped"); + + /* load cert */ + AssertNotNull(f = XFOPEN(cliCertDerFile, "rb")); + AssertIntGT((certSz = (int)XFREAD(cert, 1, sizeof(cert), f)), 0); + XFCLOSE(f); + + /* load key */ + AssertNotNull(f = XFOPEN(cliKeyFile, "rb")); + AssertIntGT((keySz = (int)XFREAD(key, 1, sizeof(key), f)), 0); + XFCLOSE(f); + keySz = wolfSSL_KeyPemToDer(key, keySz, key, keySz, NULL); + + /* create envelope */ + AssertNotNull(pkcs7 = wc_PKCS7_New(NULL, 0)); + AssertIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, certSz), 0); + pkcs7->content = cert; + pkcs7->contentSz = certSz; + pkcs7->contentOID = DATA; + pkcs7->encryptOID = AES256CBCb; + pkcs7->privateKey = key; + pkcs7->privateKeySz = keySz; + AssertIntGT((envSz = wc_PKCS7_EncodeEnvelopedData(pkcs7, env, envSz)), 0); + wc_PKCS7_Free(pkcs7); + + /* create signed enveloped data */ + AssertNotNull(pkcs7 = wc_PKCS7_New(NULL, 0)); + AssertIntEQ(wc_InitRng(&rng), 0); + AssertIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, certSz), 0); + pkcs7->content = env; + pkcs7->contentSz = envSz; + pkcs7->contentOID = DATA; + pkcs7->encryptOID = AES256CBCb; + pkcs7->privateKey = key; + pkcs7->privateKeySz = keySz; + pkcs7->encryptOID = RSAk; + pkcs7->hashOID = SHA256h; + pkcs7->rng = &rng; + + /* Set no certs in bundle for this test. Hang on to the pointer though to + * free it later. */ + pt = (void*)pkcs7->certList; + pkcs7->certList = NULL; /* no certs in bundle */ + AssertIntGT((sigSz = wc_PKCS7_EncodeSignedData(pkcs7, sig, sigSz)), 0); + pkcs7->certList = pt; /* restore pointer for PKCS7 free call */ + wc_PKCS7_Free(pkcs7); + wc_FreeRng(&rng); + + /* check verify */ + AssertNotNull(pkcs7 = wc_PKCS7_New(NULL, 0)); + AssertIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, certSz), 0); + AssertIntEQ(wc_PKCS7_VerifySignedData(pkcs7, sig, sigSz), 0); + wc_PKCS7_Free(pkcs7); + printf(resultFmt, passed); + +#endif +} /* Testing wc_SignatureGetSize() for signature type ECC */ static int test_wc_SignatureGetSize_ecc(void) @@ -24040,6 +24114,7 @@ void ApiTest(void) test_wc_PKCS7_EncodeEncryptedData(); test_wc_PKCS7_Degenerate(); test_wc_PKCS7_BER(); + test_PKCS7_signed_enveloped(); test_wolfSSL_CTX_LoadCRL(); diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index cd2e0ad33..cf5bbf537 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -2038,7 +2038,8 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, } certPtr = NULL; - esd->certsSetSz = SetImplicit(ASN_SET, 0, certSetSz, esd->certsSet); + if (certSetSz > 0) + esd->certsSetSz = SetImplicit(ASN_SET, 0, certSetSz, esd->certsSet); esd->singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->singleDigAlgoId, oidHashType, 0); @@ -3418,7 +3419,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, word32 hashSz, byte* in, word32 inSz, byte* in2, word32 in2Sz) { - word32 idx, outerContentType, hashOID = 0, sigOID, contentTypeSz = 0, totalSz = 0; + word32 idx, outerContentType, hashOID = 0, sigOID = 0, contentTypeSz = 0, totalSz = 0; int length = 0, version, ret = 0; byte* content = NULL; byte* contentDynamic = NULL; @@ -3547,7 +3548,6 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, pkiMsgSz) < 0) ret = ASN_PARSE_E; - if (ret == 0 && outerContentType != SIGNED_DATA) { WOLFSSL_MSG("PKCS#7 input not of type SignedData"); ret = PKCS7_OID_E; @@ -3859,6 +3859,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, pkiMsg2 = pkiMsg; pkiMsg2Sz = pkiMsgSz; #ifndef NO_PKCS7_STREAM + pkcs7->stream->varOne = pkiMsg2Sz; pkcs7->stream->flagOne = 1; #endif } @@ -3868,6 +3869,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, pkiMsg2 = pkiMsg; pkiMsg2Sz = pkiMsgSz; #ifndef NO_PKCS7_STREAM + pkcs7->stream->varOne = pkiMsg2Sz; pkcs7->stream->flagOne = 1; #endif } @@ -3886,6 +3888,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, if (ret == 0 && idx >= pkiMsg2Sz) ret = BUFFER_E; + length = 0; /* set length to 0 to check if reading in any certs */ if (ret == 0 && pkiMsg2[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) { idx++; @@ -4083,7 +4086,8 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, #ifndef NO_PKCS7_STREAM /* factor in that recent idx was in cert buffer. If in2 buffer was * used then don't advance idx. */ - if (pkcs7->stream->flagOne && pkcs7->stream->length == 0) { + if (length > 0 && pkcs7->stream->flagOne && + pkcs7->stream->length == 0) { idx = stateIdx + idx; if (idx > inSz) { /* index is more than input size */ @@ -4283,9 +4287,11 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, } /* store public key type based on digestEncryptionAlgorithm */ - if ((ret = 0) && ((ret = wc_PKCS7_SetPublicKeyOID(pkcs7, sigOID)) - <= 0)) { - WOLFSSL_MSG("Failed to set public key OID from signature"); + if (ret == 0) { + ret = wc_PKCS7_SetPublicKeyOID(pkcs7, sigOID); + if (ret < 0) { + WOLFSSL_MSG("Failed to set public key OID from signature"); + } } if (idx >= pkiMsg2Sz)