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.
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.
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.
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).
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).