diff --git a/src/internal.c b/src/internal.c index 1c9e703a6c8..fb607c14eae 100644 --- a/src/internal.c +++ b/src/internal.c @@ -26449,7 +26449,7 @@ int SendCertificateStatus(WOLFSSL* ssl) WC_FREE_VAR_EX(cert, ssl->heap, DYNAMIC_TYPE_DCERT); } else { - while (ret == 0 && + while (ret == 0 && i < MAX_CHAIN_DEPTH && NULL != (request = ssl->ctx->chainOcspRequest[i])) { if ((i + 1) >= MAX_CERT_EXTENSIONS) { ret = MAX_CERT_EXTENSIONS_ERR; diff --git a/src/ssl_api_cert.c b/src/ssl_api_cert.c index 15fbe1b40c3..dbb95d5f563 100644 --- a/src/ssl_api_cert.c +++ b/src/ssl_api_cert.c @@ -1991,7 +1991,7 @@ int wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN* chain) * @param [in] chain Certificate chain object. * @param [in] idx Index of the certificate in the chain. * @return Length of the DER certificate in bytes on success. - * @return 0 when chain is NULL. + * @return 0 when chain is NULL or idx is out of range. */ int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx) { @@ -1999,7 +1999,7 @@ int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx) WOLFSSL_ENTER("wolfSSL_get_chain_length"); - if (chain != NULL) { + if ((chain != NULL) && (idx >= 0) && (idx < chain->count)) { /* DER length of the certificate stored at the given index. */ length = chain->certs[idx].length; } @@ -2013,7 +2013,7 @@ int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx) * @param [in] chain Certificate chain object. * @param [in] idx Index of the certificate in the chain. * @return Buffer holding the DER certificate on success. - * @return 0 when chain is NULL. + * @return 0 when chain is NULL or idx is out of range. */ byte* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN* chain, int idx) { @@ -2021,7 +2021,7 @@ byte* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN* chain, int idx) WOLFSSL_ENTER("wolfSSL_get_chain_cert"); - if (chain != NULL) { + if ((chain != NULL) && (idx >= 0) && (idx < chain->count)) { /* DER buffer of the certificate stored at the given index. */ cert = chain->certs[idx].buffer; } @@ -2049,7 +2049,7 @@ WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx) WOLFSSL_ENTER("wolfSSL_get_chain_X509"); - if ((chain != NULL) && (idx < MAX_CHAIN_DEPTH)) { + if ((chain != NULL) && (idx >= 0) && (idx < chain->count)) { x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL, DYNAMIC_TYPE_X509); if (x509 == NULL) { diff --git a/src/ssl_load.c b/src/ssl_load.c index 9831518005e..5e884525563 100644 --- a/src/ssl_load.c +++ b/src/ssl_load.c @@ -329,6 +329,13 @@ static int ProcessUserChain(WOLFSSL_CTX* ctx, WOLFSSL* ssl, ret = DataToDerBuffer(buff + consumed, (word32)(sz - consumed), format, type, info, heap, &part, NULL); if (ret == 0) { + /* Enforce maximum chain depth once a real cert is parsed. */ + if (cnt >= MAX_CHAIN_DEPTH) { + WOLFSSL_MSG("Chain depth limit reached"); + FreeDer(&part); + ret = MAX_CHAIN_ERROR; + break; + } /* Process the user certificate. */ ret = ProcessUserCert(ctx->cm, &part, type, verify, chain.buffer, &idx, (word32)maxSz); diff --git a/src/tls.c b/src/tls.c index 2fa6abd6117..da848cedcaf 100644 --- a/src/tls.c +++ b/src/tls.c @@ -2849,6 +2849,9 @@ int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, ato16(clientHello + offset, &listLen); offset += OPAQUE16_LEN; + if (listLen != extLen - OPAQUE16_LEN) + return BUFFER_ERROR; + if (helloSz < offset + listLen) return BUFFER_ERROR; @@ -2859,6 +2862,9 @@ int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz, ato16(clientHello + offset, &sniLen); offset += OPAQUE16_LEN; + if (sniLen > listLen - (ENUM_LEN + OPAQUE16_LEN)) + return BUFFER_ERROR; + if (helloSz < offset + sniLen) return BUFFER_ERROR; @@ -3434,7 +3440,7 @@ static void TLSX_CSR_Free(CertificateStatusRequest* csr, void* heap) switch (csr->status_type) { case WOLFSSL_CSR_OCSP: - for (i = 0; i <= csr->requests; i++) { + for (i = 0; i < csr->requests; i++) { FreeOcspRequest(&csr->request.ocsp[i]); } break; diff --git a/src/tls13.c b/src/tls13.c index d2e9888a130..aadb2b30a09 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -9616,6 +9616,10 @@ static int SendTls13Certificate(WOLFSSL* ssl) } /* Certificate Data */ certSz = ssl->buffers.certificate->length; + if (ssl->buffers.certChainCnt > MAX_CHAIN_DEPTH) { + WOLFSSL_MSG("Certificate chain count exceeds maximum depth"); + return MAX_CHAIN_ERROR; + } /* Cert Req Ctx Len | Cert Req Ctx | Cert List Len | Cert Data Len */ headerSz = OPAQUE8_LEN + certReqCtxLen + CERT_HEADER_SZ + CERT_HEADER_SZ; diff --git a/tests/api.c b/tests/api.c index bb20aedf0aa..69d95d18ca3 100644 --- a/tests/api.c +++ b/tests/api.c @@ -3856,6 +3856,108 @@ static int test_wolfSSL_CTX_use_certificate_chain_buffer_format(void) return EXPECT_RESULT(); } +/* wolfSSL_get_chain_{length,cert,X509} must reject out-of-range idx. */ +static int test_wolfSSL_get_chain_idx_bounds(void) +{ + EXPECT_DECLS; +#if defined(SESSION_CERTS) && \ + defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) + struct test_memio_ctx test_ctx; + WOLFSSL_CTX* ctx_c = NULL; + WOLFSSL_CTX* ctx_s = NULL; + WOLFSSL* ssl_c = NULL; + WOLFSSL* ssl_s = NULL; + WOLFSSL_X509_CHAIN* chain = NULL; + int count = 0; + + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s, + wolfTLS_client_method, wolfTLS_server_method), 0); + ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0); + + ExpectNotNull(chain = wolfSSL_get_peer_chain(ssl_c)); + ExpectIntGT(count = wolfSSL_get_chain_count(chain), 0); + + ExpectIntEQ(wolfSSL_get_chain_length(chain, -1), 0); + ExpectIntEQ(wolfSSL_get_chain_length(chain, count), 0); + ExpectIntEQ(wolfSSL_get_chain_length(chain, MAX_CHAIN_DEPTH), 0); + ExpectNull(wolfSSL_get_chain_cert(chain, -1)); + ExpectNull(wolfSSL_get_chain_cert(chain, count)); + ExpectNull(wolfSSL_get_chain_cert(chain, MAX_CHAIN_DEPTH)); +#ifdef OPENSSL_EXTRA + { + WOLFSSL_X509* x = NULL; + ExpectNull(x = wolfSSL_get_chain_X509(chain, -1)); + if (x != NULL) { wolfSSL_X509_free(x); x = NULL; } + ExpectNull(x = wolfSSL_get_chain_X509(chain, count)); + if (x != NULL) { wolfSSL_X509_free(x); x = NULL; } + ExpectNull(x = wolfSSL_get_chain_X509(chain, MAX_CHAIN_DEPTH)); + if (x != NULL) { wolfSSL_X509_free(x); x = NULL; } + } +#endif + + wolfSSL_free(ssl_c); + wolfSSL_free(ssl_s); + wolfSSL_CTX_free(ctx_c); + wolfSSL_CTX_free(ctx_s); +#endif + return EXPECT_RESULT(); +} + +/* Chain-depth boundary: exactly MAX_CHAIN_DEPTH chain certs (plus trailing data + * that forces one more parse pass) must load; one more cert must be rejected. + * cliCertFile is single-cert, so copy 0 is the leaf and N copies => N-1 chain. */ +static int test_wolfSSL_CTX_use_certificate_chain_buffer_max_depth(void) +{ + EXPECT_DECLS; +#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \ + !defined(NO_WOLFSSL_CLIENT) && !defined(NO_RSA) && \ + defined(WOLFSSL_PEM_TO_DER) + WOLFSSL_CTX* ctx = NULL; + unsigned char* one = NULL; + unsigned char* buf = NULL; + size_t oneLen = 0; + const char* tail = "# trailing comment\n"; + size_t tailLen = XSTRLEN(tail); + /* +1 copy for the leaf yields exactly MAX_CHAIN_DEPTH chain certs. */ + const int atMax = MAX_CHAIN_DEPTH + 1; + int i; + + ExpectIntEQ(load_file(cliCertFile, &one, &oneLen), 0); + + /* Exactly MAX_CHAIN_DEPTH chain certs + trailing data: loads. */ + ExpectNotNull(buf = (unsigned char*)XMALLOC( + oneLen * (size_t)atMax + tailLen, NULL, DYNAMIC_TYPE_TMP_BUFFER)); + for (i = 0; EXPECT_SUCCESS() && i < atMax; i++) + XMEMCPY(buf + (size_t)i * oneLen, one, oneLen); + if (buf != NULL) + XMEMCPY(buf + (size_t)atMax * oneLen, tail, tailLen); + ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); + ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer(ctx, buf, + (long)(oneLen * (size_t)atMax + tailLen)), WOLFSSL_SUCCESS); + wolfSSL_CTX_free(ctx); + ctx = NULL; + if (buf != NULL) + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + buf = NULL; + + /* One more chain cert: rejected. */ + ExpectNotNull(buf = (unsigned char*)XMALLOC(oneLen * (size_t)(atMax + 1), + NULL, DYNAMIC_TYPE_TMP_BUFFER)); + for (i = 0; EXPECT_SUCCESS() && i < atMax + 1; i++) + XMEMCPY(buf + (size_t)i * oneLen, one, oneLen); + ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); + ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer(ctx, buf, + (long)(oneLen * (size_t)(atMax + 1))), WC_NO_ERR_TRACE(MAX_CHAIN_ERROR)); + wolfSSL_CTX_free(ctx); + if (buf != NULL) + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (one != NULL) + XFREE(one, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return EXPECT_RESULT(); +} + static int test_wolfSSL_CTX_use_certificate_chain_file_format(void) { EXPECT_DECLS; @@ -35060,6 +35162,8 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_CTX_add1_chain_cert), TEST_DECL(test_wolfSSL_add_to_chain_overflow), TEST_DECL(test_wolfSSL_CTX_use_certificate_chain_buffer_format), + TEST_DECL(test_wolfSSL_CTX_use_certificate_chain_buffer_max_depth), + TEST_DECL(test_wolfSSL_get_chain_idx_bounds), TEST_DECL(test_wolfSSL_CTX_use_certificate_chain_file_format), TEST_DECL(test_wolfSSL_use_certificate_chain_file), TEST_DECL(test_wolfSSL_CTX_trust_peer_cert), diff --git a/tests/api/test_dtls.h b/tests/api/test_dtls.h index 4523cdef1e9..234f632f888 100644 --- a/tests/api/test_dtls.h +++ b/tests/api/test_dtls.h @@ -160,7 +160,6 @@ int test_WOLFSSL_dtls_version_alert(void); TEST_DECL_GROUP("dtls", test_dtls12_export_import_etm), \ TEST_DECL_GROUP("dtls", test_dtls13_min_rtx_interval), \ TEST_DECL_GROUP("dtls", test_dtls13_no_session_id_echo), \ - TEST_DECL_GROUP("dtls", test_dtls13_oversized_cert_chain), \ TEST_DECL_GROUP("dtls", test_dtls_set_session_min_downgrade), \ TEST_DECL_GROUP("dtls", test_wolfSSL_dtls_create_free_peer), \ TEST_DECL_GROUP("dtls", test_wolfSSL_dtls_get0_peer), \ diff --git a/tests/api/test_dtls13.c b/tests/api/test_dtls13.c index b74740eb4c7..1716fd439dc 100644 --- a/tests/api/test_dtls13.c +++ b/tests/api/test_dtls13.c @@ -1779,97 +1779,3 @@ int test_dtls13_5_9_0_compat(void) #endif return EXPECT_RESULT(); } - -/*-- oversized_cert_chain (test_dtls.c lines 3174,3265) ---*/ -int test_dtls13_oversized_cert_chain(void) -{ - EXPECT_DECLS; -#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) \ - && !defined(NO_FILESYSTEM) && !defined(NO_RSA) - WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL; - WOLFSSL *ssl_c = NULL, *ssl_s = NULL; - struct test_memio_ctx test_ctx; - XFILE f = XBADFILE; - long sz = 0; - byte *cert = NULL; - byte *chain = NULL; - int copies, off, i; - - XMEMSET(&test_ctx, 0, sizeof(test_ctx)); - - /* Read server cert */ - f = XFOPEN(svrCertFile, "rb"); - ExpectTrue(f != XBADFILE); - if (EXPECT_SUCCESS()) { - (void)XFSEEK(f, 0, XSEEK_END); - sz = XFTELL(f); - (void)XFSEEK(f, 0, XSEEK_SET); - } - ExpectTrue(sz > 0); - cert = (byte*)XMALLOC((size_t)(sz + 1), NULL, DYNAMIC_TYPE_TMP_BUFFER); - ExpectNotNull(cert); - if (EXPECT_SUCCESS()) - ExpectIntEQ((int)XFREAD(cert, 1, (size_t)sz, f), (int)sz); - if (f != XBADFILE) - XFCLOSE(f); - - /* Build an oversized chain by duplicating the cert */ - copies = EXPECT_SUCCESS() ? (int)(70000 / sz) + 2 : 0; - chain = (byte*)XMALLOC((size_t)(sz * copies + 1), NULL, - DYNAMIC_TYPE_TMP_BUFFER); - ExpectNotNull(chain); - off = 0; - if (EXPECT_SUCCESS()) { - for (i = 0; i < copies; i++) { - XMEMCPY(chain + off, cert, (size_t)sz); - off += (int)sz; - } - } - - /* Server context: load the oversized chain */ - ExpectNotNull(ctx_s = wolfSSL_CTX_new(wolfDTLSv1_3_server_method())); - ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer(ctx_s, - chain, (long)off), WOLFSSL_SUCCESS); - ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx_s, svrKeyFile, - WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS); - if (EXPECT_SUCCESS()) { - wolfSSL_SetIORecv(ctx_s, test_memio_read_cb); - wolfSSL_SetIOSend(ctx_s, test_memio_write_cb); - } - - /* Client context: no verification (chain certs are duplicates) */ - ExpectNotNull(ctx_c = wolfSSL_CTX_new(wolfDTLSv1_3_client_method())); - if (EXPECT_SUCCESS()) { - wolfSSL_CTX_set_verify(ctx_c, WOLFSSL_VERIFY_NONE, NULL); - wolfSSL_SetIORecv(ctx_c, test_memio_read_cb); - wolfSSL_SetIOSend(ctx_c, test_memio_write_cb); - } - - ExpectNotNull(ssl_s = wolfSSL_new(ctx_s)); - if (EXPECT_SUCCESS()) { - wolfSSL_SetIOWriteCtx(ssl_s, &test_ctx); - wolfSSL_SetIOReadCtx(ssl_s, &test_ctx); - } - - ExpectNotNull(ssl_c = wolfSSL_new(ctx_c)); - if (EXPECT_SUCCESS()) { - wolfSSL_SetIOWriteCtx(ssl_c, &test_ctx); - wolfSSL_SetIOReadCtx(ssl_c, &test_ctx); - } - - /* Handshake must not crash. If SendTls13Certificate mishandles the - * oversized chain this will trigger a wild pointer dereference or stack - * overflow resulting with the test failing. - * The correct behaviour either returns BUFFER_E or succeeds - * if the build config truncated the chain during loading. */ - (void)test_memio_do_handshake(ssl_c, ssl_s, 10, NULL); - - wolfSSL_free(ssl_c); - wolfSSL_free(ssl_s); - wolfSSL_CTX_free(ctx_c); - wolfSSL_CTX_free(ctx_s); - XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(chain, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return EXPECT_RESULT(); -} diff --git a/tests/api/test_dtls13.h b/tests/api/test_dtls13.h index 7b48a35b78e..6b82a50483a 100644 --- a/tests/api/test_dtls13.h +++ b/tests/api/test_dtls13.h @@ -52,7 +52,6 @@ int test_dtls_srtp(void); int test_dtls13_min_rtx_interval(void); int test_dtls13_no_session_id_echo(void); int test_dtls13_5_9_0_compat(void); -int test_dtls13_oversized_cert_chain(void); #define TEST_DTLS13_DECLS \ TEST_DECL_GROUP("dtls13", test_dtls13_bad_epoch_ch), \ @@ -75,7 +74,6 @@ int test_dtls13_oversized_cert_chain(void); TEST_DECL_GROUP("dtls13", test_dtls_srtp), \ TEST_DECL_GROUP("dtls13", test_dtls13_min_rtx_interval), \ TEST_DECL_GROUP("dtls13", test_dtls13_no_session_id_echo), \ - TEST_DECL_GROUP("dtls13", test_dtls13_5_9_0_compat), \ - TEST_DECL_GROUP("dtls13", test_dtls13_oversized_cert_chain) + TEST_DECL_GROUP("dtls13", test_dtls13_5_9_0_compat) #endif /* TESTS_API_DTLS13_H */ diff --git a/tests/api/test_pkcs7.c b/tests/api/test_pkcs7.c index 84ab3c3bade..eaa20d365d5 100644 --- a/tests/api/test_pkcs7.c +++ b/tests/api/test_pkcs7.c @@ -2873,6 +2873,66 @@ int test_wc_PKCS7_DecodeEnvelopedData_forgedRecipientSetLen(void) } /* END test_wc_PKCS7_DecodeEnvelopedData_forgedRecipientSetLen() */ +/* Decoding an AuthEnvelopedData blob whose encryptedContent or authTag + * is truncated must return BUFFER_E rather than reading past pkiMsg. */ +int test_wc_PKCS7_DecodeAuthEnvelopedData_truncated(void) +{ + EXPECT_DECLS; +#if defined(HAVE_PKCS7) && defined(HAVE_AESGCM) && !defined(NO_RSA) && \ + !defined(NO_AES) && defined(WOLFSSL_AES_128) && defined(NO_PKCS7_STREAM) + PKCS7* pkcs7 = NULL; + byte enveloped[2048]; + byte decoded[256]; + byte data[] = "truncated authEnvelopedData test"; + int encSz = 0; + + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); + ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (byte*)client_cert_der_2048, + sizeof_client_cert_der_2048), 0); + if (pkcs7 != NULL) { + pkcs7->content = data; + pkcs7->contentSz = (word32)sizeof(data); + pkcs7->contentOID = DATA; + pkcs7->encryptOID = AES128GCMb; + } + /* >32 so the encSz-32 / encSz-1 truncations below can't underflow */ + ExpectIntGT(encSz = wc_PKCS7_EncodeAuthEnvelopedData(pkcs7, enveloped, + sizeof(enveloped)), 32); + wc_PKCS7_Free(pkcs7); + pkcs7 = NULL; + + /* Truncate inside encryptedContent (encryptedContentSz check). */ + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); + ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (byte*)client_cert_der_2048, + sizeof_client_cert_der_2048), 0); + if (pkcs7 != NULL) { + pkcs7->privateKey = (byte*)client_key_der_2048; + pkcs7->privateKeySz = sizeof_client_key_der_2048; + } + ExpectIntEQ(wc_PKCS7_DecodeAuthEnvelopedData(pkcs7, enveloped, + (word32)encSz - 32, decoded, sizeof(decoded)), + WC_NO_ERR_TRACE(BUFFER_E)); + wc_PKCS7_Free(pkcs7); + pkcs7 = NULL; + + /* Truncate one byte off the auth tag (authTagSz check). */ + ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId)); + ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (byte*)client_cert_der_2048, + sizeof_client_cert_der_2048), 0); + if (pkcs7 != NULL) { + pkcs7->privateKey = (byte*)client_key_der_2048; + pkcs7->privateKeySz = sizeof_client_key_der_2048; + } + ExpectIntEQ(wc_PKCS7_DecodeAuthEnvelopedData(pkcs7, enveloped, + (word32)encSz - 1, decoded, sizeof(decoded)), + WC_NO_ERR_TRACE(BUFFER_E)); + + wc_PKCS7_Free(pkcs7); +#endif + return EXPECT_RESULT(); +} /* END test_wc_PKCS7_DecodeAuthEnvelopedData_truncated() */ + + /* * Testing wc_PKCS7_DecodeEnvelopedData with streaming */ diff --git a/tests/api/test_pkcs7.h b/tests/api/test_pkcs7.h index 01ecb903dd1..bf25365cc7b 100644 --- a/tests/api/test_pkcs7.h +++ b/tests/api/test_pkcs7.h @@ -71,6 +71,7 @@ int test_wc_PKCS7_SetOriDecryptCtx(void); int test_wc_PKCS7_DecodeCompressedData(void); int test_wc_PKCS7_DecodeEnvelopedData_multiple_recipients(void); int test_wc_PKCS7_DecodeEnvelopedData_forgedRecipientSetLen(void); +int test_wc_PKCS7_DecodeAuthEnvelopedData_truncated(void); int test_wc_PKCS7_VerifySignedData_PKCS7ContentSeq(void); int test_wc_PKCS7_VerifySignedData_IndefLenOOB(void); int test_wc_PKCS7_VerifySignedData_TruncEContentTag(void); @@ -145,7 +146,8 @@ int test_wc_PKCS7_VerifySignedData_TruncCertSetTag(void); TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_SetOriEncryptCtx), \ TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_SetOriDecryptCtx), \ TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_DecodeEnvelopedData_multiple_recipients), \ - TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_DecodeEnvelopedData_forgedRecipientSetLen) + TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_DecodeEnvelopedData_forgedRecipientSetLen), \ + TEST_DECL_GROUP("pkcs7_ed", test_wc_PKCS7_DecodeAuthEnvelopedData_truncated) #define TEST_PKCS7_SIGNED_ENCRYPTED_DATA_DECLS \ TEST_DECL_GROUP("pkcs7_sed", test_wc_PKCS7_signed_enveloped) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index b04504a0054..aaafb74259d 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -15022,6 +15022,12 @@ int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, } } + #ifdef NO_PKCS7_STREAM + if (ret == 0 && encryptedContentSz > (int)(pkiMsgSz - idx)) { + ret = BUFFER_E; + } + #endif + if (ret < 0) break; @@ -15245,6 +15251,12 @@ int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, localIdx = idx; + #ifdef NO_PKCS7_STREAM + if (ret == 0 && localIdx >= pkiMsgSz) { + ret = BUFFER_E; + } + #endif + /* Get authTag OCTET STRING */ if (ret == 0 && pkiMsg[localIdx] != ASN_OCTET_STRING) { ret = ASN_PARSE_E; @@ -15284,6 +15296,12 @@ int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, #endif idx = localIdx; + #ifdef NO_PKCS7_STREAM + if (ret == 0 && authTagSz > (word32)(pkiMsgSz - idx)) { + ret = BUFFER_E; + } + #endif + if (ret == 0 && authTagSz > (word32)sizeof(authTag)) { WOLFSSL_MSG("AuthEnvelopedData authTag too large for buffer"); ret = ASN_PARSE_E;