REALITY.5 follow-up cleanups (MessageTooLarge/u24_len, pre-write signing-key, partial-record splice, group-29 test) #88

Merged
vxfemboy merged 27 commits from feat/reality-5-followup-cleanups into main 2026-07-19 01:19:32 +00:00
vxfemboy commented 2026-07-19 00:39:38 +00:00 (Migrated from github.com)

REALITY.5 follow-up cleanups

Stacked on #87 (REALITY.5d). Base is feat/reality-5d-wire-server-flight; merge after #87. Clears the non-blocking follow-ups accumulated across the REALITY.5 stack (the ones you asked to fix — this deliberately leaves exact-leaf-length padding out, keeping the natural-leaf decision, and leaves P256/P384 + HelloRetryRequest as its own milestone #84).

yip-utls

  • Error::MessageTooLargeemit_server_flight's handshake-message u24 length guards were reusing the record-layer handshake::Error::RecordTooLarge; a dedicated message-framing variant reads clearer.
  • u24_len(usize) -> Result<[u8;3], Error> — extracts the u32::try_from + > 0xFF_FFFF ceiling check that was duplicated across the handshake-message / CertificateEntry / certificate_list length prefixes, guarding the real u24 ceiling (not just u32::MAX). Unit-tested at the boundaries (0, 1, mid, exactly 0xFF_FFFF, one over).

yip-rendezvous — fail-safe + camouflage

  • Hoist the CertVerify signing-key load pre-write (tls_front.rs) — SigningKey::from_pkcs8_der now runs above the ServerHello write, so its (unreachable — the same PKCS#8 already parsed as an rcgen KeyPair) failure splices rather than drops, keeping every fallible step on the pre-write side of the fail-safe boundary.
  • Splice partial-record stalls (reality_io.rs) — read_first_tls_record now enforces the HANDSHAKE_TIMEOUT deadline itself (per read via timeout_at, an absolute deadline — slowloris-safe) instead of the caller wrapping it in a cancelling timeout(). A client that stalls after sending a partial record now yields the consumed bytes as Passthrough → spliced to dest (a real upstream holds a half-sent record and answers), rather than being dropped (a mild timing distinguisher). A zero-byte connection still drops (Empty). New test: partial-then-stall over a real socket, writer held open, asserts the exact consumed prefix is replayed.

Tests

  • Group-29 dest end-to-end test — an X25519-only cert source (set_curves_list("X25519")) forces the captured template to key_share_group == 29, so the authed path feeds the standalone 0x001d share (not the 4588 tail) into emit_server_hello; a real verify=on client must still complete the hand-rolled handshake and verify the 4b binding. Deterministic, independent of which hybrid groups the BoringSSL version supports (the 4588 path is covered by the netns money test). start_reality_front_with gains a cert_src parameter (both existing callers updated).
  • netns nit — dropped a redundant dump_logs on the wrong-pbk FAIL branch of run-netns-reality-5d.sh (it cat'd the stale good-run log, not the wrong-pbk run's).

Deferred (intentionally not here)

  • Exact-leaf-length padding — you chose the natural forged leaf; the passive DPI can't see cert size, and real dests carry SCTs that keep the forged flight smaller.
  • P256/P384 + HelloRetryRequest — issue #84, milestone-sized (such a dest currently → splice, safe).

Review (sonnet): Approved — all six match intent; the security-sensitive read-timeout change is slowloris-safe (absolute deadline) with a genuine test; no unsafe/as/bare-#[allow]. 70 yip-utls + 86 yip-rendezvous tests green, clippy clean.

## REALITY.5 follow-up cleanups **Stacked on #87 (REALITY.5d).** Base is `feat/reality-5d-wire-server-flight`; merge after #87. Clears the non-blocking follow-ups accumulated across the REALITY.5 stack (the ones you asked to fix — this deliberately leaves exact-leaf-length padding out, keeping the natural-leaf decision, and leaves P256/P384 + HelloRetryRequest as its own milestone #84). ### yip-utls - **`Error::MessageTooLarge`** — `emit_server_flight`'s handshake-message u24 length guards were reusing the record-layer `handshake::Error::RecordTooLarge`; a dedicated message-framing variant reads clearer. - **`u24_len(usize) -> Result<[u8;3], Error>`** — extracts the `u32::try_from` + `> 0xFF_FFFF` ceiling check that was duplicated across the handshake-message / CertificateEntry / certificate_list length prefixes, guarding the real u24 ceiling (not just `u32::MAX`). Unit-tested at the boundaries (0, 1, mid, exactly `0xFF_FFFF`, one over). ### yip-rendezvous — fail-safe + camouflage - **Hoist the CertVerify signing-key load pre-write** (`tls_front.rs`) — `SigningKey::from_pkcs8_der` now runs *above* the ServerHello write, so its (unreachable — the same PKCS#8 already parsed as an rcgen KeyPair) failure **splices** rather than drops, keeping every fallible step on the pre-write side of the fail-safe boundary. - **Splice partial-record stalls** (`reality_io.rs`) — `read_first_tls_record` now enforces the `HANDSHAKE_TIMEOUT` deadline itself (per read via `timeout_at`, an *absolute* deadline — slowloris-safe) instead of the caller wrapping it in a cancelling `timeout()`. A client that stalls *after* sending a partial record now yields the consumed bytes as `Passthrough` → spliced to `dest` (a real upstream holds a half-sent record and answers), rather than being dropped (a mild timing distinguisher). A zero-byte connection still drops (`Empty`). New test: partial-then-stall over a real socket, writer held open, asserts the exact consumed prefix is replayed. ### Tests - **Group-29 dest end-to-end test** — an X25519-only cert source (`set_curves_list("X25519")`) forces the captured template to `key_share_group == 29`, so the authed path feeds the standalone `0x001d` share (not the 4588 tail) into `emit_server_hello`; a real `verify=on` client must still complete the hand-rolled handshake and verify the 4b binding. Deterministic, independent of which hybrid groups the BoringSSL version supports (the 4588 path is covered by the netns money test). `start_reality_front_with` gains a `cert_src` parameter (both existing callers updated). - **netns nit** — dropped a redundant `dump_logs` on the wrong-pbk FAIL branch of `run-netns-reality-5d.sh` (it cat'd the stale good-run log, not the wrong-pbk run's). ### Deferred (intentionally not here) - Exact-leaf-length padding — you chose the natural forged leaf; the passive DPI can't see cert size, and real dests carry SCTs that keep the forged flight smaller. - P256/P384 + HelloRetryRequest — issue #84, milestone-sized (such a dest currently → splice, safe). Review (sonnet): **Approved** — all six match intent; the security-sensitive read-timeout change is slowloris-safe (absolute deadline) with a genuine test; no `unsafe`/`as`/bare-`#[allow]`. 70 yip-utls + 86 yip-rendezvous tests green, clippy clean.
Sign in to join this conversation.
No description provided.