Quic server mode fixes#244
Merged
Merged
Conversation
mmaehren
approved these changes
May 4, 2026
Contributor
mmaehren
left a comment
There was a problem hiding this comment.
Thanks for this PR!
We have an internal development branch for QUIC in which we also addressed these issues. However, we are not sure when it will be released to public so implementing these fixes now is probably the best way.
Regarding the initial connection ID, in our branch we opted for creating a random value as part of the QUIC init code in QuicContext so peers never associate our new connections with older sessions.
Feel free to tag me and @NErinola as reviewers for any upcoming PRs concerning QUIC.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR fixes two bugs when using TLS-Attacker as a QUIC server.
See notes for reproducing at the end.
Bug 1: Initial secrets derived from wrong DCID
QuicContext.init()always generates a randomfirstDestinationConnectionIdand callscalculateInitialSecrets().The RFC requires both peers to derive Initial secrets from the DCID in the client's first Initial packet.
The branch that "fixes" on receive in
InitialPacketHandler.adjustContext()is not reached here, because it runs after the decryption (and the condition is false sinceisInitialSecretsInitializedis true).Fixes for this are in commit
6f71eb5f6edf713d67e2af0b8e033256e7d5b444:QuiContext.init(): when in SERVER mode skip calculating initial secretsQuicPacketLayer.readPackets(): after parsing packets, if in server mode and secrets not yet initialized, adopt the first Initial's DCID and calculate secretsBug 2: CRYPTO frame offsets always zero on send path
sendDataInternal()uses a localoffseteach time it is called. This leads to all CRYPTO frames in the Handshake being emitted at stream offset 0, when they should be continuously increasing depending on message sizes.Fixes for this are in commit
9659763ac5eb08151df1ba6209dbff0d1536b7f1:QuicFrameLayer. Use tracked offset as base for each call and advance bydata.length.Reproduction
Prerequisites
pip install aioquicAutomated
Drop
reproduce.shandServerModeQuicRepro.javainto a directory, then:The script generates a throwaway cert, compiles the Java repro against TLS-Attacker's classpath, starts the server, connects an aioquic client, and reports PASS/FAIL.
ServerModeQuicRepro.java
reproduce.sh
Output before fix
Output after fix
TLS-Attacker: ../TLS-Attacker (34fc23088 add tests) Java: openjdk version "21.0.11" 2026-04-21 Starting server on port 4433... Running aioquic client... === Server === [repro] QUIC server listening on port 4433 [repro] executedAsPlanned=true === Client === OK handshake_completed RESULT: PASSNote on ODCID
TLS-Attacker does not set the original destination connection ID by itself. I was not sure whether this is intended behavior so a fix for that is not included here.