§2.1
Chapter 02 · QUIC Connection Establishment and Security Handshake

§2.1QUIC Handshake Message Flow and State Transitions

RFC 9001RFC 9000

Learning objective. Follow a QUIC handshake flight by flight: which packets carry which TLS messages, when each set of keys becomes available, and what "complete" versus "confirmed" mean. Then the trace you captured in §1.5 reads as a story rather than a list of packets.

One handshake, three key levels #

QUIC does not run TLS over a reliable stream and then start the transport. It runs one handshake in which the TLS 1.3 messages ride inside QUIC CRYPTO frames, and the keys that TLS produces are the keys QUIC uses to protect packets ([RFC 9001 §4]). The handshake advances through three encryption levels, each with its own packet type and packet number space (§1.2):

  • Initial. Keys derived from a fixed salt and the client's Destination Connection ID (§2.2). Anyone can compute them, so Initial packets are authenticated but not confidential; they exist to bootstrap.
  • Handshake. Keys derived from the TLS key exchange, so these packets are genuinely encrypted. They carry the rest of the TLS handshake away from onlookers.
  • 1-RTT. The application-data keys, used for everything after the handshake.
ServerClientInitial keys derived from a fixed salt + client's DCID (no secrecy)derive Handshakekeysauthenticate server ·install 1-RTT keyshandshake completehandshake confirmed — 1-RTT keys only from hereInitial [CRYPTO: ClientHello + transport parameters]Initial [CRYPTO: ServerHello] · ACKHandshake [CRYPTO: EncryptedExtensions, Certificate,CertificateVerify, Finished + transport parameters]Handshake [CRYPTO: Finished] · ACK1-RTT [application data]1-RTT [HANDSHAKE_DONE] · ACK
Fig. 2.1-1A full 1-RTT handshake. TLS messages travel in CRYPTO frames; each flight installs the next level of keys. Transport parameters ride the TLS handshake in both directions.RFC 9001 §4

Flight by flight #

The client opens with an Initial packet whose CRYPTO frame holds the TLS ClientHello, carrying QUIC's transport parameters in a TLS extension (quic_transport_parameters, §7.1). The server replies in one datagram (often two coalesced packets, §1.4): an Initial with the ServerHello, and a Handshake packet with the encrypted remainder: EncryptedExtensions, Certificate, CertificateVerify, and the server's Finished, plus the server's transport parameters. At that point the client can authenticate the server and install 1-RTT keys. It sends its own Handshake packet with a Finished, and may immediately begin sending 1-RTT application data. The server, once it has the client's Finished, sends a HANDSHAKE_DONE frame (0x1e) in a 1-RTT packet.

This is exactly the timeline the §1.5 lab captured: initial [crypto] out, initial [ack,crypto] and handshake [crypto] back, handshake [ack,crypto] out, then 1rtt in both directions ending with handshake_done.

Figure 2.1-3 makes that same handshake concrete at every layer at once: the four UDP datagrams, the packets each one carries (long-header while the handshake runs, short-header once 1-RTT begins, sometimes two coalesced in one datagram, §1.4), and the frames inside each packet. It is dense on purpose: seeing datagram, packet, and frame boundaries together, in colour, is the fastest way to internalize how QUIC frames its traffic.

Client → Server
UDP datagram · ≥ 1200 bytes
Initial packet · long header
CRYPTOClientHello + transport paramsPADDINGpad up to 1200 B
Server → Client
UDP datagram
Initial packet · long header
ACKCRYPTOServerHello
Handshake packet · long header
CRYPTOEncryptedExtensions, Certificate, CertificateVerify, Finished + transport params
Client → Server
UDP datagram
Handshake packet · long header
ACKCRYPTOFinished
1-RTT packet · short header
STREAMfirst HTTP/3 request
Server → Client
UDP datagram
1-RTT packet · short header
ACKHANDSHAKE_DONENEW_CONNECTION_IDSTREAMHTTP/3 response
packetsInitialHandshake1-RTT
framesCRYPTO (TLS)ACKSTREAM (app data)controlPADDING
Fig. 2.1-3The 1-RTT handshake, fully framed — every datagram, packet, and frameRFC 9000 §12; RFC 9001 §4

Complete, then confirmed #

Two milestones are worth separating. The handshake is complete at an endpoint when its TLS stack has finished — the client after processing the server's Finished, the server after processing the client's. It is confirmed slightly later: at the server, the moment it sends HANDSHAKE_DONE; at the client, the moment it receives one ([RFC 9001 §4.1.2]). Confirmation matters because a few actions, notably initiating a key update (§2.2), are forbidden until the handshake is confirmed, and because the Initial and Handshake keys (and their packet number spaces) are discarded around these points, never to be used again.

ServerHello processed

TLS Finished sent & received

HANDSHAKE_DONE received

connection close

Initial keys (salt-derived)

Handshake keys (encrypted)

1-RTT keys (application data)

Confirmed (key update allowed)

Fig. 2.1-2The endpoint's view as a state machine over encryption levels. Each transition is driven by a specific TLS or transport event.RFC 9001 §4.1.2, §7
Note

The client can send 1-RTT application data before the handshake is confirmed — as soon as it has installed 1-RTT keys after the server's Finished. Confirmation is a later, stronger condition than "I can send application data," which is why 0-RTT and early 1-RTT both exist as distinct optimizations (§2.3).

In practice

editorial Most handshake stalls trace to one of three things: the client's first datagram not reaching the 1200-byte floor (so the server drops it, §1.4); the server hitting the 3× anti-amplification limit and waiting for a client packet it never gets (§8.1); or a lost Handshake packet with no application traffic to piggyback ACKs on, stretching recovery to a PTO. When a connection "hangs" mid-handshake, capture both endpoints' qlog and compare which encryption level each one reached. The gap is the failure. §2.5 works through the specific error cases.

Takeaways #

A QUIC handshake is a tightly choreographed exchange of CRYPTO frames that walks the connection up three levels of keys in one round trip, threading transport parameters through the TLS handshake in both directions. The next section opens the box marked "derive keys," showing exactly how TLS 1.3 secrets become QUIC's packet-protection keys (§2.2).