Skip to content

transport params: validate stateless reset token length - #2802

Open
mneha05 wants to merge 1 commit into
cloudflare:masterfrom
mneha05:fix/stateless-reset-token-length
Open

mneha05 wants to merge 1 commit into
cloudflare:masterfrom
mneha05:fix/stateless-reset-token-length

Conversation

@mneha05

@mneha05 mneha05 commented Oct 6, 2026

Copy link
Copy Markdown

Summary

Validate that the stateless_reset_token transport parameter is exactly 16 bytes, as required by RFC 9000 Section 18.2.

Previously, an overlong value was accepted with trailing bytes ignored, while an underlong value surfaced as BufferTooShort rather than InvalidTransportParam.

Changes

  • reject stateless_reset_token values whose declared length is not exactly 16 bytes
  • add regression coverage for 15-byte and 17-byte values
  • keep a 16-byte value as a positive control

Fixes #2659.

@mneha05
mneha05 requested a review from a team as a code owner October 6, 2026 01:29
@ghedo ghedo added type: bugfix Corrects defective behavior. area: transport-parameters Changes related to transport-parameters. labels Oct 14, 2026
@ghedo
ghedo force-pushed the fix/stateless-reset-token-length branch from d609083 to bf17643 Compare November 12, 2026 12:19

@ghedo ghedo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the fix. Rejecting a stateless_reset_token whose length isn't 16 bytes with TRANSPORT_PARAMETER_ERROR matches RFC 9000 §18.2 and §7.4, and 16-byte values still decode.

The practical impact is small. Only the overlong case was non-compliant, since it was accepted with the extra bytes ignored. The underlong case already closed the connection with PROTOCOL_VIOLATION, which §11 allows in place of a more specific code. Neither case affected security or interop.

The formatting issue needs to be fixed before merging. The other two comments simplify the change, and together they shrink it from 38 added lines to 15 added and 3 removed. The suggested test fails without the fix and passes with the simplified conversion.

Comment on lines +267 to +269
if val.cap() != 16 {
return Err(Error::InvalidTransportParam);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

With this check in place, val.get_bytes(16)? and .map_err(|_| Error::BufferTooShort)? below can no longer fail, which leaves two unreachable error paths. Dropping the check and changing the existing conversion instead rejects both the 15-byte and 17-byte cases with InvalidTransportParam:

 tp.stateless_reset_token = Some(u128::from_be_bytes(
-    val.get_bytes(16)?
-        .to_vec()
+    val.to_vec()
         .try_into()
-        .map_err(|_| Error::BufferTooShort)?,
+        .map_err(|_| Error::InvalidTransportParam)?,
 ));

Comment on lines +632 to +633


Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These two consecutive blank lines fail cargo fmt -- --check, because rustfmt.toml sets blank_lines_upper_bound = 1. The Nightly workflow runs that check on external PRs, so CI will fail. Running cargo +nightly fmt fixes it, and moving the test to quiche/src/tests.rs, as suggested on the test module, removes these lines entirely.

}


#[cfg(test)]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The other transport parameter tests live in quiche/src/tests.rs, so this test fits next to transport_params_forbid_duplicates without a new test module. The 16-byte case duplicates the existing transport_params test, which already round-trips the same [0xba; 16] token through decode. Since TransportParams derives Debug and PartialEq, assert_eq! works here like in transport_params_forbid_duplicates and shows the actual result on failure.

Suggested replacement:

#[test]
fn transport_params_invalid_stateless_reset_token() {
    for len in [15, 17] {
        let mut raw_params = vec![0x02, len as u8];
        raw_params.resize(2 + len, 0xba);

        assert_eq!(
            TransportParams::decode(&raw_params, false, None),
            Err(Error::InvalidTransportParam)
        );
    }
}

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: transport-parameters Changes related to transport-parameters. type: bugfix Corrects defective behavior.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

stateless_reset_token exact-length validation missing

2 participants