Skip to content

Check rustls provider panic reachability - #572

Merged
moq-bot[bot] merged 3 commits into
mainfrom
quest/m2/confidence/rustls-provider-panics
Nov 10, 2026
Merged

moq-bot[bot] merged 3 commits into
mainfrom
quest/m2/confidence/rustls-provider-panics

Conversation

@kixelated

@kixelated kixelated commented Nov 10, 2026 •

Copy link
Copy Markdown
Collaborator

Closes the quest with evidence: no peer input, and no normal use of the provider, can reach the unwraps in rind-rustls/src/aead.rs (aead_key at :12, the TLS 1.2 ChaCha IV at :77, the AES-GCM TLS 1.2 IV at :241). No code changes.

Provenance (rustls 0.23.46)

  • TLS 1.3 key/IV: KeyScheduleSuite::set_encrypter/derive_decrypter (src/tls13/key_schedule.rs) build the key with derive_traffic_key(expander, aead_alg), which HKDF-expands exactly aead_alg.key_len() bytes, and the IV with derive_traffic_iv, a fixed [u8; NONCE_LEN]. rind's key_len() returns the algorithm's own key length, so aead::Key::new always gets the right size.
  • TLS 1.2 key/IV: make_cipher_pair (src/tls12/mod.rs:157) splits a PRF key block sized from our own key_block_shape() (enc_key_len = algorithm key length, fixed_iv_len 12 for ChaCha / 4 for GCM, explicit 8 for GCM). decrypter gets fixed_iv_len bytes, so GCM's iv.try_into() into [u8; 4] and ChaCha's 12-byte IV always fit. extract_keys is fed the same split.
  • The peer influences only the secret's value (via the handshake), never these lengths; lengths are fixed by the negotiated suite, which is one of ours.

Trait contract

AeadKey::new is pub(crate) in rustls; outside rustls a key can only be built via From<[u8; 32]>. A direct trait caller handing a 32-byte key to an AES-128 encrypter, or a wrong-length IV slice, is outside the contract rustls documents ("the caller arranges that key is key_len() in bytes"). rustls's own ring provider unwraps in exactly the same places (src/crypto/ring/tls12.rs:127,146,183,193,219, tls13.rs:175,183), and rind-rustls must offer exactly that provider's API and behavior, so returning errors here is impossible (the trait methods are infallible) and panicking on contract violation matches upstream.

Decisions made without asking

  • Closed rather than adding a fallible path: the trait signatures leave no error channel, and the fuzz quest (adapters-hostile-input, and draft moq-dev/rind#561) guards the peer boundary mechanically.
  • No broader rind API hardening planned: the evidence doesn't warrant it.

Public API

None.

Caused by

No defect found.

Models

Size: S
Implementer: Claude Code, Opus 5.5, unknown effort

🤖 Generated with Claude Code

(Written by Opus 5.5)

Review

Rewritten by quest review after each round.

  • Reviewer: Codex, gpt-6.1-sol, medium effort
  • Session: 01a1c621-384a-76b3-a4b3-fce694753275, round 1
  • Head: 12d6cf8
  • Base: origin/main at 9a47bbc
  • Score: 10/10, The change only removes a quest document and its references, changes no executable code or tests, and leaves no references to the deleted document.
  • Findings: none

kixelated and others added 2 commits November 10, 2026 07:43
@kixelated
kixelated marked this pull request as ready for review November 10, 2026 15:44
@coderabbitai

coderabbitai Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 17 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 5bdab05b-3c35-4bbd-be37-213ce220a2c0
Commits

Reviewing files that changed from the base of the PR and between 9a47bbc and 4f3c97b.

Files selected for processing: 3

  • quest/m2/confidence/README.md
  • quest/m2/confidence/adapters-hostile-input.md
  • quest/m2/confidence/rustls-provider-panics.md
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No blocking issues — the evidence in the PR body verifies against the pinned sources, and the quest tree stays consistent. One stale cross-reference worth a one-sentence follow-up.

Reviewed changes

  • Quest closure: deletes quest/m2/confidence/rustls-provider-panics.md, its ## Required bullet in quest/m2/confidence/README.md, and both cross-reference bullets in adapters-hostile-input.md; a whole-tree grep finds no remaining reference to the deleted quest.
  • Closure evidence verified against the repo: the three unwraps are exactly where the body says — aead_key at rind-rustls/src/aead.rs:12, the TLS 1.2 ChaCha IV at :77, the AES-GCM TLS 1.2 IV at :241 — and Cargo.lock pins rustls 0.23.46, the version the provenance cites.
  • Closure evidence verified against rustls 0.23.46 (tag v/0.23.46): KeyScheduleSuite::set_encrypter/derive_decrypter build the key via derive_traffic_key, which HKDF-expands exactly aead_alg.key_len() bytes, and the IV via derive_traffic_iv, a fixed 12-byte Iv; make_cipher_pair splits a PRF key block sized from the provider's own key_block_shape() and hands the decrypter exactly fixed_iv_len bytes, with extract_keys fed the same split; AeadKey::new is pub(crate) (behind the tls12 feature) and From<[u8; 32]> is the only public constructor, so a peer or a normal provider user cannot influence any length.
  • Parity decision sound: rustls's own ring provider unwraps in the same places (UnboundKey::new(...).unwrap() in both providers' encrypters/decrypters, the try_into().unwrap() in TLS 1.2 extract_keys), with the same documented contract — "the caller arranges that key is key_len() in bytes" — and the trait methods are infallible, so matching upstream rather than adding a fallible path follows the adapter-parity rule in AGENTS.md.

ℹ️ adapters-hostile-input.md still points at the trace this PR deletes

quest/m2/confidence/adapters-hostile-input.md:14 says the 2026-11-09 audit "found no panic a peer can reach, apart from the unwraps the trace under Related owns" — but this PR removes that trace from ## Related, and the trace is now closed with the conclusion that no peer input reaches those unwraps. The sentence both dangles (nothing under Related is the trace anymore) and understates the settled result. One sentence fixes it; the mechanical guard this PR points at is unaffected.

Technical details
# Stale prose reference to the closed panic-reachability trace

## Affected sites
- quest/m2/confidence/adapters-hostile-input.md:14 — "apart from the `unwrap`s the trace under Related owns": the Related bullet for that trace was deleted by this PR, so "the trace" no longer resolves, and the trace's outcome (no peer input reaches the `unwrap`s in `rind-rustls/src/aead.rs`) is settled by this PR's body.

## Required outcome
- The sentence names something a reader can still find: either reference the closed trace by its PR ("the trace in #572, which closed with no reachable panic") or fold the result in ("the `unwrap`s in `rind-rustls/src/aead.rs`, which #572 confirmed no peer input reaches").

Pullfrog  | Fix it ➔ | View workflow run | Using glm-5.3 | 𝕏

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated enabled auto-merge November 10, 2026 16:04
@moq-bot
moq-bot Bot added this pull request to the merge queue Nov 10, 2026
Merged via the queue into main with commit 9eb8e1c Nov 10, 2026
4 checks passed
@kixelated
kixelated deleted the quest/m2/confidence/rustls-provider-panics branch November 11, 2026 21:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant