Repository navigation
Conversation
81d6404 to
e16541a
Compare
|
646253f to
55ec736
Compare
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #11362
Scan targets checked: wolfcrypt-rs-bugs, wolfssl-bugs, wolfssl-src
Findings: 3
3 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Reported findings require changes before merge.
55ec736 to
72e8586
Compare
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #11362
Scan targets checked: wolfcrypt-rs-bugs, wolfssl-bugs, wolfssl-src
Findings: 3
3 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Reported findings require changes before merge.
72e8586 to
f512027
Compare
f512027 to
de17187
Compare
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #11362
Scan targets checked: wolfcrypt-rs-bugs, wolfssl-bugs, wolfssl-src
Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Reported findings require changes before merge.
de17187 to
1882e64
Compare
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #11362
Scan targets checked: wolfcrypt-rs-bugs, wolfssl-bugs, wolfssl-src
Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Reported findings require changes before merge.
0c1588b to
94d8fcb
Compare
|
@claude review |
There was a problem hiding this comment.
Findings marked 🟡 are optional suggestions and need no follow-up push.
Additional findings (outside the current diff — GitHub can't attach inline comments there):
-
🔴
src/internal.c— SCT-only builds leak the leaf's CertificateEntry extension buffer when a server frees a connection before its Certificate message is fully sent. wolfSSL_ResourceFree() frees ssl->buffers.certExts only under HAVE_CERTIFICATE_STATUS_REQUEST. Since this change, WriteCertEntryExts() also allocates certExts[0] for the SCT list under WOLFSSL_CERT_ENTRY_EXTS. Fix: guard this cleanup with WOLFSSL_CERT_ENTRY_EXTS (with !NO_CERTS and WOLFSSL_TLS13), the macro wolfssl/internal.h says every site that builds, indexes or frees these buffers must share.Why this was flagged
The trigger is a build with --enable-sct but not OCSP stapling, so HAVE_SIGNED_CERT_TIMESTAMP is defined and HAVE_CERTIFICATE_STATUS_REQUEST is not. In that build WOLFSSL_CERT_ENTRY_EXTS is defined (wolfssl/internal.h). A TLS 1.3 server answering an SCT request calls WriteCertEntryExts() (src/tls13.c:11712), which AllocDer()s ssl->buffers.certExts[0] for the leaf's SCT list. That buffer is freed only once the leaf has been completely copied out (src/tls13.c:11889). Two cases leave it allocated: the send stops part way, or it fails before the leaf is written. Examples are a WANT_WRITE between fragments under a small max_fragment_length or record_size_limit followed by wolfSSL_free(), or a CheckAvailableSize() failure. The only teardown free, src/internal.c:10541-10550, is compiled out in this build, so each such connection leaks the buffer. On the base branch certExts was only allocated in builds that also compiled this free.
Verification: In SCT-only builds, WriteCertEntryExts calls
AllocDer(&certExts[extIdx], ...)for the SCT list (src/tls13.c:10677), freed only once the leaf is fully sent (tls13.c:11889). The only fallback cleanup is wolfSSL_ResourceFree at src/internal.c:10541-10550. It is guarded bydefined(HAVE_CERTIFICATE_STATUS_REQUEST), so it compiles out in SCT-only builds. -
🔴
src/ssl.c— Apps using wolfSSL_write_dup() will send records larger than a peer's negotiated record_size_limit, so an RFC 8449 peer aborts with record_overflow. DupSSL() copies max_fragment and maxSendFragment to the write-only object but not peerRecordSizeLimit. The dup starts that field at 0 from InitSSL(), so wolfSSL_GetMaxFragSize() never caps its sends. Fix: copy peerRecordSizeLimit into the dup next to max_fragment, under HAVE_RECORD_SIZE_LIMIT, so every record the writer sends respects the peer's limit.Why this was flagged
The trigger is a build with HAVE_WRITE_DUP and HAVE_RECORD_SIZE_LIMIT, where the peer advertised a limit below 2^14 (e.g. wolfSSL_UseRecordSizeLimit(ssl, 512) on a wolfSSL peer, or a constrained embedded stack). wolfSSL_write_dup() (src/ssl.c:1037) zero-inits the dup in InitSSL() (src/internal.c:9215), then DupSSL() copies only max_fragment (src/ssl.c:953) and maxSendFragment (src/ssl.c:1006). peerRecordSizeLimit, set only on the read object by TLSX_RecordSizeLimit_Parse() (src/tls.c:8559), stays 0 on the dup. So the HAVE_RECORD_SIZE_LIMIT cap in wolfSSL_GetMaxFragSize() (src/internal.c:48519) is skipped, and wolfSSL_write() on the dup sends records of up to MAX_RECORD_SIZE. A wolfSSL peer rejects them in GetRecordHeader() (src/internal.c:14187) with LENGTH_ERROR / record_overflow, and the connection dies on the first large write. Without write-dup the same object sends correctly sized records. The max_fragment copy shows DupSSL() is meant to carry negotiated send limits, but the new field was left out.
Verification: DupSSL() copies
dup->max_fragment = ssl->max_fragment;(src/ssl.c:953) but never peerRecordSizeLimit, which InitSSL zeroes (src/internal.c:9215). wolfSSL_GetMaxFragSize applies the RFC 8449 cap only if peerRecordSizeLimit != 0 (src/internal.c:48519). On the dup that field is 0, so records go out at up to MAX_RECORD_SIZE (16384). -
🔴
src/internal.c— A TLS or DTLS connection exported and re-imported with wolfSSL_tls_export()/wolfSSL_dtls_export() loses the peer's negotiated record_size_limit. After import it sends full-size records the peer must reject with record_overflow. ExportOptions() and ImportOptions() do not serialize peerRecordSizeLimit, so the imported object starts at 0 and wolfSSL_GetMaxFragSize() applies no cap. Fix: add peerRecordSizeLimit (and recordSizeLimit, for the receive check) to the export blob under HAVE_RECORD_SIZE_LIMIT with an export version bump, so an imported session keeps honouring the peer's limit.Why this was flagged
The trigger is an application built with WOLFSSL_SESSION_EXPORT and HAVE_RECORD_SIZE_LIMIT that exports a live connection (src/ssl_sess.c:3725 / 3792) after the peer advertised a limit below 2^14, then imports it with wolfSSL_tls_import()/wolfSSL_dtls_import(). ExportOptions() (src/internal.c:1514) and ImportOptions() (src/internal.c:1707) do not carry the new peerRecordSizeLimit field from TLSX_RecordSizeLimit_Parse() (src/tls.c:8559). The importing WOLFSSL has peerRecordSizeLimit 0, so wolfSSL_GetMaxFragSize() (src/internal.c:48519) does not cap sends, and the GetRecordHeader() receive check (src/internal.c:14187) is disabled too. Any write above the peer's limit then produces a record the peer must answer with a fatal record_overflow alert, while the original object would have fragmented it. max_fragment is not exported either, so this matches an existing gap for MFL; that shows the path was never covered, not that it is safe now that record_size_limit is advertised by default.
Verification: Trigger: a build with WOLFSSL_SESSION_EXPORT and HAVE_RECORD_SIZE_LIMIT exports, then imports, a connection whose peer advertised a record_size_limit below 2^14. ExportOptions() (src/internal.c:1514-1690) writes nothing from peerRecordSizeLimit, so wolfSSL_GetMaxFragSize() (48519) returns MAX_RECORD_SIZE and the peer rejects records with record_overflow. On the base, wolfSSL never negotiated record_size_limit.
|
Tests good with multi-test with |
philljj
left a comment
There was a problem hiding this comment.
merge conflict, and see review items
94d8fcb to
9292c02
Compare
9292c02 to
6327b2c
Compare
|
@claude review |
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved SCT response sizing and suspended certificate verification defects risk buffer overflow and use-after-free, while record-size checks can accept plaintext exceeding negotiated limits.
8 open issues
Enforce negotiated plaintext limit after CBC decryption · New Prevent word16 overflow in ServerHello size calculation · New Preserve decompressed certificates across suspended verification · New Gate extra record byte on actual ClientHello advertisement · New Copy peer record size limit in DupSSL() · New Register SCT response when installing the first list · New Reject record-limit changes after ClientHello is sent · New Free SCT buffers in SCT-only builds · New
3 resolved since last review
Review effort: Balanced
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #11362
Scan targets checked: wolfssl-src, wolfssl-bugs
Not reviewed (no scan target covers them): .github/configs/os-check-linux.json, CMakeLists.txt, cmake/options.h.in, configure.ac, doc/dox_comments/header_files/ssl.h, examples/client/client.c, tests/api/test_tls.h, tests/api/test_tls13.h
Coverage: 12 of 21 in-scope changed file(s) opened by the reviewer; not opened: src/dtls13.c, src/ssl_load.c, src/ssl_sess.c, tests/api.c, tests/api/test_compress.c, tests/api/test_dtls13.c, tests/api/test_tls.c, tests/api/test_tls13.c, wolfssl/openssl/ssl.h
Findings: 2
2 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Reported findings require changes before merge.
Review tier: Lite
6327b2c to
3eab5a3
Compare
|
@claude review |
There was a problem hiding this comment.
🟡 Changes recommended
The post-decryption size check rejects valid TLS 1.2 records, and stale state after wolfSSL_clear() prevents reconfiguring the record-size limit on reused connections.
2 open issues
8 resolved since last review
Preserve decompressed certificates across suspended verification Prevent word16 overflow in ServerHello size calculation Enforce negotiated plaintext limit after CBC decryption Free SCT buffers in SCT-only builds Reject record-limit changes after ClientHello is sent Register SCT response when installing the first list Copy peer record size limit in DupSSL() Gate extra record byte on actual ClientHello advertisement
Review effort: Balanced
There was a problem hiding this comment.
Additional findings (outside the current diff — GitHub can't attach inline comments there):
-
🔴
src/dtls13.c— DTLS 1.3 endpoints that negotiate a small record_size_limit can send ACK records larger than the peer's limit. The peer drops them, so the unacknowledged side retransmits until it times out fatally. Dtls13WriteAckMessage() packs every seen record number, up to DTLS13_ACK_MAX_RECORDS (128), into one protected record. It never checks the peer limit that the handshake fragmentation now honours. Fix: cap each ACK at (wolfssl_local_GetMaxPlaintextSize(ssl) - OPAQUE16_LEN) / DTLS13_RN_SIZE record numbers, and send the rest in further ACK records.Why this was flagged
The trigger is a DTLS 1.3 connection where both ends set a small limit with wolfSSL_CTX_UseRecordSizeLimit(), for example 64 or 256. Dtls13HandshakeSend() splits handshake messages using wolfssl_local_GetMaxPlaintextSize(), which wolfSSL_GetMaxFragSize() now caps at peerRecordSizeLimit, so a flight becomes many small records. SendDtls13Ack() then calls Dtls13WriteAckMessage() (src/dtls13.c:3241-3291), which writes 2 + 16*N bytes into one record and never consults the peer limit. In the peer's GetRecordHeader() (src/internal.c:14509-14611), the record exceeds recordSizeLimitSent + aead_mac_size and gets LENGTH_ERROR. DtlsShouldDrop() then drops it silently. The sender never sees the ACK, keeps retransmitting, and Dtls13RtxTimeout() eventually makes wolfSSL_dtls_got_timeout() return WOLFSSL_FATAL_ERROR. The base branch has no record_size_limit, so this does not happen there.
Verification: Severity: normal.
Dtls13WriteAckMessage()(src/dtls13.c:3241-3243) only checksrecordsCount > DTLS13_ACK_MAX_RECORDSand setsmsgSz = DTLS13_RN_SIZE * recordsCount. Nothing compares the ACK size againstpeerRecordSizeLimit. For DTLS,DtlsShouldDrop()(internal.c:26821) silently drops records withLENGTH_ERROR, so the ACK is thrown away.
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #11362
Scan targets checked: wolfssl-src, wolfssl-bugs
Not reviewed (no scan target covers them): .github/configs/os-check-linux.json, CMakeLists.txt, cmake/options.h.in, configure.ac, doc/dox_comments/header_files/ssl.h, examples/client/client.c, tests/api/test_tls.h, tests/api/test_tls13.h
Coverage: 16 of 22 in-scope changed file(s) opened by the reviewer; not opened: src/ssl_sess.c, tests/api.c, tests/api/test_compress.c, tests/api/test_dtls13.c, tests/api/test_tls.c, wolfssl/openssl/ssl.h
Findings: 3
3 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Reported findings require changes before merge.
Review tier: Max
Added support for record_size_limit in TLS 1.3 and TLS 1.2. Added compress_certificate support for TLS 1.3. Added signed_certificate_timestamp TLS 1.2 and 1.3. Added handshake-message fragmentation to EncryptedExtension, CertificateRequest and NewSessionTicket. Accepts server_name in CertificateRequest. Added API for setting signature algorithms for signature_algorithms_cert. SHA-1 certificate chain fix: a peer advertising ecdsa_sha1 against a chain with an RSA-SHA1 intermediates will see a failed handshake. Tests added and interop performed where possible.



Description
Added support for record_size_limit in TLS 1.3 and TLS 1.2.
Added compress_certificate support for TLS 1.3.
Added signed_certificate_timestamp TLS 1.2 and 1.3.
Added handshake-message fragmentation to EncryptedExtension, CertificateRequest
and NewSessionTicket.
Accepts server_name in CertificateRequest.
Added API for setting signature algorithms for signature_algorithms_cert.
SHA-1 certificate chain fix: a peer advertising ecdsa_sha1 against a chain
with an RSA-SHA1 intermediates will see a failed handshake.
Tests added and interop performed where possible.
Testing
Regression tested TLS.