From 1e254c014db62b871e6e017e7afc03475a50ba1c Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Thu, 20 Feb 2025 00:23:06 -0700 Subject: [PATCH] application decryption successful --- certs/include.am | 1 + certs/renewcerts.sh | 5 + certs/test-stream-dec.p7b | Bin 0 -> 6093 bytes tests/api.c | 69 ++++ wolfcrypt/src/pkcs7.c | 663 +++++++++++++++++++++++++++----------- wolfssl/wolfcrypt/pkcs7.h | 15 + 6 files changed, 560 insertions(+), 193 deletions(-) create mode 100644 certs/test-stream-dec.p7b diff --git a/certs/include.am b/certs/include.am index f3f1f6a36..1c622e8c3 100644 --- a/certs/include.am +++ b/certs/include.am @@ -53,6 +53,7 @@ EXTRA_DIST += \ certs/wolfssl-website-ca.pem \ certs/test-degenerate.p7b \ certs/test-stream-sign.p7b \ + certs/test-stream-dec.p7b \ certs/test-ber-exp02-05-2022.p7b \ certs/test-servercert.p12 \ certs/test-servercert-rc2.p12 \ diff --git a/certs/renewcerts.sh b/certs/renewcerts.sh index 5a1726bd5..cf5154217 100755 --- a/certs/renewcerts.sh +++ b/certs/renewcerts.sh @@ -858,6 +858,11 @@ run_renewcerts(){ openssl smime -sign -in ./ca-cert.pem -out test-stream-sign.p7b -signer ./ca-cert.pem -nodetach -nocerts -binary -outform DER -stream -inkey ./ca-key.pem check_result $? "" + echo "Creating test-stream-dec.p7b..." + echo "" + openssl cms -encrypt -in ca-cert.pem -recip client-cert.pem -out test-stream-dec.p7b -outform DER -stream + check_result $? "" + echo "End of section" echo "---------------------------------------------------------------------" diff --git a/certs/test-stream-dec.p7b b/certs/test-stream-dec.p7b new file mode 100644 index 0000000000000000000000000000000000000000..a70b37fc4dc6f519dda5bae2c6c42619bd69fe55 GIT binary patch literal 6093 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 P?!Q@E%5Eo|W`F|#55K8~ literal 0 HcmV?d00001 diff --git a/tests/api.c b/tests/api.c index e90082864..6d63494b0 100644 --- a/tests/api.c +++ b/tests/api.c @@ -39205,6 +39205,74 @@ static int myCEKwrapFunc(PKCS7* pkcs7, byte* cek, word32 cekSz, byte* keyId, #endif /* HAVE_PKCS7 && !NO_AES && HAVE_AES_CBC && !NO_AES_256 */ +#define MAX_TEST_DECODE_SIZE 6000 +static int test_wc_PKCS7_DecodeEnvelopedData_stream_decrypt_cb(PKCS7* pkcs7, const byte* output, + word32 outputSz, void* ctx) { + WOLFSSL_BUFFER_INFO* out = (WOLFSSL_BUFFER_INFO*)ctx; + + if (out == NULL) { + return -1; + } + + if (outputSz + out->length > MAX_TEST_DECODE_SIZE) { + printf("Example buffer size needs increased"); + } + + XMEMCPY(out->buffer + out->length, output, outputSz); + out->length += outputSz; + + (void)pkcs7; + return 0; +} + +/* + * Testing wc_PKCS7_DecodeEnvelopedData with streaming + */ +static int test_wc_PKCS7_DecodeEnvelopedData_stream(void) +{ +#if defined(HAVE_PKCS7) && defined(ASN_BER_TO_DER) + EXPECT_DECLS; + PKCS7* pkcs7 = NULL; + int ret; + FILE* f; + const char* testStream = "./certs/test-stream-dec.p7b"; + byte testStreamBuffer[100]; + int testStreamBufferSz; + byte decodedData[MAX_TEST_DECODE_SIZE]; /* large enough to hold result of decode, which is ca-cert.pem */ + WOLFSSL_BUFFER_INFO out; + + out.length = 0; + out.buffer = decodedData; + + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); + 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); + ExpectIntEQ(wc_PKCS7_SetStreamMode(pkcs7, 1, NULL, + test_wc_PKCS7_DecodeEnvelopedData_stream_decrypt_cb, (void*)&out), 0); + + do { + ExpectTrue((f = XFOPEN(testStream, "rb")) != XBADFILE); + ExpectIntGT(testStreamBufferSz = (int)XFREAD(testStreamBuffer, 1, + sizeof(testStreamBuffer), f), 0); + + ret = wc_PKCS7_DecodeEnvelopedData(pkcs7, testStreamBuffer, testStreamBufferSz, NULL, 0); + } while (ret == WC_PKCS7_WANT_READ_E); + ExpectIntGT(ret, 0); + + if (f != XBADFILE) { + XFCLOSE(f); + f = XBADFILE; + } + + wc_PKCS7_Free(pkcs7); + return EXPECT_RESULT(); +#else + return TEST_SKIPPED; +#endif +} /* END test_wc_PKCS7_DecodeEnvelopedData_stream() */ + /* * Testing wc_PKCS7_EncodeEnvelopedData() */ @@ -89456,6 +89524,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_wc_PKCS7_EncodeSignedData_ex), TEST_DECL(test_wc_PKCS7_VerifySignedData_RSA), TEST_DECL(test_wc_PKCS7_VerifySignedData_ECC), + TEST_DECL(test_wc_PKCS7_DecodeEnvelopedData_stream), TEST_DECL(test_wc_PKCS7_EncodeDecodeEnvelopedData), TEST_DECL(test_wc_PKCS7_EncodeEncryptedData), TEST_DECL(test_wc_PKCS7_Degenerate), diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 95209d3dd..08c3281b4 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -383,7 +383,7 @@ static int wc_PKCS7_SetMaxStream(wc_PKCS7* pkcs7, byte* in, word32 defSz) idx = 0; if ((ret = wc_BerToDer(pt, maxIdx, NULL, (word32*)&length)) != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) { - return ret; + // return ret; } } #endif /* ASN_BER_TO_DER */ @@ -8448,34 +8448,21 @@ static int wc_PKCS7_EncryptContent(wc_PKCS7* pkcs7, int encryptOID, byte* key, } -/* decrypt content using encryptOID algo - * returns 0 on success */ -static int wc_PKCS7_DecryptContent(wc_PKCS7* pkcs7, int encryptOID, byte* key, - int keySz, byte* iv, int ivSz, byte* aad, word32 aadSz, byte* authTag, - word32 authTagSz, byte* in, int inSz, byte* out, int devId, void* heap) +static int wc_PKCS7_DecryptContentInit(PKCS7* pkcs7, int encryptOID, byte* key, + int keySz, byte* iv, int ivSz, int devId, void* heap) { int ret; #ifndef NO_AES -#ifdef WOLFSSL_SMALL_STACK Aes *aes; -#else - Aes aes[1]; -#endif #endif #ifndef NO_DES3 - Des des; - Des3 des3; + Des *des; + Des3 *des3; #endif - if (iv == NULL || in == NULL || out == NULL) + if (iv == NULL) return BAD_FUNC_ARG; - if (pkcs7->decryptionCb != NULL) { - return pkcs7->decryptionCb(pkcs7, encryptOID, iv, ivSz, - aad, aadSz, authTag, authTagSz, in, - inSz, out, pkcs7->decryptionCtx); - } - if (key == NULL) return BAD_FUNC_ARG; @@ -8503,26 +8490,138 @@ static int wc_PKCS7_DecryptContent(wc_PKCS7* pkcs7, int encryptOID, byte* key, #endif (ivSz != WC_AES_BLOCK_SIZE) ) return BAD_FUNC_ARG; -#ifdef WOLFSSL_SMALL_STACK - if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL, - DYNAMIC_TYPE_AES)) == NULL) + + pkcs7->decryptKey.aes = (Aes *)XMALLOC(sizeof *aes, NULL, + DYNAMIC_TYPE_AES); + aes = pkcs7->decryptKey.aes; + if (aes == NULL) return MEMORY_E; -#endif ret = wc_AesInit(aes, heap, devId); if (ret == 0) { ret = wc_AesSetKey(aes, key, (word32)keySz, iv, AES_DECRYPTION); - if (ret == 0) { - ret = wc_AesCbcDecrypt(aes, out, in, (word32)inSz); - #ifdef WOLFSSL_ASYNC_CRYPT - /* async decrypt not available here, so block till done */ - ret = wc_AsyncWait(ret, &aes->asyncDev, WC_ASYNC_FLAG_NONE); - #endif - } - wc_AesFree(aes); } -#ifdef WOLFSSL_SMALL_STACK - XFREE(aes, NULL, DYNAMIC_TYPE_AES); -#endif + break; + + #endif /* HAVE_AES_CBC */ + #ifdef HAVE_AESGCM + #ifdef WOLFSSL_AES_128 + case AES128GCMb: + #endif + #ifdef WOLFSSL_AES_192 + case AES192GCMb: + #endif + #ifdef WOLFSSL_AES_256 + case AES256GCMb: + #endif + #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \ + defined(WOLFSSL_AES_256) + pkcs7->decryptKey.aes = (Aes *)XMALLOC(sizeof *aes, NULL, + DYNAMIC_TYPE_AES); + aes = pkcs7->decryptKey.aes; + if (aes == NULL) + return MEMORY_E; + ret = wc_AesInit(aes, heap, devId); + if (ret == 0) { + ret = wc_AesGcmSetKey(aes, key, (word32)keySz); + } + break; + #endif + #endif /* HAVE_AESGCM */ + #ifdef HAVE_AESCCM + #ifdef WOLFSSL_AES_128 + case AES128CCMb: + #endif + #ifdef WOLFSSL_AES_192 + case AES192CCMb: + #endif + #ifdef WOLFSSL_AES_256 + case AES256CCMb: + #endif + #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \ + defined(WOLFSSL_AES_256) + pkcs7->decryptKey.aes = (Aes *)XMALLOC(sizeof *aes, NULL, + DYNAMIC_TYPE_AES); + aes = pkcs7->decryptKey.aes; + if (aes == NULL) + return MEMORY_E; + ret = wc_AesInit(aes, heap, devId); + if (ret == 0) { + ret = wc_AesCcmSetKey(aes, key, (word32)keySz); + } + break; + #endif + #endif /* HAVE_AESCCM */ +#endif /* !NO_AES */ +#ifndef NO_DES3 + case DESb: + if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE) + return BAD_FUNC_ARG; + + pkcs7->decryptKey.des = (Des *)XMALLOC(sizeof *des, NULL, + DYNAMIC_TYPE_PKCS7); + des = pkcs7->decryptKey.des; + if (des == NULL) { + return MEMORY_E; + } + ret = wc_Des_SetKey(des, key, iv, DES_DECRYPTION); + break; + case DES3b: + if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE) + return BAD_FUNC_ARG; + + pkcs7->decryptKey.des3 = (Des3 *)XMALLOC(sizeof *des3, NULL, + DYNAMIC_TYPE_PKCS7); + des3 = pkcs7->decryptKey.des3; + if (des3 == NULL) { + return MEMORY_E; + } + ret = wc_Des3Init(des3, heap, devId); + if (ret == 0) { + ret = wc_Des3_SetKey(des3, key, iv, DES_DECRYPTION); + } + + break; +#endif /* !NO_DES3 */ + default: + WOLFSSL_MSG("Unsupported content cipher type"); + return ALGO_ID_E; + }; + + return ret; +} + + +/* Only does decryption of content using encryptOID algo and already set keys + * returns 0 on success */ +static int wc_PKCS7_DecryptContentEx(PKCS7* pkcs7, int encryptOID, + byte* iv, int ivSz, byte* aad, word32 aadSz, byte* authTag, + word32 authTagSz, byte* in, int inSz, byte* out) +{ + int ret; + + if (in == NULL && pkcs7->getContentCb == NULL) { + return BAD_FUNC_ARG; + } + + switch (encryptOID) { +#ifndef NO_AES + #ifdef HAVE_AES_CBC + #ifdef WOLFSSL_AES_128 + case AES128CBCb: + #endif + #ifdef WOLFSSL_AES_192 + case AES192CBCb: + #endif + #ifdef WOLFSSL_AES_256 + case AES256CBCb: + #endif +printf("trying to do decryption\n"); + ret = wc_AesCbcDecrypt(pkcs7->decryptKey.aes, out, in, + (word32)inSz); + #ifdef WOLFSSL_ASYNC_CRYPT + /* async decrypt not available here, so block till done */ + ret = wc_AsyncWait(ret, &aes->asyncDev, WC_ASYNC_FLAG_NONE); + #endif break; #endif /* HAVE_AES_CBC */ #ifdef HAVE_AESGCM @@ -8540,28 +8639,14 @@ static int wc_PKCS7_DecryptContent(wc_PKCS7* pkcs7, int encryptOID, byte* key, if (authTag == NULL) return BAD_FUNC_ARG; -#ifdef WOLFSSL_SMALL_STACK - if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL, - DYNAMIC_TYPE_AES)) == NULL) - return MEMORY_E; -#endif - ret = wc_AesInit(aes, heap, devId); - if (ret == 0) { - ret = wc_AesGcmSetKey(aes, key, (word32)keySz); - if (ret == 0) { - ret = wc_AesGcmDecrypt(aes, out, in, (word32)inSz, iv, - (word32)ivSz, authTag, authTagSz, - aad, aadSz); - #ifdef WOLFSSL_ASYNC_CRYPT - /* async decrypt not available here, so block till done */ - ret = wc_AsyncWait(ret, &aes->asyncDev, WC_ASYNC_FLAG_NONE); - #endif - } - wc_AesFree(aes); - } -#ifdef WOLFSSL_SMALL_STACK - XFREE(aes, NULL, DYNAMIC_TYPE_AES); -#endif + ret = wc_AesGcmDecrypt(pkcs7->decryptKey.aes, out, in, + (word32)inSz, iv, (word32)ivSz, authTag, authTagSz, + aad, aadSz); + #ifdef WOLFSSL_ASYNC_CRYPT + /* async decrypt not available here, so block till done */ + ret = wc_AsyncWait(ret, &pkcs7->decryptKey.aes->asyncDev, + WC_ASYNC_FLAG_NONE); + #endif break; #endif #endif /* HAVE_AESGCM */ @@ -8575,64 +8660,31 @@ static int wc_PKCS7_DecryptContent(wc_PKCS7* pkcs7, int encryptOID, byte* key, #ifdef WOLFSSL_AES_256 case AES256CCMb: #endif - #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \ - defined(WOLFSSL_AES_256) - if (authTag == NULL) - return BAD_FUNC_ARG; - -#ifdef WOLFSSL_SMALL_STACK - if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL, - DYNAMIC_TYPE_AES)) == NULL) - return MEMORY_E; -#endif - ret = wc_AesInit(aes, heap, devId); - if (ret == 0) { - ret = wc_AesCcmSetKey(aes, key, (word32)keySz); - if (ret == 0) { - ret = wc_AesCcmDecrypt(aes, out, in, (word32)inSz, iv, - (word32)ivSz, authTag, authTagSz, - aad, aadSz); - #ifdef WOLFSSL_ASYNC_CRYPT - /* async decrypt not available here, so block till done */ - ret = wc_AsyncWait(ret, &aes->asyncDev, WC_ASYNC_FLAG_NONE); - #endif - } - wc_AesFree(aes); - } -#ifdef WOLFSSL_SMALL_STACK - XFREE(aes, NULL, DYNAMIC_TYPE_AES); -#endif - break; + ret = wc_AesCcmDecrypt(pkcs7->decryptKey.aes, out, in, + (word32)inSz, iv, (word32)ivSz, authTag, authTagSz, + aad, aadSz); + #ifdef WOLFSSL_ASYNC_CRYPT + /* async decrypt not available here, so block till done */ + ret = wc_AsyncWait(ret, &pkcs7->decryptKey.aes->asyncDev, + WC_ASYNC_FLAG_NONE); #endif + break; #endif /* HAVE_AESCCM */ #endif /* !NO_AES */ #ifndef NO_DES3 case DESb: - if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE) - return BAD_FUNC_ARG; - - ret = wc_Des_SetKey(&des, key, iv, DES_DECRYPTION); - if (ret == 0) - ret = wc_Des_CbcDecrypt(&des, out, in, (word32)inSz); - + ret = wc_Des_CbcDecrypt(pkcs7->decryptKey.des, out, in, + (word32)inSz); break; + case DES3b: - if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE) - return BAD_FUNC_ARG; - - ret = wc_Des3Init(&des3, heap, devId); - if (ret == 0) { - ret = wc_Des3_SetKey(&des3, key, iv, DES_DECRYPTION); - if (ret == 0) { - ret = wc_Des3_CbcDecrypt(&des3, out, in, (word32)inSz); - #ifdef WOLFSSL_ASYNC_CRYPT - /* async decrypt not available here, so block till done */ - ret = wc_AsyncWait(ret, &des3.asyncDev, WC_ASYNC_FLAG_NONE); - #endif - } - wc_Des3Free(&des3); - } - + ret = wc_Des3_CbcDecrypt(pkcs7->decryptKey.des3, out, in, + (word32)inSz); + #ifdef WOLFSSL_ASYNC_CRYPT + /* async decrypt not available here, so block till done */ + ret = wc_AsyncWait(ret, + &pkcs7->decryptKey.des3.asyncDev, WC_ASYNC_FLAG_NONE); + #endif break; #endif /* !NO_DES3 */ default: @@ -8651,6 +8703,102 @@ static int wc_PKCS7_DecryptContent(wc_PKCS7* pkcs7, int encryptOID, byte* key, } +/* clears up struct for algo used and free's memory */ +static void wc_PKCS7_DecryptContentFree(PKCS7* pkcs7, int encryptOID, + void* heap) +{ + switch (encryptOID) { +#ifndef NO_AES + #ifdef HAVE_AES_CBC + #ifdef WOLFSSL_AES_128 + case AES128CBCb: + #endif + #ifdef WOLFSSL_AES_192 + case AES192CBCb: + #endif + #ifdef WOLFSSL_AES_256 + case AES256CBCb: + #endif + #endif /* HAVE_AES_CBC */ + #ifdef HAVE_AESGCM + #ifdef WOLFSSL_AES_128 + case AES128GCMb: + #endif + #ifdef WOLFSSL_AES_192 + case AES192GCMb: + #endif + #ifdef WOLFSSL_AES_256 + case AES256GCMb: + #endif + #endif /* HAVE_AESGCM */ + #ifdef HAVE_AESCCM + #ifdef WOLFSSL_AES_128 + case AES128CCMb: + #endif + #ifdef WOLFSSL_AES_192 + case AES192CCMb: + #endif + #ifdef WOLFSSL_AES_256 + case AES256CCMb: + #endif + #endif /* HAVE_AESCCM */ + if (pkcs7->decryptKey.aes != NULL) { + wc_AesFree(pkcs7->decryptKey.aes); + XFREE(pkcs7->decryptKey.aes, heap, DYNAMIC_TYPE_AES); + pkcs7->decryptKey.aes = NULL; + } + break; +#endif /* !NO_AES */ +#ifndef NO_DES3 + case DESb: + if (pkcs7->decryptKey.des != NULL) { + XFREE(pkcs7->decryptKey.des, heap, DYNAMIC_TYPE_PKCS7); + pkcs7->decryptKey.des = NULL; + } + break; + case DES3b: + if (pkcs7->decryptKey.des3 != NULL) { + wc_Des3Free(pkcs7->decryptKey.des3); + XFREE(pkcs7->decryptKey.des3, heap, DYNAMIC_TYPE_PKCS7); + pkcs7->decryptKey.des3 = NULL; + } + break; +#endif /* !NO_DES3 */ + default: + WOLFSSL_MSG("Unsupported content cipher type"); + }; +} + + +/* decrypts the content in one shot, doing init / decrypt / free + * returns 0 on success + */ +static int wc_PKCS7_DecryptContent(wc_PKCS7* pkcs7, int encryptOID, byte* key, + int keySz, byte* iv, int ivSz, byte* aad, word32 aadSz, byte* authTag, + word32 authTagSz, byte* in, int inSz, byte* out, int devId, void* heap) +{ + int ret; + + if (pkcs7->decryptionCb != NULL) { + return pkcs7->decryptionCb(pkcs7, encryptOID, iv, ivSz, + aad, aadSz, authTag, authTagSz, in, + inSz, out, pkcs7->decryptionCtx); + } + + ret = wc_PKCS7_DecryptContentInit(pkcs7, encryptOID, key, keySz, iv, ivSz, + devId, heap); + + if (ret == 0) { + ret = wc_PKCS7_DecryptContentEx(pkcs7, encryptOID, iv, ivSz, aad, + aadSz, authTag, authTagSz, in, inSz, out); + } + + wc_PKCS7_DecryptContentFree(pkcs7, encryptOID, heap); + + return ret; +} + + /* Generate random block, place in out, return 0 on success negative on error. * Used for generation of IV, nonce, etc */ static int wc_PKCS7_GenerateBlock(wc_PKCS7* pkcs7, WC_RNG* rng, byte* out, @@ -10106,6 +10254,7 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, return ASN_VERSION_E; } +printf("epxected size = %d\n", pkcs7->stream->expected); #ifndef NO_PKCS7_STREAM if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) { break; @@ -10119,10 +10268,12 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, ret = BUFFER_E; break; } - pkcs7->stream->expected = (pkcs7->stream->maxLen - - pkcs7->stream->totalRd) + pkcs7->stream->length; +// pkcs7->stream->expected = (pkcs7->stream->maxLen - +// pkcs7->stream->totalRd) + pkcs7->stream->length; #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI_2); +//pkcs7->stream->expected = MAX_SEQ_SZ; +printf("epxected size = %d\n", pkcs7->stream->expected); FALL_THROUGH; case WC_PKCS7_DECRYPT_KTRI_2: @@ -10139,6 +10290,7 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, wc_PKCS7_StreamGetVar(pkcs7, NULL, &sidType, &version); +printf("epxected size = %d\n", pkcs7->stream->expected); /* @TODO get expected size for next part, does not account for * GetInt call well */ if (pkcs7->stream->expected == MAX_SEQ_SZ) { @@ -10159,7 +10311,8 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, } pkcs7->stream->expected = (word32)sz + MAX_ALGO_SZ + ASN_TAG_SZ + - MAX_LENGTH_SZ; + MAX_LENGTH_SZ + 512; + printf("new expected size = %d\n", pkcs7->stream->expected); if (pkcs7->stream->length > 0 && pkcs7->stream->length < pkcs7->stream->expected) { return WC_PKCS7_WANT_READ_E; @@ -10167,16 +10320,20 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, } #endif /* !NO_PKCS7_STREAM */ +printf("flag 1\n"); if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) { +printf("flag 1.2\n"); /* remove IssuerAndSerialNumber */ if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) return ASN_PARSE_E; +printf("flag 1.3\n"); if (GetNameHash_ex(pkiMsg, idx, issuerHash, (int)pkiMsgSz, pkcs7->publicKeyOID) < 0) return ASN_PARSE_E; +printf("flag 1.4\n"); /* if we found correct recipient, issuer hashes will match */ if (XMEMCMP(issuerHash, pkcs7->issuerHash, (word32)keyIdSize) == 0) { @@ -10197,6 +10354,7 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, return ASN_PARSE_E; } +printf("flag 1.5\n"); mp_clear(serialNum); #ifdef WOLFSSL_SMALL_STACK @@ -10216,6 +10374,7 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, * context specific with tag number 0 within the class. */ +printf("flag 1.2\n"); if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) return ASN_PARSE_E; @@ -10262,20 +10421,24 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, } #endif +printf("flag 2\n"); /* read encryptedKey */ if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) return ASN_PARSE_E; +printf("flag 3\n"); if (tag != ASN_OCTET_STRING) return ASN_PARSE_E; if (GetLength(pkiMsg, idx, &encryptedKeySz, pkiMsgSz) < 0) { return ASN_PARSE_E; } +printf("flag 4\n"); if (encryptedKeySz > MAX_ENCRYPTED_KEY_SZ) { return BUFFER_E; } +printf("flag 5\n"); #ifndef NO_PKCS7_STREAM if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) { break; @@ -11754,7 +11917,7 @@ static int wc_PKCS7_DecryptRecipientInfos(wc_PKCS7* pkcs7, byte* in, /* when looking for next recipient, use first sequence and version to * indicate there is another, if not, move on */ - while(*recipFound == 0) { + while (*recipFound == 0) { /* remove RecipientInfo, if we don't have a SEQUENCE, back up idx to * last good saved one */ @@ -11946,7 +12109,6 @@ static int wc_PKCS7_ParseToRecipientInfoSet(wc_PKCS7* pkcs7, byte* in, switch (pkcs7->state) { case WC_PKCS7_INFOSET_START: - case WC_PKCS7_INFOSET_BER: case WC_PKCS7_INFOSET_STAGE1: case WC_PKCS7_INFOSET_STAGE2: case WC_PKCS7_INFOSET_END: @@ -11965,6 +12127,7 @@ static int wc_PKCS7_ParseToRecipientInfoSet(wc_PKCS7* pkcs7, byte* in, return ret; } if ((ret = wc_PKCS7_SetMaxStream(pkcs7, in, inSz)) != 0) { + printf("ret of set max stream = %d\n", ret); break; } pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz; @@ -11973,46 +12136,13 @@ static int wc_PKCS7_ParseToRecipientInfoSet(wc_PKCS7* pkcs7, byte* in, if (ret == 0 && GetSequence_ex(pkiMsg, idx, &length, pkiMsgSz, NO_USER_CHECK) < 0) { +printf("ret of getsequence = %d\n", ret); ret = ASN_PARSE_E; } if (ret == 0 && length == 0 && pkiMsg[(*idx)-1] == 0x80) { #ifdef ASN_BER_TO_DER - word32 len; - - wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_BER); - FALL_THROUGH; - - /* full buffer is needed for conversion */ - case WC_PKCS7_INFOSET_BER: - #ifndef NO_PKCS7_STREAM - if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, - pkcs7->stream->maxLen - pkcs7->stream->length, - &pkiMsg, idx)) != 0) { - return ret; - } - pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: - inSz; - #endif - - len = 0; - - ret = wc_BerToDer(pkiMsg, pkiMsgSz, NULL, &len); - if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) - return ret; - pkcs7->der = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - if (pkcs7->der == NULL) - return MEMORY_E; - ret = wc_BerToDer(pkiMsg, pkiMsgSz, pkcs7->der, &len); - if (ret < 0) - return ret; - - pkiMsg = in = pkcs7->der; - pkiMsgSz = pkcs7->derSz = inSz = len; - *idx = 0; - - if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) - return ASN_PARSE_E; + pkcs7->indefDepth++; #else return BER_INDEF_E; #endif @@ -12141,10 +12271,12 @@ static int wc_PKCS7_ParseToRecipientInfoSet(wc_PKCS7* pkcs7, byte* in, NO_USER_CHECK) < 0) ret = ASN_PARSE_E; +printf("Length of recipient inof set = %d\n", length); if (ret < 0) break; #ifndef NO_PKCS7_STREAM + pkcs7->stream->expected = length; if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) { break; } @@ -12181,6 +12313,7 @@ WOLFSSL_API int wc_PKCS7_SetKey(wc_PKCS7* pkcs7, byte* key, word32 keySz) } +#if 0 /* append data to encrypted content cache in PKCS7 structure * return 0 on success, negative on error */ static int PKCS7_CacheEncryptedContent(wc_PKCS7* pkcs7, byte* in, word32 inSz) @@ -12214,6 +12347,7 @@ static int PKCS7_CacheEncryptedContent(wc_PKCS7* pkcs7, byte* in, word32 inSz) return 0; } +#endif /* unwrap and decrypt PKCS#7 envelopedData object, return decoded size */ @@ -12248,8 +12382,10 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, if (pkcs7 == NULL) return BAD_FUNC_ARG; - if (pkiMsg == NULL || pkiMsgSz == 0 || - output == NULL || outputSz == 0) + if (pkiMsg == NULL || pkiMsgSz == 0) + return BAD_FUNC_ARG; + + if (pkcs7->streamOutCb == NULL && (output == NULL || outputSz == 0)) return BAD_FUNC_ARG; #ifndef NO_PKCS7_STREAM @@ -12264,7 +12400,6 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, switch (pkcs7->state) { case WC_PKCS7_START: case WC_PKCS7_INFOSET_START: - case WC_PKCS7_INFOSET_BER: case WC_PKCS7_INFOSET_STAGE1: case WC_PKCS7_INFOSET_STAGE2: case WC_PKCS7_INFOSET_END: @@ -12274,17 +12409,6 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, break; } - #ifdef ASN_BER_TO_DER - /* check if content was BER and has been converted to DER */ - if (pkcs7->derSz > 0) { - pkiMsg = in = pkcs7->der; - inSz = pkcs7->derSz; - #ifdef NO_PKCS7_STREAM - pkiMsgSz = pkcs7->derSz; - #endif - } - #endif - decryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap, DYNAMIC_TYPE_PKCS7); if (decryptedKey == NULL) @@ -12338,10 +12462,14 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, case WC_PKCS7_ENV_3: #ifndef NO_PKCS7_STREAM - if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ + - MAX_VERSION_SZ + ASN_TAG_SZ + + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ + + MAX_OID_SZ + MAX_ALGO_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) { + //if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ + + // MAX_VERSION_SZ + ASN_TAG_SZ + + // MAX_LENGTH_SZ, &pkiMsg, &idx)) + // != 0) { return ret; } pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz; @@ -12355,11 +12483,13 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, ret = ASN_PARSE_E; } +printf("-1 ret = %d\n", ret); if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) { ret = ASN_PARSE_E; } +printf("-2 ret = %d\n", ret); if (ret == 0) { pkcs7->contentOID = (int)contentType; } @@ -12369,6 +12499,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, ret = ASN_PARSE_E; } +printf("-3 ret = %d\n", ret); blockKeySz = wc_PKCS7_GetOIDKeySize((int)encOID); if (ret == 0 && blockKeySz < 0) { ret = blockKeySz; @@ -12384,20 +12515,24 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, ret = ASN_PARSE_E; } +printf("-4 ret = %d\n", ret); if (ret == 0 && tag != ASN_OCTET_STRING) { ret = ASN_PARSE_E; } +printf("-5 ret = %d\n", ret); if (ret == 0 && GetLength_ex(pkiMsg, &idx, &length, pkiMsgSz, NO_USER_CHECK) < 0) { ret = ASN_PARSE_E; } +printf("-6 ret = %d\n", ret); if (ret == 0 && length != expBlockSz) { WOLFSSL_MSG("Incorrect IV length, must be of content alg block size"); ret = ASN_PARSE_E; } +printf("-7 ret = %d\n", ret); if (ret != 0) break; #ifndef NO_PKCS7_STREAM @@ -12449,9 +12584,12 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, } idx++; - if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentTotalSz, - pkiMsgSz) <= 0) { - ret = ASN_PARSE_E; + if (ret == 0) { + ret = GetLength_ex(pkiMsg, &idx, &encryptedContentTotalSz, + pkiMsgSz, 0); + if (ret < 0) { + ret = ASN_PARSE_E; + } } if (ret != 0) @@ -12462,6 +12600,10 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, break; } pkcs7->stream->expected = (word32)encryptedContentTotalSz; + if (explicitOctet) { + pkcs7->stream->expected = MAX_OCTET_STR_SZ; + } +printf("Expecting %d bytes... \n", pkcs7->stream->expected); wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, 0); wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, explicitOctet); #endif @@ -12471,6 +12613,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, case WC_PKCS7_ENV_5: #ifndef NO_PKCS7_STREAM +printf("inSz = %d pkcs7->length = %d, idx = %d expected = %d\n", inSz, pkcs7->stream->length, idx, pkcs7->stream->expected); if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { return ret; @@ -12480,6 +12623,9 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, tmpIv = pkcs7->stream->tmpIv; encryptedContentTotalSz = (int)pkcs7->stream->expected; + pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz; + + printf("pkcs7->length = %d pkimsgSz = %d\n", pkcs7->stream->length, pkiMsgSz); /* restore decrypted key */ decryptedKey = pkcs7->stream->aad; decryptedKeySz = pkcs7->stream->aadSz; @@ -12491,47 +12637,168 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, if (explicitOctet) { /* encrypted content may be fragmented into multiple * consecutive OCTET STRINGs, if so loop through - * collecting and caching encrypted content bytes */ - localIdx = idx; - while (idx < (localIdx + (word32)encryptedContentTotalSz)) { + * decrypting and outputing or caching contents until the indef + * ending tag is found */ - if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) { - ret = ASN_PARSE_E; + if (pkcs7->decryptionCb == NULL) { + + ret = wc_PKCS7_DecryptContentInit(pkcs7, encOID, + decryptedKey, blockKeySz, tmpIv, expBlockSz, + pkcs7->devId, pkcs7->heap); + } + + while (1) { + if (pkiMsgSz <= localIdx) { + /* ran out of data to parse */ +printf("ran out of pkimsgsz, trying to read more from in\n"); + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, + pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { + printf("error %d reading more\n", ret); + break; + } + } + + localIdx = idx; + printf("getting asn tag, idx = %d , pkiMsgSz = %d\n", idx, pkiMsgSz); + if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) < 0) { + if (localIdx >= pkiMsgSz) { + /* ran out of data to parse */ + ret = WC_PKCS7_WANT_READ_E; + } + else { + ret = ASN_PARSE_E; + } } if (ret == 0 && (tag != ASN_OCTET_STRING)) { ret = ASN_PARSE_E; } - if (ret == 0 && GetLength(pkiMsg, &idx, - &encryptedContentSz, pkiMsgSz) <= 0) { - ret = ASN_PARSE_E; + printf("ret [%d] getting length, idx = %d , pkiMsgSz = %d %02X %02X\n", ret, idx, pkiMsgSz, pkiMsg[localIdx], pkiMsg[localIdx+1]); + if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, + &encryptedContentSz, pkiMsgSz, 0) <= 0) { + if (localIdx + MAX_LENGTH_SZ >= pkiMsgSz) { + /* ran out of data to parse */ + ret = WC_PKCS7_WANT_READ_E; + } + else { + ret = ASN_PARSE_E; + } + } + if (ret == 0) { + pkcs7->stream->expected = encryptedContentSz + (localIdx-idx); + } + +printf("Length of octet found is %d, pkiMsgSz = %d idx = %d\n", encryptedContentSz, pkiMsgSz, idx); +{ + int z; + for (z = 0; z < 6; z++) printf("%02X", pkiMsg[localIdx + z]); + printf("\n"); +} + if (ret == 0 && + pkcs7->cachedEncryptedContentSz < + (word32)encryptedContentSz) { + if (pkcs7->cachedEncryptedContent != NULL) { + XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap, + DYNAMIC_TYPE_PKCS7); + } + pkcs7->cachedEncryptedContent = (byte*)XMALLOC( + encryptedContentSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + if (pkcs7->cachedEncryptedContent == NULL) { + ret = MEMORY_E; + } + } + pkcs7->cachedEncryptedContentSz = encryptedContentSz; + + /* sanity check that the buffer has all of the data */ + if (ret == 0 && (localIdx + encryptedContentSz) > pkiMsgSz) { + ret = WC_PKCS7_WANT_READ_E; + + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, + pkcs7->stream->expected, &pkiMsg, &localIdx)) != 0) { + return ret; + } + } +printf("caching?..\n"); + + /* Use callback for decryption still, if set */ + if (ret == 0 && pkcs7->decryptionCb != NULL) { + ret = pkcs7->decryptionCb(pkcs7, encOID, tmpIv, + expBlockSz, NULL, 0, NULL, 0, &pkiMsg[localIdx], + encryptedContentSz, pkcs7->cachedEncryptedContent, + pkcs7->decryptionCtx); } if (ret == 0) { - ret = PKCS7_CacheEncryptedContent(pkcs7, &pkiMsg[idx], - (word32)encryptedContentSz); + ret = wc_PKCS7_DecryptContentEx(pkcs7, encOID, + tmpIv, expBlockSz, NULL, 0, NULL, 0, &pkiMsg[localIdx], + encryptedContentSz, pkcs7->cachedEncryptedContent); } if (ret != 0) { + if (ret == -270) + wc_PKCS7_StreamEndCase(pkcs7, &localIdx, &idx); break; } /* advance idx past encrypted content */ - idx += (word32)encryptedContentSz; + localIdx += (word32)encryptedContentSz; + + if (localIdx + ASN_INDEF_END_SZ < pkiMsgSz) { + if (pkiMsg[localIdx] == ASN_EOC && + pkiMsg[localIdx+1] == ASN_EOC) { + /* found the end of encrypted content */ +printf("found end of BER indef, ret = %d\n", ret); + localIdx += ASN_INDEF_END_SZ; + break; + } + } + + pkcs7->stream->expected = MAX_OCTET_STR_SZ; + if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &localIdx, &localIdx)) != 0) { + break; + } +printf("consumed and decrypted some, localIdx = %d, idx = %d\n", localIdx, idx); + + + /* save last decrypted string to handle padding (this output + * flush happens outside of the while loop in the case that + * the indef end was found) */ + if (ret == 0) { + if (pkcs7->streamOutCb) { +printf("flush out decrypted data\n"); + ret = pkcs7->streamOutCb(pkcs7, + pkcs7->cachedEncryptedContent, + encryptedContentSz, pkcs7->streamCtx); + } + else { + //@TODO copy over into output buffer, we need an + // index/ofset into the buffer + } + } + + idx = localIdx; } if (ret != 0) { break; } - + wc_PKCS7_DecryptContentFree(pkcs7, encOID, pkcs7->heap); } else { - /* cache encrypted content, no OCTET STRING */ - ret = PKCS7_CacheEncryptedContent(pkcs7, &pkiMsg[idx], - (word32)encryptedContentTotalSz); + pkcs7->cachedEncryptedContent = XMALLOC(encryptedContentTotalSz, + pkcs7->heap, DYNAMIC_TYPE_PKCS7); + pkcs7->cachedEncryptedContentSz = encryptedContentTotalSz; + + /* decrypt encryptedContent */ + ret = wc_PKCS7_DecryptContent(pkcs7, (int)encOID, decryptedKey, + blockKeySz, tmpIv, expBlockSz, NULL, 0, NULL, 0, + &pkiMsg[idx], encryptedContentTotalSz, + pkcs7->cachedEncryptedContent, + pkcs7->devId, pkcs7->heap); if (ret != 0) { break; } + idx += (word32)encryptedContentTotalSz; } @@ -12539,25 +12806,34 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, encryptedContent = pkcs7->cachedEncryptedContent; encryptedContentSz = (int)pkcs7->cachedEncryptedContentSz; - /* decrypt encryptedContent */ - ret = wc_PKCS7_DecryptContent(pkcs7, (int)encOID, decryptedKey, - blockKeySz, tmpIv, expBlockSz, NULL, 0, NULL, 0, - encryptedContent, encryptedContentSz, encryptedContent, - pkcs7->devId, pkcs7->heap); - if (ret != 0) { - break; - } - +{ + word32 z; + printf("last decryted block: "); + for (z = 0; z < pkcs7->cachedEncryptedContentSz; z++) printf("%02X", pkcs7->cachedEncryptedContent[z]); + printf("\n"); +} padLen = encryptedContent[encryptedContentSz-1]; +printf("padLen = %d\n", padLen); /* copy plaintext to output */ - if (padLen > encryptedContentSz || - (word32)(encryptedContentSz - padLen) > outputSz) { + if (padLen > encryptedContentSz) { ret = BUFFER_E; break; } - XMEMCPY(output, encryptedContent, + + if (pkcs7->streamOutCb) { + ret = pkcs7->streamOutCb(pkcs7, encryptedContent, + encryptedContentSz - padLen, pkcs7->streamCtx); + printf("ret of streamOutCb = %d\n", ret); + } + else { + if ((word32)(encryptedContentSz - padLen) > outputSz) { + ret = BUFFER_E; + break; + } + XMEMCPY(output, encryptedContent, (word32)encryptedContentSz - padLen); + } /* free memory, zero out keys */ ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ); @@ -12570,6 +12846,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, } ret = encryptedContentSz - padLen; + printf("ret at 12836 = %d\n", ret); #ifndef NO_PKCS7_STREAM pkcs7->stream->aad = NULL; pkcs7->stream->aadSz = 0; diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 4bb57d4f6..8dc024f21 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -243,6 +243,7 @@ typedef int (*CallbackRsaSignRawDigest)(wc_PKCS7* pkcs7, byte* digest, int devId, int hashOID); #endif + /* Public Structure Warning: * Existing members must not be changed to maintain backwards compatibility! */ @@ -258,6 +259,7 @@ struct wc_PKCS7 { #ifdef ASN_BER_TO_DER byte* der; /* DER encoded version of message */ word32 derSz; + byte indefDepth; CallbackGetContent getContentCb; CallbackStreamOut streamOutCb; void* streamCtx; /* passed to getcontentCb and streamOutCb */ @@ -372,6 +374,19 @@ struct wc_PKCS7 { byte* customSKID; word16 customSKIDSz; + +#if !defined(NO_DES3) || !defined(NO_AES) + union { + #ifndef NO_AES + Aes* aes; + #endif + #ifndef NO_DES3 + Des* des; + Des3* des3; + #endif + } decryptKey; +#endif + /* !! NEW DATA MEMBERS MUST BE ADDED AT END !! */ };