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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 > 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 !! */ };