Harden chain depth bounds and parser input validation#10209
Conversation
9a2f68d to
3304644
Compare
|
089287c to
d84c824
Compare
|
retest this please |
Enforce MAX_CHAIN_DEPTH limits in OCSP chain processing (SendCertificateStatus, ProcessChainOCSPRequest), certificate loading (ProcessUserChain), and TLS 1.3 certificate sending (SendTls13Certificate). Add idx bounds checks to chain accessors in ssl.c. Harden SNI extension parser (TLSX_SNI_GetFromBuffer) with length checks preventing buffer overreads on malformed ClientHello. Fix off-by-one in TLSX_CSR_Free where <= should be < since csr->requests is a count, not a max index. Add remaining-buffer bounds checks to PKCS7 decoders: DecodeEnvelopedData, DecodeAuthEnvelopedData (encryptedContentSz and authTagSz), DecodeEncryptedData, SignedData null signature tag, and PwriKek_KeyUnWrap cekLen validation.
test_dtls13_oversized_cert_chain (added upstream in 1653ecd) loaded a >9-cert chain to exercise SendTls13Certificate's word16 overflow guard. This PR now rejects over-MAX_CHAIN_DEPTH chains at load in ProcessUserChain, so the chain never reaches the send path; the load-time rejection is covered by test_wolfSSL_CTX_use_certificate_chain_buffer_max_depth. The word16 send guard remains as defense-in-depth (now only reachable via large PQC chains).
d84c824 to
359fb7e
Compare
There was a problem hiding this comment.
Pull request overview
This PR hardens certificate-chain depth handling and improves parser input validation to prevent out-of-bounds access and buffer overreads, with accompanying API/regression tests.
Changes:
- Enforces
MAX_CHAIN_DEPTHin certificate chain loading/sending paths and adds index bounds checks to chain accessors. - Hardens SNI extension parsing with stricter length validation and fixes an off-by-one in OCSP CSR cleanup.
- Adds PKCS7 AuthEnvelopedData truncation regression coverage and updates API tests; removes a DTLS oversized-chain test.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
wolfcrypt/src/pkcs7.c |
Adds remaining-buffer bounds checks during AuthEnvelopedData parsing. |
src/tls.c |
Tightens SNI extension length validation; fixes OCSP CSR free-loop off-by-one. |
src/ssl.c |
Adds idx bounds checks for peer-chain accessors (length/cert/X509). |
src/ssl_load.c |
Enforces MAX_CHAIN_DEPTH during user chain parsing/loading. |
src/internal.c |
Bounds OCSP chain processing loops by MAX_CHAIN_DEPTH. |
src/tls13.c |
Rejects TLS 1.3 certificate sends when chain count exceeds MAX_CHAIN_DEPTH. |
tests/api/test_pkcs7.h |
Declares/registers new PKCS7 truncated AuthEnvelopedData test. |
tests/api/test_pkcs7.c |
Adds new truncation regression test for AuthEnvelopedData decode. |
tests/api/test_dtls.h |
Removes declaration/registration of oversized-chain DTLS 1.3 test. |
tests/api/test_dtls.c |
Removes implementation of oversized-chain DTLS 1.3 test. |
tests/api.c |
Adds tests for chain accessor idx bounds and max-depth chain buffer rejection. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
julek-wolfssl
left a comment
There was a problem hiding this comment.
Copilot has some valid points
- pkcs7.c: wrap the AuthEnvelopedData encryptedContentSz bounds check entirely in #ifdef NO_PKCS7_STREAM so the default streaming build carries no empty/no-op branch (behavior unchanged). - test_pkcs7.c: assert the encoded size is >32 so the encSz-32 and encSz-1 truncations can't underflow.
Master's test reorg (c674cec) moved test_dtls13_oversized_cert_chain into the new tests/api/test_dtls13.c. This branch removes that test, so resolve by taking master's test_dtls.{c,h} and re-applying the removal in test_dtls13.{c,h}.
Agreed, I have pushed updates to address the issues. |
|
Jenkins retest this please |
dgarske
left a comment
There was a problem hiding this comment.
Skoll Code Review
Scan type: reviewOverall recommendation: COMMENT
Findings: 4 total — 4 posted, 0 skipped
4 finding(s) posted as inline comments (see file-level comments below)
Posted findings
- [Medium] MAX_CHAIN_DEPTH check placement can reject a valid maximum-depth chain that has trailing data —
src/ssl_load.c:328-333 - [Low] Max-depth load test overshoots the limit and omits the exact-boundary success case —
tests/api.c:3866-3915 - [Info] PR description lists pkcs7.c changes that are not present in the diff —
wolfcrypt/src/pkcs7.c:14971-14975,15239-15243 - [Info] SendTls13Certificate depth guard is now defense-in-depth only and its direct test path was removed —
src/tls13.c:9523-9526
Review generated by Skoll
- ProcessUserChain: enforce MAX_CHAIN_DEPTH after a cert is parsed, so a full-depth chain followed by trailing data still loads instead of failing with MAX_CHAIN_ERROR. - SendCertificateStatus: error on an over-long OCSP chain instead of silently truncating the stapled response; keep the chainOcspRequest[] index bound. - wc_PKCS7_DecodeAuthEnvelopedData: bounds-check the authTag tag read under NO_PKCS7_STREAM. - Tests: chain-depth test now pins the boundary (exactly MAX_CHAIN_DEPTH loads, one more rejected).
…h-and-parser-bounds # Conflicts: # src/ssl.c
Summary
Harden certificate-chain depth handling and parser input validation.
MAX_CHAIN_DEPTHin certificate loading (ProcessUserChain), OCSPstapling (
SendCertificateStatus), and TLS 1.3 certificate send(
SendTls13Certificate). The load-time check runs after a cert is parsed,so a full-depth chain followed by trailing data still loads.
idxbounds checks to the peer-chain accessors inssl.c.SendCertificateStatus: bound the OCSP chain loops byMAX_CHAIN_DEPTHanderror on an over-long chain rather than silently truncating the response.
TLSX_SNI_GetFromBufferlength validation (requirelistLen == extLen - OPAQUE16_LEN, boundsniLen) against overreads on amalformed ClientHello.
TLSX_CSR_Free(<=to<).wc_PKCS7_DecodeAuthEnvelopedDataagainst truncated input(
encryptedContentSz, the authTag tag read,authTagSz) underNO_PKCS7_STREAM.Tests
tests/api.c.test_pkcs7.c.test_dtls13_oversized_cert_chain, superseded by the load-time cap.