1 /* packet-quic.c
2 * Routines for QUIC (IETF) dissection
3 * Copyright 2017, Alexis La Goutte <alexis.lagoutte at gmail dot com>
4 * Copyright 2018 Peter Wu <peter@lekensteyn.nl>
5 *
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
12
13 /*
14 * See https://quicwg.org
15 * RFC9000 QUIC: A UDP-Based Multiplexed and Secure Transport
16 * RFC9001 Using TLS to Secure QUIC
17 * RFC8889 Version-Independent Properties of QUIC
18 * https://tools.ietf.org/html/draft-ietf-quic-version-negotiation-03
19 *
20 * Extension:
21 * https://tools.ietf.org/html/draft-ferrieuxhamchaoui-quic-lossbits-03
22 * https://datatracker.ietf.org/doc/html/draft-ietf-quic-datagram-06
23 * https://tools.ietf.org/html/draft-huitema-quic-ts-02
24 * https://tools.ietf.org/html/draft-iyengar-quic-delayed-ack-00
25 * https://tools.ietf.org/html/draft-deconinck-quic-multipath-06
26 *
27 * Currently supported QUIC version(s): draft-21, draft-22, draft-23, draft-24,
28 * draft-25, draft-26, draft-27, draft-28, draft-29, draft-30, draft-31, draft-32,
29 * draft-33
30 * For a table of supported QUIC versions per Wireshark version, see
31 * https://github.com/quicwg/base-drafts/wiki/Tools#wireshark
32 *
33 * Decryption is supported via TLS 1.3 secrets in the "TLS Key Log File",
34 * configured either at the TLS Protocol preferences, or embedded in a pcapng
35 * file. Sample captures and secrets can be found at:
36 * https://gitlab.com/wireshark/wireshark/-/issues/13881
37 *
38 * Limitations:
39 * - STREAM offsets larger than 32-bit are unsupported.
40 * - STREAM with sizes larger than 32 bit are unsupported. STREAM sizes can be
41 * up to 62 bit in QUIC, but the TVB and reassembly API is limited to 32 bit.
42 * - Out-of-order and overlapping STREAM frame data is not handled.
43 * - "Follow QUIC Stream" doesn't work with STREAM IDs larger than 32 bit
44 */
45
46 #include <config.h>
47
48 #include <epan/packet.h>
49 #include <epan/expert.h>
50 #include <epan/proto_data.h>
51 #include <epan/to_str.h>
52 #include "packet-tls-utils.h"
53 #include "packet-tls.h"
54 #include "packet-tcp.h" /* used for STREAM reassembly. */
55 #include "packet-quic.h"
56 #include <epan/reassemble.h>
57 #include <epan/prefs.h>
58 #include <wsutil/pint.h>
59
60 #include <epan/tap.h>
61 #include <epan/follow.h>
62 #include <epan/addr_resolv.h>
63
64 /* Prototypes */
65 void proto_reg_handoff_quic(void);
66 void proto_register_quic(void);
67
68 static int quic_follow_tap = -1;
69
70 /* Initialize the protocol and registered fields */
71 static int proto_quic = -1;
72 static int hf_quic_connection_number = -1;
73 static int hf_quic_packet_length = -1;
74 static int hf_quic_header_form = -1;
75 static int hf_quic_long_packet_type = -1;
76 static int hf_quic_long_reserved = -1;
77 static int hf_quic_packet_number_length = -1;
78 static int hf_quic_dcid = -1;
79 static int hf_quic_scid = -1;
80 static int hf_quic_dcil = -1;
81 static int hf_quic_scil = -1;
82 static int hf_quic_token_length = -1;
83 static int hf_quic_token = -1;
84 static int hf_quic_length = -1;
85 static int hf_quic_packet_number = -1;
86 static int hf_quic_version = -1;
87 static int hf_quic_supported_version = -1;
88 static int hf_quic_vn_unused = -1;
89 static int hf_quic_short = -1;
90 static int hf_quic_fixed_bit = -1;
91 static int hf_quic_spin_bit = -1;
92 static int hf_quic_short_reserved = -1;
93 static int hf_quic_q_bit = -1;
94 static int hf_quic_l_bit = -1;
95 static int hf_quic_key_phase = -1;
96 static int hf_quic_payload = -1;
97 static int hf_quic_protected_payload = -1;
98 static int hf_quic_remaining_payload = -1;
99 static int hf_quic_odcil = -1;
100 static int hf_quic_odcid = -1;
101 static int hf_quic_retry_token = -1;
102 static int hf_quic_retry_integrity_tag = -1;
103
104 static int hf_quic_frame = -1;
105 static int hf_quic_frame_type = -1;
106
107 static int hf_quic_padding_length = -1;
108 static int hf_quic_ack_largest_acknowledged = -1;
109 static int hf_quic_ack_ack_delay = -1;
110 static int hf_quic_ack_ack_range_count = -1;
111 static int hf_quic_ack_first_ack_range = -1;
112 static int hf_quic_ack_gap = -1;
113 static int hf_quic_ack_ack_range = -1;
114 static int hf_quic_ack_ect0_count = -1;
115 static int hf_quic_ack_ect1_count = -1;
116 static int hf_quic_ack_ecn_ce_count = -1;
117 static int hf_quic_rsts_stream_id = -1;
118 static int hf_quic_rsts_application_error_code = -1;
119 static int hf_quic_rsts_final_size = -1;
120 static int hf_quic_ss_stream_id = -1;
121 static int hf_quic_ss_application_error_code = -1;
122 static int hf_quic_crypto_offset = -1;
123 static int hf_quic_crypto_length = -1;
124 static int hf_quic_crypto_crypto_data = -1;
125 static int hf_quic_nt_length = -1;
126 static int hf_quic_nt_token = -1;
127 static int hf_quic_stream_fin = -1;
128 static int hf_quic_stream_len = -1;
129 static int hf_quic_stream_off = -1;
130 static int hf_quic_stream_stream_id = -1;
131 static int hf_quic_stream_initiator = -1;
132 static int hf_quic_stream_direction = -1;
133 static int hf_quic_stream_offset = -1;
134 static int hf_quic_stream_length = -1;
135 static int hf_quic_stream_data = -1;
136 static int hf_quic_md_maximum_data = -1;
137 static int hf_quic_msd_stream_id = -1;
138 static int hf_quic_msd_maximum_stream_data = -1;
139 static int hf_quic_ms_max_streams = -1;
140 static int hf_quic_db_stream_data_limit = -1;
141 static int hf_quic_sdb_stream_id = -1;
142 static int hf_quic_sdb_stream_data_limit = -1;
143 static int hf_quic_sb_stream_limit = -1;
144 static int hf_quic_nci_retire_prior_to = -1;
145 static int hf_quic_nci_sequence = -1;
146 static int hf_quic_nci_connection_id_length = -1;
147 static int hf_quic_nci_connection_id = -1;
148 static int hf_quic_nci_stateless_reset_token = -1;
149 static int hf_quic_rci_sequence = -1;
150 static int hf_quic_path_challenge_data = -1;
151 static int hf_quic_path_response_data = -1;
152 static int hf_quic_cc_error_code = -1;
153 static int hf_quic_cc_error_code_app = -1;
154 static int hf_quic_cc_error_code_tls_alert = -1;
155 static int hf_quic_cc_frame_type = -1;
156 static int hf_quic_cc_reason_phrase_length = -1;
157 static int hf_quic_cc_reason_phrase = -1;
158 static int hf_quic_dg_length = -1;
159 static int hf_quic_dg = -1;
160 static int hf_quic_af_sequence_number = -1;
161 static int hf_quic_af_packet_tolerance = -1;
162 static int hf_quic_af_update_max_ack_delay = -1;
163 static int hf_quic_ts = -1;
164 static int hf_quic_reassembled_in = -1;
165 static int hf_quic_reassembled_length = -1;
166 static int hf_quic_reassembled_data = -1;
167 static int hf_quic_fragments = -1;
168 static int hf_quic_fragment = -1;
169 static int hf_quic_fragment_overlap = -1;
170 static int hf_quic_fragment_overlap_conflict = -1;
171 static int hf_quic_fragment_multiple_tails = -1;
172 static int hf_quic_fragment_too_long_fragment = -1;
173 static int hf_quic_fragment_error = -1;
174 static int hf_quic_fragment_count = -1;
175 static int hf_quic_mp_add_address_first_byte = -1;
176 static int hf_quic_mp_add_address_reserved = -1;
177 static int hf_quic_mp_add_address_port_present = -1;
178 static int hf_quic_mp_add_address_ip_version = -1;
179 static int hf_quic_mp_add_address_id = -1;
180 static int hf_quic_mp_add_address_sq_number = -1;
181 static int hf_quic_mp_add_address_interface_type = -1;
182 static int hf_quic_mp_add_address_ip_address = -1;
183 static int hf_quic_mp_add_address_ip_address_v6 = -1;
184 static int hf_quic_mp_add_address_port = -1;
185 static int hf_quic_mp_uniflow_id = -1;
186 static int hf_quic_mp_receiving_uniflows = -1;
187 static int hf_quic_mp_active_sending_uniflows = -1;
188 static int hf_quic_mp_add_local_address_id = -1;
189 static int hf_quic_mp_uniflow_info_section = -1;
190 static int hf_quic_mp_receiving_uniflow_info_section = -1;
191 static int hf_quic_mp_active_sending_uniflows_info_section = -1;
192
193 static expert_field ei_quic_connection_unknown = EI_INIT;
194 static expert_field ei_quic_ft_unknown = EI_INIT;
195 static expert_field ei_quic_decryption_failed = EI_INIT;
196 static expert_field ei_quic_protocol_violation = EI_INIT;
197 static expert_field ei_quic_bad_retry = EI_INIT;
198 static expert_field ei_quic_coalesced_padding_data = EI_INIT;
199
200 static gint ett_quic = -1;
201 static gint ett_quic_short_header = -1;
202 static gint ett_quic_connection_info = -1;
203 static gint ett_quic_ft = -1;
204 static gint ett_quic_ftflags = -1;
205 static gint ett_quic_ftid = -1;
206 static gint ett_quic_fragments = -1;
207 static gint ett_quic_fragment = -1;
208
209 static dissector_handle_t quic_handle;
210 static dissector_handle_t tls13_handshake_handle;
211
212 static dissector_table_t quic_proto_dissector_table;
213
214 #ifdef HAVE_LIBGCRYPT_AEAD
215 /* Fields for showing reassembly results for fragments of QUIC stream data. */
216 static const fragment_items quic_stream_fragment_items = {
217 &ett_quic_fragment,
218 &ett_quic_fragments,
219 &hf_quic_fragments,
220 &hf_quic_fragment,
221 &hf_quic_fragment_overlap,
222 &hf_quic_fragment_overlap_conflict,
223 &hf_quic_fragment_multiple_tails,
224 &hf_quic_fragment_too_long_fragment,
225 &hf_quic_fragment_error,
226 &hf_quic_fragment_count,
227 &hf_quic_reassembled_in,
228 &hf_quic_reassembled_length,
229 &hf_quic_reassembled_data,
230 "Fragments"
231 };
232 #endif /* HAVE_LIBGCRYPT_AEAD */
233
234 /*
235 * PROTECTED PAYLOAD DECRYPTION (done in first pass)
236 *
237 * Long packet types always use a single cipher depending on packet type.
238 * Short packet types always use 1-RTT secrets for packet protection (pp).
239 *
240 * Considerations:
241 * - QUIC packets might appear out-of-order (short packets before handshake
242 * message is captured), lost or retransmitted/duplicated.
243 * - During live capture, keys might not be immediately be available. 1-RTT
244 * client keys will be ready while client proceses Server Hello (Handshake).
245 * 1-RTT server keys will be ready while server creates Handshake message in
246 * response to Initial Handshake.
247 * - So delay cipher creation until first short packet is received.
248 *
249 * Required input from TLS dissector: TLS-Exporter 0-RTT/1-RTT secrets and
250 * cipher/hash algorithms.
251 *
252 * QUIC payload decryption requires proper reconstruction of the packet number
253 * which requires proper header decryption. The different states are:
254 *
255 * Packet type Packet number space Secrets
256 * Long: Initial Initial Initial secrets
257 * Long: Handshake Handshake Handshake
258 * Long: 0-RTT 0/1-RTT (appdata) 0-RTT
259 * Short header 0/1-RTT (appdata) 1-RTT (KP0 / KP1)
260 *
261 * Important to note is that Short Header decryption requires TWO ciphers (one
262 * for each key phase), but that header protection uses only KP0. Total state
263 * needed for each peer (client and server):
264 * - 3 packet number spaces: Initial, Handshake, 0/1-RTT (appdata).
265 * - 4 header protection ciphers: initial, 0-RTT, HS, 1-RTT.
266 * - 5 payload protection ciphers: initial, 0-RTT, HS, 1-RTT (KP0), 1-RTT (KP1).
267 */
268
269 /* Loss bits feature: https://tools.ietf.org/html/draft-ferrieuxhamchaoui-quic-lossbits-03
270 "The use of the loss bits is negotiated using a transport parameter.
271 [..]
272 When loss_bits parameter is present, the peer is allowed to use
273 reserved bits in the short packet header as loss bits if the peer
274 sends loss_bits=1.
275 When loss_bits is set to 1, the sender will use reserved bits as loss
276 bits if the peer includes the loss_bits transport parameter.
277 [..]
278 Unlike the reserved (R) bits, the loss (Q and L) bits are not
279 protected. When sending loss bits has been negotiated, the first
280 byte of the header protection mask used to protect short packet
281 headers has its five most significant bits masked out instead of
282 three.
283 */
284
285 typedef struct quic_decrypt_result {
286 const guchar *error; /**< Error message or NULL for success. */
287 const guint8 *data; /**< Decrypted result on success (file-scoped). */
288 guint data_len; /**< Size of decrypted data. */
289 } quic_decrypt_result_t;
290
291 /** QUIC decryption context. */
292
293
294 typedef struct quic_hp_cipher {
295 gcry_cipher_hd_t hp_cipher; /**< Header protection cipher. */
296 } quic_hp_cipher;
297 typedef struct quic_pp_cipher {
298 gcry_cipher_hd_t pp_cipher; /**< Packet protection cipher. */
299 guint8 pp_iv[TLS13_AEAD_NONCE_LENGTH];
300 } quic_pp_cipher;
301 typedef struct quic_ciphers {
302 quic_hp_cipher hp_cipher;
303 quic_pp_cipher pp_cipher;
304 } quic_ciphers;
305
306 /**
307 * Packet protection state for an endpoint.
308 */
309 typedef struct quic_pp_state {
310 guint8 *next_secret; /**< Next application traffic secret. */
311 quic_pp_cipher pp_ciphers[2]; /**< PP cipher for Key Phase 0/1 */
312 quic_hp_cipher hp_cipher; /**< HP cipher for both Key Phases; it does not change after KeyUpdate */
313 guint64 changed_in_pkn; /**< Packet number where key change occurred. */
314 gboolean key_phase : 1; /**< Current key phase. */
315 } quic_pp_state_t;
316
317 /** Singly-linked list of Connection IDs. */
318 typedef struct quic_cid_item quic_cid_item_t;
319 struct quic_cid_item {
320 struct quic_cid_item *next;
321 quic_cid_t data;
322 };
323
324 /**
325 * Per-STREAM state, identified by QUIC Stream ID.
326 *
327 * Assume that every QUIC Short Header packet has no STREAM frames that overlap
328 * each other in the same QUIC packet (identified by "frame_num"). Thus, the
329 * Stream ID and offset uniquely identifies the STREAM Frame info in per packet.
330 */
331 typedef struct _quic_stream_state {
332 guint64 stream_id;
333 wmem_tree_t *multisegment_pdus;
334 void *subdissector_private;
335 } quic_stream_state;
336
337 /**
338 * Data used to allow "Follow QUIC Stream" functionality
339 */
340 typedef struct _quic_follow_stream {
341 guint32 num;
342 guint64 stream_id;
343 } quic_follow_stream;
344
345 typedef struct quic_follow_tap_data {
346 tvbuff_t *tvb;
347 guint64 stream_id;
348 } quic_follow_tap_data_t;
349
350 /**
351 * State for a single QUIC connection, identified by one or more Destination
352 * Connection IDs (DCID).
353 */
354 typedef struct quic_info_data {
355 guint32 number; /** Similar to "udp.stream", but for identifying QUIC connections across migrations. */
356 guint32 version;
357 address server_address;
358 guint16 server_port;
359 gboolean skip_decryption : 1; /**< Set to 1 if no keys are available. */
360 gboolean client_dcid_set : 1; /**< Set to 1 if client_dcid_initial is set. */
361 gboolean client_loss_bits_recv : 1; /**< The client is able to read loss bits info */
362 gboolean client_loss_bits_send : 1; /**< The client wants to send loss bits info */
363 gboolean server_loss_bits_recv : 1; /**< The server is able to read loss bits info */
364 gboolean server_loss_bits_send : 1; /**< The server wants to send loss bits info */
365 int hash_algo; /**< Libgcrypt hash algorithm for key derivation. */
366 int cipher_algo; /**< Cipher algorithm for packet number and packet encryption. */
367 int cipher_mode; /**< Cipher mode for packet encryption. */
368 quic_ciphers client_initial_ciphers;
369 quic_ciphers server_initial_ciphers;
370 quic_ciphers client_0rtt_ciphers;
371 quic_ciphers client_handshake_ciphers;
372 quic_ciphers server_handshake_ciphers;
373 quic_pp_state_t client_pp;
374 quic_pp_state_t server_pp;
375 guint64 max_client_pkn[3]; /**< Packet number spaces for Initial, Handshake and appdata. */
376 guint64 max_server_pkn[3];
377 quic_cid_item_t client_cids; /**< SCID of client from first Initial Packet. */
378 quic_cid_item_t server_cids; /**< SCID of server from first Retry/Handshake. */
379 quic_cid_t client_dcid_initial; /**< DCID from Initial Packet. */
380 dissector_handle_t app_handle; /**< Application protocol handle (NULL if unknown). */
381 wmem_map_t *client_streams; /**< Map from Stream ID -> STREAM info (guint64 -> quic_stream_state), sent by the client. */
382 wmem_map_t *server_streams; /**< Map from Stream ID -> STREAM info (guint64 -> quic_stream_state), sent by the server. */
383 wmem_list_t *streams_list; /**< Ordered list of QUIC Stream ID in this connection (both directions). Used by "Follow QUIC Stream" functionality */
384 wmem_map_t *streams_map; /**< Map pinfo->num --> First stream in that frame (guint -> quic_follow_stream). Used by "Follow QUIC Stream" functionality */
385 gquic_info_data_t *gquic_info; /**< GQUIC info for >Q050 flows. */
386 } quic_info_data_t;
387
388 /** Per-packet information about QUIC, populated on the first pass. */
389 struct quic_packet_info {
390 struct quic_packet_info *next;
391 guint64 packet_number; /**< Reconstructed full packet number. */
392 quic_decrypt_result_t decryption;
393 guint8 pkn_len; /**< Length of PKN (1/2/3/4) or unknown (0). */
394 guint8 first_byte; /**< Decrypted flag byte, valid only if pkn_len is non-zero. */
395 gboolean retry_integrity_failure : 1;
396 gboolean retry_integrity_success : 1;
397 };
398 typedef struct quic_packet_info quic_packet_info_t;
399
400 /** A UDP datagram contains one or more QUIC packets. */
401 typedef struct quic_datagram {
402 quic_info_data_t *conn;
403 quic_packet_info_t first_packet;
404 gboolean from_server : 1;
405 } quic_datagram;
406
407 /**
408 * Maps CID (quic_cid_t *) to a QUIC Connection (quic_info_data_t *).
409 * This assumes that the CIDs are not shared between two different connections
410 * (potentially with different versions) as that would break dissection.
411 *
412 * These mappings are authorative. For example, Initial.SCID is stored in
413 * quic_client_connections while Retry.SCID is stored in
414 * quic_server_connections. Retry.DCID should normally correspond to an entry in
415 * quic_client_connections.
416 */
417 static wmem_map_t *quic_client_connections, *quic_server_connections;
418 static wmem_map_t *quic_initial_connections; /* Initial.DCID -> connection */
419 static wmem_list_t *quic_connections; /* All unique connections. */
420 static guint32 quic_cid_lengths; /* Bitmap of CID lengths. */
421 static guint quic_connections_count;
422
423 /* Returns the QUIC draft version or 0 if not applicable. */
quic_draft_version(guint32 version)424 static inline guint8 quic_draft_version(guint32 version) {
425 /* IETF Draft versions */
426 if ((version >> 8) == 0xff0000) {
427 return (guint8) version;
428 }
429 /* Facebook mvfst, based on draft -22. */
430 if (version == 0xfaceb001) {
431 return 22;
432 }
433 /* Facebook mvfst, based on draft -27. */
434 if (version == 0xfaceb002 || version == 0xfaceb00e) {
435 return 27;
436 }
437 /* GQUIC Q050, T050 and T051: they are not really based on any drafts,
438 * but we must return a sensible value */
439 if (version == 0x51303530 ||
440 version == 0x54303530 ||
441 version == 0x54303531) {
442 return 27;
443 }
444 /* https://tools.ietf.org/html/draft-ietf-quic-transport-32#section-15
445 "Versions that follow the pattern 0x?a?a?a?a are reserved for use in
446 forcing version negotiation to be exercised"
447 It is tricky to return a correct draft version: such number is primarly
448 used to select a proper salt (which depends on the version itself), but
449 we don't have a real version here! Let's hope that we need to handle
450 only latest drafts... */
451 if ((version & 0x0F0F0F0F) == 0x0a0a0a0a) {
452 return 29;
453 }
454 /* QUIC (final?) constants for v1 are defined in draft-33 */
455 if (version == 0x00000001) {
456 return 33;
457 }
458 return 0;
459 }
460
is_quic_draft_max(guint32 version,guint8 max_version)461 static inline gboolean is_quic_draft_max(guint32 version, guint8 max_version) {
462 guint8 draft_version = quic_draft_version(version);
463 return draft_version && draft_version <= max_version;
464 }
465
466 const range_string quic_version_vals[] = {
467 { 0x00000000, 0x00000000, "Version Negotiation" },
468 { 0x00000001, 0x00000001, "1" },
469 { 0x45474700, 0x454747ff, "Quant" },
470 { 0x50435130, 0x50435131, "Picoquic internal" },
471 { 0x50524f58, 0x50524f58, "Proxied QUIC (PROX)" },
472 /* Versions QXXX < Q050 are dissected by Wireshark as GQUIC and not as QUIC.
473 Nonetheless, some implementations report these values in "Version Negotiation"
474 packets, so decode these fields */
475 { 0x51303433, 0x51303433, "Google Q043" },
476 { 0x51303434, 0x51303434, "Google Q044" },
477 { 0x51303436, 0x51303436, "Google Q046" },
478 { 0x51303530, 0x51303530, "Google Q050" },
479 { 0x51474f00, 0x51474fff, "QGO (QUIC GO)" },
480 { 0x54303530, 0x54303530, "Google T050" },
481 { 0x54303531, 0x54303531, "Google T051" },
482 { 0x91c17000, 0x91c170ff, "Quicly" },
483 { 0xabcd0000, 0xabcd000f, "MsQuic" },
484 { 0xf0f0f0f0, 0xf0f0f0ff, "ETH Zürich (Measurability experiments)" },
485 { 0xf0f0f1f0, 0xf0f0f1ff, "Telecom Italia (Measurability experiments)" },
486 { 0xf123f0c0, 0xf123f0cf, "MozQuic" },
487 { 0xfaceb001, 0xfaceb001, "Facebook mvfst (draft-22)" },
488 { 0xfaceb002, 0xfaceb002, "Facebook mvfst (draft-27)" },
489 { 0xfaceb003, 0xfaceb00d, "Facebook mvfst" },
490 { 0xfaceb00e, 0xfaceb00e, "Facebook mvfst (Experimental)" },
491 { 0xfaceb00f, 0xfaceb00f, "Facebook mvfst" },
492 { 0xff000004, 0xff000004, "draft-04" },
493 { 0xff000005, 0xff000005, "draft-05" },
494 { 0xff000006, 0xff000006, "draft-06" },
495 { 0xff000007, 0xff000007, "draft-07" },
496 { 0xff000008, 0xff000008, "draft-08" },
497 { 0xff000009, 0xff000009, "draft-09" },
498 { 0xff00000a, 0xff00000a, "draft-10" },
499 { 0xff00000b, 0xff00000b, "draft-11" },
500 { 0xff00000c, 0xff00000c, "draft-12" },
501 { 0xff00000d, 0xff00000d, "draft-13" },
502 { 0xff00000e, 0xff00000e, "draft-14" },
503 { 0xff00000f, 0xff00000f, "draft-15" },
504 { 0xff000010, 0xff000010, "draft-16" },
505 { 0xff000011, 0xff000011, "draft-17" },
506 { 0xff000012, 0xff000012, "draft-18" },
507 { 0xff000013, 0xff000013, "draft-19" },
508 { 0xff000014, 0xff000014, "draft-20" },
509 { 0xff000015, 0xff000015, "draft-21" },
510 { 0xff000016, 0xff000016, "draft-22" },
511 { 0xff000017, 0xff000017, "draft-23" },
512 { 0xff000018, 0xff000018, "draft-24" },
513 { 0xff000019, 0xff000019, "draft-25" },
514 { 0xff00001a, 0xff00001a, "draft-26" },
515 { 0xff00001b, 0xff00001b, "draft-27" },
516 { 0xff00001c, 0xff00001c, "draft-28" },
517 { 0xff00001d, 0xff00001d, "draft-29" },
518 { 0xff00001e, 0xff00001e, "draft-30" },
519 { 0xff00001f, 0xff00001f, "draft-31" },
520 { 0xff000020, 0xff000020, "draft-32" },
521 { 0xff000021, 0xff000021, "draft-33" },
522 { 0xff000022, 0xff000022, "draft-34" },
523 { 0, 0, NULL }
524 };
525
526 static const value_string quic_short_long_header_vals[] = {
527 { 0, "Short Header" },
528 { 1, "Long Header" },
529 { 0, NULL }
530 };
531
532 #define SH_KP 0x04
533
534 #define QUIC_LPT_INITIAL 0x0
535 #define QUIC_LPT_0RTT 0x1
536 #define QUIC_LPT_HANDSHAKE 0x2
537 #define QUIC_LPT_RETRY 0x3
538 #define QUIC_LPT_VER_NEG 0xfe /* Version Negotiation packets don't have any real packet type */
539 #define QUIC_SHORT_PACKET 0xff /* dummy value that is definitely not LPT */
540
541 static const value_string quic_long_packet_type_vals[] = {
542 { QUIC_LPT_INITIAL, "Initial" },
543 { QUIC_LPT_RETRY, "Retry" },
544 { QUIC_LPT_HANDSHAKE, "Handshake" },
545 { QUIC_LPT_0RTT, "0-RTT" },
546 /* Version Negotiation packets never use this mapping, so no need to add QUIC_LPT_VER_NEG */
547 { 0, NULL }
548 };
549
550 /* https://github.com/quicwg/base-drafts/wiki/Temporary-IANA-Registry#quic-frame-types */
551 #define FT_PADDING 0x00
552 #define FT_PING 0x01
553 #define FT_ACK 0x02
554 #define FT_ACK_ECN 0x03
555 #define FT_RESET_STREAM 0x04
556 #define FT_STOP_SENDING 0x05
557 #define FT_CRYPTO 0x06
558 #define FT_NEW_TOKEN 0x07
559 #define FT_STREAM_8 0x08
560 #define FT_STREAM_9 0x09
561 #define FT_STREAM_A 0x0a
562 #define FT_STREAM_B 0x0b
563 #define FT_STREAM_C 0x0c
564 #define FT_STREAM_D 0x0d
565 #define FT_STREAM_E 0x0e
566 #define FT_STREAM_F 0x0f
567 #define FT_MAX_DATA 0x10
568 #define FT_MAX_STREAM_DATA 0x11
569 #define FT_MAX_STREAMS_BIDI 0x12
570 #define FT_MAX_STREAMS_UNI 0x13
571 #define FT_DATA_BLOCKED 0x14
572 #define FT_STREAM_DATA_BLOCKED 0x15
573 #define FT_STREAMS_BLOCKED_BIDI 0x16
574 #define FT_STREAMS_BLOCKED_UNI 0x17
575 #define FT_NEW_CONNECTION_ID 0x18
576 #define FT_RETIRE_CONNECTION_ID 0x19
577 #define FT_PATH_CHALLENGE 0x1a
578 #define FT_PATH_RESPONSE 0x1b
579 #define FT_CONNECTION_CLOSE_TPT 0x1c
580 #define FT_CONNECTION_CLOSE_APP 0x1d
581 #define FT_HANDSHAKE_DONE 0x1e
582 #define FT_DATAGRAM 0x30
583 #define FT_MP_NEW_CONNECTION_ID 0x40
584 #define FT_MP_RETIRE_CONNECTION_ID 0x41
585 #define FT_MP_ACK 0x42
586 #define FT_MP_ACK_ECN 0x43
587 #define FT_ADD_ADDRESS 0x44
588 #define FT_REMOVE_ADDRESS 0x45
589 #define FT_UNIFLOWS 0x46
590 #define FT_DATAGRAM_LENGTH 0x31
591 #define FT_ACK_FREQUENCY 0xAF
592 #define FT_TIME_STAMP 0x02F5
593
594 static const range_string quic_frame_type_vals[] = {
595 { 0x00, 0x00, "PADDING" },
596 { 0x01, 0x01, "PING" },
597 { 0x02, 0x03, "ACK" },
598 { 0x04, 0x04, "RESET_STREAM" },
599 { 0x05, 0x05, "STOP_SENDING" },
600 { 0x06, 0x06, "CRYPTO" },
601 { 0x07, 0x07, "NEW_TOKEN" },
602 { 0x08, 0x0f, "STREAM" },
603 { 0x10, 0x10, "MAX_DATA" },
604 { 0x11, 0x11, "MAX_STREAM_DATA" },
605 { 0x12, 0x12, "MAX_STREAMS (BIDI)" },
606 { 0x13, 0x13, "MAX_STREAMS (UNI)" },
607 { 0x14, 0x14, "DATA_BLOCKED" },
608 { 0x15, 0x15, "STREAM_DATA_BLOCKED" },
609 { 0x16, 0x16, "STREAMS_BLOCKED (BIDI)" },
610 { 0x16, 0x17, "STREAMS_BLOCKED (UNI)" },
611 { 0x18, 0x18, "NEW_CONNECTION_ID" },
612 { 0x19, 0x19, "RETIRE_CONNECTION_ID" },
613 { 0x1a, 0x1a, "PATH_CHALLENGE" },
614 { 0x1b, 0x1b, "PATH_RESPONSE" },
615 { 0x1c, 0x1c, "CONNECTION_CLOSE (Transport)" },
616 { 0x1d, 0x1d, "CONNECTION_CLOSE (Application)" },
617 { 0x1e, 0x1e, "HANDSHAKE_DONE" },
618 { 0x30, 0x31, "DATAGRAM" },
619 { 0x40, 0x40, "MP_NEW_CONNECTION_ID" },
620 { 0x41, 0x41, "MP_RETIRE_CONNECTION_ID" },
621 { 0x42, 0x43, "MP_ACK" },
622 { 0x44, 0x44, "ADD_ADDRESS" },
623 { 0x45, 0x45, "REMOVE_ADDRESS" },
624 { 0x46, 0x46, "UNIFLOWS" },
625 { 0xaf, 0xaf, "ACK_FREQUENCY" },
626 { 0x02f5, 0x02f5, "TIME_STAMP" },
627 { 0, 0, NULL },
628 };
629
630
631 /* >= draft-08 */
632 #define FTFLAGS_STREAM_FIN 0x01
633 #define FTFLAGS_STREAM_LEN 0x02
634 #define FTFLAGS_STREAM_OFF 0x04
635
636 #define FTFLAGS_STREAM_INITIATOR 0x01
637 #define FTFLAGS_STREAM_DIRECTION 0x02
638
639 static const range_string quic_transport_error_code_vals[] = {
640 /* 0x00 - 0x3f Assigned via Standards Action or IESG Review policies. */
641 { 0x0000, 0x0000, "NO_ERROR" },
642 { 0x0001, 0x0001, "INTERNAL_ERROR" },
643 { 0x0002, 0x0002, "CONNECTION_REFUSED" },
644 { 0x0003, 0x0003, "FLOW_CONTROL_ERROR" },
645 { 0x0004, 0x0004, "STREAM_ID_ERROR" },
646 { 0x0005, 0x0005, "STREAM_STATE_ERROR" },
647 { 0x0006, 0x0006, "FINAL_SIZE_ERROR" },
648 { 0x0007, 0x0007, "FRAME_ENCODING_ERROR" },
649 { 0x0008, 0x0008, "TRANSPORT_PARAMETER_ERROR" },
650 { 0x0009, 0x0009, "CONNECTION_ID_LIMIT_ERROR" },
651 { 0x000a, 0x000a, "PROTOCOL_VIOLATION" },
652 { 0x000b, 0x000b, "INVALID_TOKEN" },
653 { 0x000c, 0x000c, "APPLICATION_ERROR" },
654 { 0x000d, 0x000d, "CRYPTO_BUFFER_EXCEEDED" },
655 { 0x000e, 0x000e, "KEY_UPDATE_ERROR" },
656 { 0x000f, 0x000f, "AEAD_LIMIT_REACHED" },
657 { 0x0010, 0x0010, "NO_VIABLE_PATH" },
658 { 0x0100, 0x01ff, "CRYPTO_ERROR" },
659 /* 0x40 - 0x3fff Assigned via Specification Required policy. */
660 { 0x53F8, 0x53F8, "VERSION_NEGOTIATION_ERROR" },
661 { 0, 0, NULL }
662 };
663
664 static const value_string quic_packet_number_lengths[] = {
665 { 0, "1 bytes" },
666 { 1, "2 bytes" },
667 { 2, "3 bytes" },
668 { 3, "4 bytes" },
669 { 0, NULL }
670 };
671
672 static const val64_string quic_frame_id_initiator[] = {
673 { 0, "Client-initiated" },
674 { 1, "Server-initiated" },
675 { 0, NULL }
676 };
677
678 static const val64_string quic_frame_id_direction[] = {
679 { 0, "Bidirectional" },
680 { 1, "Unidirectional" },
681 { 0, NULL }
682 };
683
684 static void
685 quic_extract_header(tvbuff_t *tvb, guint8 *long_packet_type, guint32 *version,
686 quic_cid_t *dcid, quic_cid_t *scid);
687
688 #ifdef HAVE_LIBGCRYPT_AEAD
689 static void
690 quic_streams_add(packet_info *pinfo, quic_info_data_t *quic_info, guint64 stream_id);
691 #endif
692
693 static void
quic_hp_cipher_reset(quic_hp_cipher * hp_cipher)694 quic_hp_cipher_reset(quic_hp_cipher *hp_cipher)
695 {
696 gcry_cipher_close(hp_cipher->hp_cipher);
697 memset(hp_cipher, 0, sizeof(*hp_cipher));
698 }
699 static void
quic_pp_cipher_reset(quic_pp_cipher * pp_cipher)700 quic_pp_cipher_reset(quic_pp_cipher *pp_cipher)
701 {
702 gcry_cipher_close(pp_cipher->pp_cipher);
703 memset(pp_cipher, 0, sizeof(*pp_cipher));
704 }
705 static void
quic_ciphers_reset(quic_ciphers * ciphers)706 quic_ciphers_reset(quic_ciphers *ciphers)
707 {
708 quic_hp_cipher_reset(&ciphers->hp_cipher);
709 quic_pp_cipher_reset(&ciphers->pp_cipher);
710 }
711
712 #ifdef HAVE_LIBGCRYPT_AEAD
713 static gboolean
quic_is_hp_cipher_initialized(quic_hp_cipher * hp_cipher)714 quic_is_hp_cipher_initialized(quic_hp_cipher *hp_cipher)
715 {
716 return hp_cipher && hp_cipher->hp_cipher;
717 }
718 static gboolean
quic_is_pp_cipher_initialized(quic_pp_cipher * pp_cipher)719 quic_is_pp_cipher_initialized(quic_pp_cipher *pp_cipher)
720 {
721 return pp_cipher && pp_cipher->pp_cipher;
722 }
723 static gboolean
quic_are_ciphers_initialized(quic_ciphers * ciphers)724 quic_are_ciphers_initialized(quic_ciphers *ciphers)
725 {
726 return ciphers &&
727 quic_is_hp_cipher_initialized(&ciphers->hp_cipher) &&
728 quic_is_pp_cipher_initialized(&ciphers->pp_cipher);
729 }
730
731 /* Inspired from ngtcp2 */
quic_pkt_adjust_pkt_num(guint64 max_pkt_num,guint64 pkt_num,size_t n)732 static guint64 quic_pkt_adjust_pkt_num(guint64 max_pkt_num, guint64 pkt_num,
733 size_t n) {
734 guint64 k = max_pkt_num == G_MAXUINT64 ? max_pkt_num : max_pkt_num + 1;
735 guint64 u = k & ~((G_GUINT64_CONSTANT(1) << n) - 1);
736 guint64 a = u | pkt_num;
737 guint64 b = (u + (G_GUINT64_CONSTANT(1) << n)) | pkt_num;
738 guint64 a1 = k < a ? a - k : k - a;
739 guint64 b1 = k < b ? b - k : k - b;
740
741 if (a1 < b1) {
742 return a;
743 }
744 return b;
745 }
746
747 /**
748 * Given a header protection cipher, a buffer and the packet number offset,
749 * return the unmasked first byte and packet number.
750 * If the loss bits feature is enabled, the protected bits in the first byte
751 * are fewer than usual: 3 instead of 5 (on short headers only)
752 */
753 static gboolean
quic_decrypt_header(tvbuff_t * tvb,guint pn_offset,quic_hp_cipher * hp_cipher,int hp_cipher_algo,guint8 * first_byte,guint32 * pn,gboolean loss_bits_negotiated)754 quic_decrypt_header(tvbuff_t *tvb, guint pn_offset, quic_hp_cipher *hp_cipher, int hp_cipher_algo,
755 guint8 *first_byte, guint32 *pn, gboolean loss_bits_negotiated)
756 {
757 if (!hp_cipher->hp_cipher) {
758 // need to know the cipher.
759 return FALSE;
760 }
761 gcry_cipher_hd_t h = hp_cipher->hp_cipher;
762
763 // Sample is always 16 bytes and starts after PKN (assuming length 4).
764 // https://tools.ietf.org/html/draft-ietf-quic-tls-22#section-5.4.2
765 guint8 sample[16];
766 tvb_memcpy(tvb, sample, pn_offset + 4, 16);
767
768 guint8 mask[5] = { 0 };
769 switch (hp_cipher_algo) {
770 case GCRY_CIPHER_AES128:
771 case GCRY_CIPHER_AES256:
772 /* Encrypt in-place with AES-ECB and extract the mask. */
773 if (gcry_cipher_encrypt(h, sample, sizeof(sample), NULL, 0)) {
774 return FALSE;
775 }
776 memcpy(mask, sample, sizeof(mask));
777 break;
778 #ifdef HAVE_LIBGCRYPT_CHACHA20
779 case GCRY_CIPHER_CHACHA20:
780 /* If Gcrypt receives a 16 byte IV, it will assume the buffer to be
781 * counter || nonce (in little endian), as desired. */
782 if (gcry_cipher_setiv(h, sample, 16)) {
783 return FALSE;
784 }
785 /* Apply ChaCha20, encrypt in-place five zero bytes. */
786 if (gcry_cipher_encrypt(h, mask, sizeof(mask), NULL, 0)) {
787 return FALSE;
788 }
789 break;
790 #endif /* HAVE_LIBGCRYPT_CHACHA20 */
791 default:
792 return FALSE;
793 }
794
795 // https://tools.ietf.org/html/draft-ietf-quic-tls-22#section-5.4.1
796 guint8 packet0 = tvb_get_guint8(tvb, 0);
797 if ((packet0 & 0x80) == 0x80) {
798 // Long header: 4 bits masked
799 packet0 ^= mask[0] & 0x0f;
800 } else {
801 // Short header
802 if (loss_bits_negotiated == FALSE) {
803 // Standard mask: 5 bits masked
804 packet0 ^= mask[0] & 0x1F;
805 } else {
806 // https://tools.ietf.org/html/draft-ferrieuxhamchaoui-quic-lossbits-03#section-5.3
807 packet0 ^= mask[0] & 0x07;
808 }
809 }
810 guint pkn_len = (packet0 & 0x03) + 1;
811
812 guint8 pkn_bytes[4];
813 tvb_memcpy(tvb, pkn_bytes, pn_offset, pkn_len);
814 guint32 pkt_pkn = 0;
815 for (guint i = 0; i < pkn_len; i++) {
816 pkt_pkn |= (pkn_bytes[i] ^ mask[1 + i]) << (8 * (pkn_len - 1 - i));
817 }
818 *first_byte = packet0;
819 *pn = pkt_pkn;
820 return TRUE;
821 }
822
823 /**
824 * Retrieve the maximum valid packet number space for a peer.
825 */
826 static guint64 *
quic_max_packet_number(quic_info_data_t * quic_info,gboolean from_server,guint8 first_byte)827 quic_max_packet_number(quic_info_data_t *quic_info, gboolean from_server, guint8 first_byte)
828 {
829 int pkn_space;
830 if ((first_byte & 0x80) && (first_byte & 0x30) >> 4 == QUIC_LPT_INITIAL) {
831 // Long header, Initial
832 pkn_space = 0;
833 } else if ((first_byte & 0x80) && (first_byte & 0x30) >> 4 == QUIC_LPT_HANDSHAKE) {
834 // Long header, Handshake
835 pkn_space = 1;
836 } else {
837 // Long header (0-RTT) or Short Header (1-RTT appdata).
838 pkn_space = 2;
839 }
840 if (from_server) {
841 return &quic_info->max_server_pkn[pkn_space];
842 } else {
843 return &quic_info->max_client_pkn[pkn_space];
844 }
845 }
846
847 /**
848 * Calculate the full packet number and store it for later use.
849 */
850 static void
quic_set_full_packet_number(quic_info_data_t * quic_info,quic_packet_info_t * quic_packet,gboolean from_server,guint8 first_byte,guint32 pkn32)851 quic_set_full_packet_number(quic_info_data_t *quic_info, quic_packet_info_t *quic_packet,
852 gboolean from_server, guint8 first_byte, guint32 pkn32)
853 {
854 guint pkn_len = (first_byte & 3) + 1;
855 guint64 pkn_full;
856 guint64 max_pn = *quic_max_packet_number(quic_info, from_server, first_byte);
857
858 /* Sequential first pass, try to reconstruct full packet number. */
859 pkn_full = quic_pkt_adjust_pkt_num(max_pn, pkn32, 8 * pkn_len);
860 quic_packet->pkn_len = pkn_len;
861 quic_packet->packet_number = pkn_full;
862 }
863 #endif /* HAVE_LIBGCRYPT_AEAD */
864
865 static const char *
cid_to_string(const quic_cid_t * cid)866 cid_to_string(const quic_cid_t *cid)
867 {
868 if (cid->len == 0) {
869 return "(none)";
870 }
871 char *str = (char *)wmem_alloc0(wmem_packet_scope(), 2 * cid->len + 1);
872 bytes_to_hexstr(str, cid->cid, cid->len);
873 return str;
874 }
875
876 /* QUIC Connection tracking. {{{ */
877 static guint
quic_connection_hash(gconstpointer key)878 quic_connection_hash(gconstpointer key)
879 {
880 const quic_cid_t *cid = (const quic_cid_t *)key;
881
882 return wmem_strong_hash((const guint8 *)cid, sizeof(quic_cid_t) - sizeof(cid->cid) + cid->len);
883 }
884
885 static gboolean
quic_connection_equal(gconstpointer a,gconstpointer b)886 quic_connection_equal(gconstpointer a, gconstpointer b)
887 {
888 const quic_cid_t *cid1 = (const quic_cid_t *)a;
889 const quic_cid_t *cid2 = (const quic_cid_t *)b;
890
891 return cid1->len == cid2->len && !memcmp(cid1->cid, cid2->cid, cid1->len);
892 }
893
894 static gboolean
quic_cids_has_match(const quic_cid_item_t * items,const quic_cid_t * raw_cid)895 quic_cids_has_match(const quic_cid_item_t *items, const quic_cid_t *raw_cid)
896 {
897 while (items) {
898 const quic_cid_t *cid = &items->data;
899 // "raw_cid" potentially has some trailing data that is not part of the
900 // actual CID, so accept any prefix match against "cid".
901 // Note that this explicitly matches an empty CID.
902 if (raw_cid->len >= cid->len && !memcmp(raw_cid->cid, cid->cid, cid->len)) {
903 return TRUE;
904 }
905 items = items->next;
906 }
907 return FALSE;
908 }
909
910 static void
quic_cids_insert(quic_cid_t * cid,quic_info_data_t * conn,gboolean from_server)911 quic_cids_insert(quic_cid_t *cid, quic_info_data_t *conn, gboolean from_server)
912 {
913 wmem_map_t *connections = from_server ? quic_server_connections : quic_client_connections;
914 // Replace any previous CID key with the new one.
915 wmem_map_remove(connections, cid);
916 wmem_map_insert(connections, cid, conn);
917 G_STATIC_ASSERT(QUIC_MAX_CID_LENGTH <= 8 * sizeof(quic_cid_lengths));
918 quic_cid_lengths |= (1ULL << cid->len);
919 }
920
921 static inline gboolean
quic_cids_is_known_length(const quic_cid_t * cid)922 quic_cids_is_known_length(const quic_cid_t *cid)
923 {
924 return (quic_cid_lengths & (1ULL << cid->len)) != 0;
925 }
926
927 /**
928 * Returns the QUIC connection for the current UDP stream. This may return NULL
929 * after connection migration if the new UDP association was not properly linked
930 * via a match based on the Connection ID.
931 */
932 static quic_info_data_t *
quic_connection_from_conv(packet_info * pinfo)933 quic_connection_from_conv(packet_info *pinfo)
934 {
935 conversation_t *conv = find_conversation_pinfo(pinfo, 0);
936 if (conv) {
937 return (quic_info_data_t *)conversation_get_proto_data(conv, proto_quic);
938 }
939 return NULL;
940 }
941
942 /**
943 * Tries to lookup a matching connection (Connection ID is optional).
944 * If connection is found, "from_server" is set accordingly.
945 */
946 static quic_info_data_t *
quic_connection_find_dcid(packet_info * pinfo,const quic_cid_t * dcid,gboolean * from_server)947 quic_connection_find_dcid(packet_info *pinfo, const quic_cid_t *dcid, gboolean *from_server)
948 {
949 /* https://tools.ietf.org/html/draft-ietf-quic-transport-22#section-5.2
950 *
951 * "If the packet has a Destination Connection ID corresponding to an
952 * existing connection, QUIC processes that packet accordingly."
953 * "If the Destination Connection ID is zero length and the packet matches
954 * the address/port tuple of a connection where the host did not require
955 * connection IDs, QUIC processes the packet as part of that connection."
956 */
957 quic_info_data_t *conn = NULL;
958 gboolean check_ports = FALSE;
959
960 if (dcid && dcid->len > 0) {
961 // Optimization: avoid lookup for invalid CIDs.
962 if (!quic_cids_is_known_length(dcid)) {
963 return NULL;
964 }
965 conn = (quic_info_data_t *) wmem_map_lookup(quic_client_connections, dcid);
966 if (conn) {
967 // DCID recognized by client, so it was from server.
968 *from_server = TRUE;
969 // On collision (both client and server choose the same CID), check
970 // the port to learn about the side.
971 // This is required for supporting draft -10 which has a single CID.
972 check_ports = !!wmem_map_lookup(quic_server_connections, dcid);
973 } else {
974 conn = (quic_info_data_t *) wmem_map_lookup(quic_server_connections, dcid);
975 if (conn) {
976 // DCID recognized by server, so it was from client.
977 *from_server = FALSE;
978 }
979 }
980 } else {
981 conn = quic_connection_from_conv(pinfo);
982 if (conn) {
983 check_ports = TRUE;
984 }
985 }
986
987 if (check_ports) {
988 *from_server = conn->server_port == pinfo->srcport &&
989 addresses_equal(&conn->server_address, &pinfo->src);
990 }
991
992 return conn;
993 }
994
995 /**
996 * Try to find a QUIC connection based on DCID. For short header packets, DCID
997 * will be modified in order to find the actual length.
998 * DCID can be empty, in that case a connection is looked up by address only.
999 */
1000 static quic_info_data_t *
quic_connection_find(packet_info * pinfo,guint8 long_packet_type,quic_cid_t * dcid,gboolean * from_server)1001 quic_connection_find(packet_info *pinfo, guint8 long_packet_type,
1002 quic_cid_t *dcid, gboolean *from_server)
1003 {
1004 gboolean is_long_packet = long_packet_type != QUIC_SHORT_PACKET;
1005 quic_info_data_t *conn = NULL;
1006
1007 if (long_packet_type == QUIC_LPT_0RTT && dcid->len > 0) {
1008 // The 0-RTT packet always matches the SCID/DCID of the Client Initial
1009 conn = (quic_info_data_t *) wmem_map_lookup(quic_initial_connections, dcid);
1010 *from_server = FALSE;
1011 } else {
1012 // Find a connection for Handshake, Version Negotiation and Server Initial packets by
1013 // matching their DCID against the SCIDs of the original Initial packets
1014 // from the peer. For Client Initial packets, match DCID of the first
1015 // Client Initial (these may contain ACK frames).
1016 conn = quic_connection_find_dcid(pinfo, dcid, from_server);
1017 if (long_packet_type == QUIC_LPT_INITIAL && conn && !*from_server && dcid->len > 0 &&
1018 memcmp(dcid, &conn->client_dcid_initial, sizeof(quic_cid_t)) &&
1019 !quic_cids_has_match(&conn->server_cids, dcid)) {
1020 // If the Initial Packet is from the client, it must either match
1021 // the DCID from the first Client Initial, or the DCID that was
1022 // assigned by the server. Otherwise this must be considered a fresh
1023 // Client Initial, for example after the Version Negotiation packet,
1024 // and the connection must be cleared to avoid decryption failure.
1025 conn = NULL;
1026 }
1027 }
1028
1029 if (!is_long_packet && !conn) {
1030 // For short packets, first try to find a match based on the address.
1031 conn = quic_connection_find_dcid(pinfo, NULL, from_server);
1032 if (conn) {
1033 if ((*from_server && !quic_cids_has_match(&conn->client_cids, dcid)) ||
1034 (!*from_server && !quic_cids_has_match(&conn->server_cids, dcid))) {
1035 // Connection does not match packet.
1036 conn = NULL;
1037 }
1038 }
1039
1040 // No match found so far, potentially connection migration. Length of
1041 // actual DCID is unknown, so just keep decrementing until found.
1042 while (!conn && dcid->len > 1) {
1043 dcid->len--;
1044 if (quic_cids_is_known_length(dcid)) {
1045 conn = quic_connection_find_dcid(pinfo, dcid, from_server);
1046 }
1047 }
1048 if (!conn) {
1049 // No match found, truncate DCID (not really needed, but this
1050 // ensures that debug prints clearly show that DCID is invalid).
1051 dcid->len = 0;
1052 }
1053 }
1054 return conn;
1055 }
1056
1057 /** Create a new QUIC Connection based on a Client Initial packet. */
1058 static quic_info_data_t *
quic_connection_create(packet_info * pinfo,guint32 version)1059 quic_connection_create(packet_info *pinfo, guint32 version)
1060 {
1061 quic_info_data_t *conn = NULL;
1062
1063 conn = wmem_new0(wmem_file_scope(), quic_info_data_t);
1064 wmem_list_append(quic_connections, conn);
1065 conn->number = quic_connections_count++;
1066 conn->version = version;
1067 copy_address_wmem(wmem_file_scope(), &conn->server_address, &pinfo->dst);
1068 conn->server_port = pinfo->destport;
1069
1070 // For faster lookups without having to check DCID
1071 conversation_t *conv = find_or_create_conversation(pinfo);
1072 conversation_add_proto_data(conv, proto_quic, conn);
1073
1074 if (version == 0x51303530 || version == 0x54303530 || version == 0x54303531) {
1075 gquic_info_data_t *gquic_info;
1076
1077 gquic_info = wmem_new(wmem_file_scope(), gquic_info_data_t);
1078 if (version == 0x51303530)
1079 gquic_info->version = 50;
1080 else if (version == 0x54303530)
1081 gquic_info->version = 150;
1082 else
1083 gquic_info->version = 151;
1084 gquic_info->encoding = ENC_BIG_ENDIAN;
1085 gquic_info->version_valid = TRUE;
1086 gquic_info->server_port = pinfo->destport;
1087 conn->gquic_info = gquic_info;
1088 }
1089
1090 return conn;
1091 }
1092
1093 /** Update client/server connection identifiers, assuming the information is
1094 * from the Client Initial. */
1095 static void
quic_connection_update_initial(quic_info_data_t * conn,const quic_cid_t * scid,const quic_cid_t * dcid)1096 quic_connection_update_initial(quic_info_data_t *conn, const quic_cid_t *scid, const quic_cid_t *dcid)
1097 {
1098 // Key connection by Client CID (if provided).
1099 if (scid->len) {
1100 memcpy(&conn->client_cids.data, scid, sizeof(quic_cid_t));
1101 quic_cids_insert(&conn->client_cids.data, conn, FALSE);
1102 }
1103 if (dcid->len > 0) {
1104 // According to the spec, the Initial Packet DCID MUST be at least 8
1105 // bytes, but non-conforming implementations could exist.
1106 memcpy(&conn->client_dcid_initial, dcid, sizeof(quic_cid_t));
1107 wmem_map_insert(quic_initial_connections, &conn->client_dcid_initial, conn);
1108 conn->client_dcid_set = TRUE;
1109 }
1110 }
1111
1112 #ifdef HAVE_LIBGCRYPT_AEAD
1113 /**
1114 * Use the new CID as additional identifier for the specified connection and
1115 * remember it for connection tracking.
1116 */
1117 static void
quic_connection_add_cid(quic_info_data_t * conn,const quic_cid_t * new_cid,gboolean from_server)1118 quic_connection_add_cid(quic_info_data_t *conn, const quic_cid_t *new_cid, gboolean from_server)
1119 {
1120 DISSECTOR_ASSERT(new_cid->len > 0);
1121 quic_cid_item_t *items = from_server ? &conn->server_cids : &conn->client_cids;
1122
1123 if (quic_cids_has_match(items, new_cid)) {
1124 // CID is already known for this connection.
1125 return;
1126 }
1127
1128 // Insert new CID right after the first known CID (the very first CID cannot
1129 // be overwritten since it might be used as key somewhere else).
1130 quic_cid_item_t *new_item = wmem_new0(wmem_file_scope(), quic_cid_item_t);
1131 new_item->data = *new_cid;
1132 new_item->next = items->next;
1133 items->next = new_item;
1134
1135 quic_cids_insert(&new_item->data, conn, from_server);
1136 }
1137 #endif /* HAVE_LIBGCRYPT_AEAD */
1138
1139 /** Create or update a connection. */
1140 static void
quic_connection_create_or_update(quic_info_data_t ** conn_p,packet_info * pinfo,guint32 long_packet_type,guint32 version,const quic_cid_t * scid,const quic_cid_t * dcid,gboolean from_server)1141 quic_connection_create_or_update(quic_info_data_t **conn_p,
1142 packet_info *pinfo, guint32 long_packet_type,
1143 guint32 version, const quic_cid_t *scid,
1144 const quic_cid_t *dcid, gboolean from_server)
1145 {
1146 quic_info_data_t *conn = *conn_p;
1147
1148 switch (long_packet_type) {
1149 case QUIC_LPT_INITIAL:
1150 if (!from_server) {
1151 if (!conn) {
1152 // The first Initial Packet from the client creates a new connection.
1153 *conn_p = quic_connection_create(pinfo, version);
1154 quic_connection_update_initial(*conn_p, scid, dcid);
1155 } else if (!conn->client_dcid_set && dcid->len) {
1156 // If this client Initial Packet responds to a Retry Packet,
1157 // then remember the new client SCID and initial DCID for the
1158 // new Initial cipher and clear the first server CID such that
1159 // the next server Initial Packet can link the connection with
1160 // that new SCID.
1161 quic_connection_update_initial(conn, scid, dcid);
1162 wmem_map_remove(quic_server_connections, &conn->server_cids.data);
1163 memset(&conn->server_cids, 0, sizeof(quic_cid_t));
1164 }
1165 break;
1166 }
1167 /* fallthrough */
1168 case QUIC_LPT_RETRY:
1169 case QUIC_LPT_HANDSHAKE:
1170 // Remember CID from first server Retry/Handshake packet
1171 // (or from the first server Initial packet, since draft -13).
1172 if (from_server && conn) {
1173 if (long_packet_type == QUIC_LPT_RETRY) {
1174 // Retry Packet: the next Initial Packet from the
1175 // client should start a new cryptographic handshake. Erase the
1176 // current "Initial DCID" such that the next client Initial
1177 // packet populates the new value.
1178 wmem_map_remove(quic_initial_connections, &conn->client_dcid_initial);
1179 memset(&conn->client_dcid_initial, 0, sizeof(quic_cid_t));
1180 conn->client_dcid_set = FALSE;
1181 }
1182 if (conn->server_cids.data.len == 0 && scid->len) {
1183 memcpy(&conn->server_cids.data, scid, sizeof(quic_cid_t));
1184 quic_cids_insert(&conn->server_cids.data, conn, TRUE);
1185 }
1186 }
1187 break;
1188 }
1189 }
1190
1191 static void
quic_connection_destroy(gpointer data,gpointer user_data _U_)1192 quic_connection_destroy(gpointer data, gpointer user_data _U_)
1193 {
1194 quic_info_data_t *conn = (quic_info_data_t *)data;
1195 quic_ciphers_reset(&conn->client_initial_ciphers);
1196 quic_ciphers_reset(&conn->server_initial_ciphers);
1197 quic_ciphers_reset(&conn->client_handshake_ciphers);
1198 quic_ciphers_reset(&conn->server_handshake_ciphers);
1199
1200 quic_ciphers_reset(&conn->client_0rtt_ciphers);
1201
1202 quic_hp_cipher_reset(&conn->client_pp.hp_cipher);
1203 quic_pp_cipher_reset(&conn->client_pp.pp_ciphers[0]);
1204 quic_pp_cipher_reset(&conn->client_pp.pp_ciphers[1]);
1205
1206 quic_hp_cipher_reset(&conn->server_pp.hp_cipher);
1207 quic_pp_cipher_reset(&conn->server_pp.pp_ciphers[0]);
1208 quic_pp_cipher_reset(&conn->server_pp.pp_ciphers[1]);
1209 }
1210 /* QUIC Connection tracking. }}} */
1211
1212 /* QUIC Streams tracking and reassembly. {{{ */
1213 static reassembly_table quic_reassembly_table;
1214
1215 #ifdef HAVE_LIBGCRYPT_AEAD
1216 /** Perform sequence analysis for STREAM frames. */
1217 static quic_stream_state *
quic_get_stream_state(packet_info * pinfo,quic_info_data_t * quic_info,gboolean from_server,guint64 stream_id)1218 quic_get_stream_state(packet_info *pinfo, quic_info_data_t *quic_info, gboolean from_server, guint64 stream_id)
1219 {
1220 wmem_map_t **streams_p = from_server ? &quic_info->server_streams : &quic_info->client_streams;
1221 wmem_map_t *streams = *streams_p;
1222 quic_stream_state *stream = NULL;
1223
1224 if (PINFO_FD_VISITED(pinfo)) {
1225 DISSECTOR_ASSERT(streams);
1226 stream = (quic_stream_state *)wmem_map_lookup(streams, &stream_id);
1227 DISSECTOR_ASSERT(stream);
1228 return stream;
1229 }
1230
1231 // Initialize per-connection and per-stream state.
1232 if (!streams) {
1233 streams = wmem_map_new(wmem_file_scope(), wmem_int64_hash, g_int64_equal);
1234 *streams_p = streams;
1235 } else {
1236 stream = (quic_stream_state *)wmem_map_lookup(streams, &stream_id);
1237 }
1238 if (!stream) {
1239 stream = wmem_new0(wmem_file_scope(), quic_stream_state);
1240 stream->stream_id = stream_id;
1241 stream->multisegment_pdus = wmem_tree_new(wmem_file_scope());
1242 wmem_map_insert(streams, &stream->stream_id, stream);
1243 }
1244 return stream;
1245 }
1246
1247 static void
process_quic_stream(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,quic_info_data_t * quic_info,quic_stream_info * stream_info)1248 process_quic_stream(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
1249 quic_info_data_t *quic_info, quic_stream_info *stream_info)
1250 {
1251 if (quic_info->app_handle) {
1252 tvbuff_t *next_tvb = tvb_new_subset_remaining(tvb, offset);
1253 // Traverse the STREAM frame tree.
1254 proto_tree *top_tree = proto_tree_get_parent_tree(tree);
1255 top_tree = proto_tree_get_parent_tree(top_tree);
1256 call_dissector_with_data(quic_info->app_handle, next_tvb, pinfo, top_tree, stream_info);
1257 }
1258 }
1259
1260 /**
1261 * Reassemble stream data within a STREAM frame.
1262 */
1263 static void
desegment_quic_stream(tvbuff_t * tvb,int offset,int length,packet_info * pinfo,proto_tree * tree,quic_info_data_t * quic_info,quic_stream_info * stream_info,quic_stream_state * stream)1264 desegment_quic_stream(tvbuff_t *tvb, int offset, int length, packet_info *pinfo,
1265 proto_tree *tree, quic_info_data_t *quic_info,
1266 quic_stream_info *stream_info,
1267 quic_stream_state *stream)
1268 {
1269 fragment_head *fh;
1270 int last_fragment_len;
1271 gboolean must_desegment;
1272 gboolean called_dissector;
1273 int another_pdu_follows;
1274 int deseg_offset;
1275 struct tcp_multisegment_pdu *msp;
1276 guint32 seq = (guint32)stream_info->stream_offset;
1277 const guint32 nxtseq = seq + (guint32)length;
1278 guint32 reassembly_id = 0;
1279
1280 // XXX fix the tvb accessors below such that no new tvb is needed.
1281 tvb = tvb_new_subset_length(tvb, 0, offset + length);
1282
1283 again:
1284 fh = NULL;
1285 last_fragment_len = 0;
1286 must_desegment = FALSE;
1287 called_dissector = FALSE;
1288 another_pdu_follows = 0;
1289 msp = NULL;
1290
1291 /*
1292 * Initialize these to assume no desegmentation.
1293 * If that's not the case, these will be set appropriately
1294 * by the subdissector.
1295 */
1296 pinfo->desegment_offset = 0;
1297 pinfo->desegment_len = 0;
1298
1299 /*
1300 * Initialize this to assume that this segment will just be
1301 * added to the middle of a desegmented chunk of data, so
1302 * that we should show it all as data.
1303 * If that's not the case, it will be set appropriately.
1304 */
1305 deseg_offset = offset;
1306
1307 /* Have we seen this PDU before (and is it the start of a multi-
1308 * segment PDU)?
1309 */
1310 if ((msp = (struct tcp_multisegment_pdu *)wmem_tree_lookup32(stream->multisegment_pdus, seq)) &&
1311 nxtseq <= msp->nxtpdu) {
1312 // TODO show expert info for retransmission? Additional checks may be
1313 // necessary here to tell a retransmission apart from other (normal?)
1314 // conditions. See also similar code in packet-tcp.c.
1315 #if 0
1316 proto_tree_add_debug_text(tree, "TODO retransmission expert info frame %d stream_id=%" G_GINT64_MODIFIER "u offset=%d visited=%d reassembly_id=0x%08x",
1317 pinfo->num, stream->stream_id, offset, PINFO_FD_VISITED(pinfo), reassembly_id);
1318 #endif
1319 return;
1320 }
1321 /* Else, find the most previous PDU starting before this sequence number */
1322 if (!msp && seq > 0) {
1323 msp = (struct tcp_multisegment_pdu *)wmem_tree_lookup32_le(stream->multisegment_pdus, seq-1);
1324 /* Unless if we already fully reassembled the msp that covers seq-1
1325 * and seq is beyond the end of that msp. In that case this segment
1326 * will be the start of a new msp.
1327 */
1328 if (msp && (msp->flags & MSP_FLAGS_GOT_ALL_SEGMENTS) &&
1329 seq >= msp->nxtpdu) {
1330 msp = NULL;
1331 }
1332 }
1333
1334 {
1335 // A single stream can contain multiple fragments (e.g. for HTTP/3
1336 // HEADERS and DATA frames). Let's hope that a single stream within a
1337 // QUIC packet does not contain multiple partial fragments, that would
1338 // result in a reassembly ID collision here. If that collision becomes
1339 // an issue, we would have to replace "msp->first_frame" with a new
1340 // field in "msp" that is initialized with "stream_info->stream_offset".
1341 #if 0
1342 guint64 reassembly_id_data[2];
1343 reassembly_id_data[0] = stream_info->stream_id;
1344 reassembly_id_data[1] = msp ? msp->first_frame : pinfo->num;
1345 reassembly_id = wmem_strong_hash((const guint8 *)&reassembly_id_data, sizeof(reassembly_id_data));
1346 #else
1347 // XXX for debug (visibility) purposes, do not use a hash but concatenate
1348 reassembly_id = ((msp ? msp->first_frame : pinfo->num) << 16) | (guint32)stream_info->stream_id;
1349 #endif
1350 }
1351
1352 if (msp && msp->seq <= seq && msp->nxtpdu > seq) {
1353 int len;
1354
1355 if (!PINFO_FD_VISITED(pinfo)) {
1356 msp->last_frame=pinfo->num;
1357 msp->last_frame_time=pinfo->abs_ts;
1358 }
1359
1360 /* OK, this PDU was found, which means the segment continues
1361 * a higher-level PDU and that we must desegment it.
1362 */
1363 if (msp->flags & MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT) {
1364 /* The dissector asked for the entire segment */
1365 len = tvb_captured_length_remaining(tvb, offset);
1366 } else {
1367 len = MIN(nxtseq, msp->nxtpdu) - seq;
1368 }
1369 last_fragment_len = len;
1370
1371 fh = fragment_add(&quic_reassembly_table, tvb, offset,
1372 pinfo, reassembly_id, NULL,
1373 seq - msp->seq, len,
1374 nxtseq < msp->nxtpdu);
1375 if (fh) {
1376 msp->flags |= MSP_FLAGS_GOT_ALL_SEGMENTS;
1377 }
1378 if (!PINFO_FD_VISITED(pinfo)
1379 && msp->flags & MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT) {
1380 msp->flags &= (~MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT);
1381
1382 /* If we consumed the entire segment there is no
1383 * other pdu starting anywhere inside this segment.
1384 * So update nxtpdu to point at least to the start
1385 * of the next segment.
1386 * (If the subdissector asks for even more data we
1387 * will advance nxtpdu even further later down in
1388 * the code.)
1389 */
1390 msp->nxtpdu = nxtseq;
1391 }
1392
1393 if( (msp->nxtpdu < nxtseq)
1394 && (msp->nxtpdu >= seq)
1395 && (len > 0)) {
1396 another_pdu_follows=msp->nxtpdu - seq;
1397 }
1398 } else {
1399 /* This segment was not found in our table, so it doesn't
1400 * contain a continuation of a higher-level PDU.
1401 * Call the normal subdissector.
1402 */
1403
1404 stream_info->offset = seq;
1405 process_quic_stream(tvb, offset, pinfo, tree, quic_info, stream_info);
1406 called_dissector = TRUE;
1407
1408 /* Did the subdissector ask us to desegment some more data
1409 * before it could handle the packet?
1410 * If so we have to create some structures in our table but
1411 * this is something we only do the first time we see this
1412 * packet.
1413 */
1414 if (pinfo->desegment_len) {
1415 if (!PINFO_FD_VISITED(pinfo)) {
1416 must_desegment = TRUE;
1417 if (msp)
1418 msp->flags &= ~MSP_FLAGS_GOT_ALL_SEGMENTS;
1419 }
1420
1421 /*
1422 * Set "deseg_offset" to the offset in "tvb"
1423 * of the first byte of data that the
1424 * subdissector didn't process.
1425 */
1426 deseg_offset = offset + pinfo->desegment_offset;
1427 }
1428
1429 /* Either no desegmentation is necessary, or this is
1430 * segment contains the beginning but not the end of
1431 * a higher-level PDU and thus isn't completely
1432 * desegmented.
1433 */
1434 fh = NULL;
1435 }
1436
1437 /* is it completely desegmented? */
1438 if (fh) {
1439 /*
1440 * Yes, we think it is.
1441 * We only call subdissector for the last segment.
1442 * Note that the last segment may include more than what
1443 * we needed.
1444 */
1445 if (fh->reassembled_in == pinfo->num) {
1446 /*
1447 * OK, this is the last segment.
1448 * Let's call the subdissector with the desegmented data.
1449 */
1450
1451 tvbuff_t *next_tvb = tvb_new_chain(tvb, fh->tvb_data);
1452 add_new_data_source(pinfo, next_tvb, "Reassembled QUIC");
1453 stream_info->offset = seq;
1454 process_quic_stream(next_tvb, 0, pinfo, tree, quic_info, stream_info);
1455 called_dissector = TRUE;
1456
1457 int old_len = (int)(tvb_reported_length(next_tvb) - last_fragment_len);
1458 if (pinfo->desegment_len &&
1459 pinfo->desegment_offset <= old_len) {
1460 /*
1461 * "desegment_len" isn't 0, so it needs more
1462 * data for something - and "desegment_offset"
1463 * is before "old_len", so it needs more data
1464 * to dissect the stuff we thought was
1465 * completely desegmented (as opposed to the
1466 * stuff at the beginning being completely
1467 * desegmented, but the stuff at the end
1468 * being a new higher-level PDU that also
1469 * needs desegmentation).
1470 */
1471 fragment_set_partial_reassembly(&quic_reassembly_table,
1472 pinfo, reassembly_id, NULL);
1473
1474 /* Update msp->nxtpdu to point to the new next
1475 * pdu boundary.
1476 */
1477 if (pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT) {
1478 /* We want reassembly of at least one
1479 * more segment so set the nxtpdu
1480 * boundary to one byte into the next
1481 * segment.
1482 * This means that the next segment
1483 * will complete reassembly even if it
1484 * is only one single byte in length.
1485 * If this is an OoO segment, then increment the MSP end.
1486 */
1487 msp->nxtpdu = MAX(seq + tvb_reported_length_remaining(tvb, offset), msp->nxtpdu) + 1;
1488 msp->flags |= MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT;
1489 #if 0
1490 } else if (pinfo->desegment_len == DESEGMENT_UNTIL_FIN) {
1491 tcpd->fwd->flags |= TCP_FLOW_REASSEMBLE_UNTIL_FIN;
1492 #endif
1493 } else {
1494 if (seq + last_fragment_len >= msp->nxtpdu) {
1495 /* This is the segment (overlapping) the end of the MSP. */
1496 msp->nxtpdu = seq + last_fragment_len + pinfo->desegment_len;
1497 } else {
1498 /* This is a segment before the end of the MSP, so it
1499 * must be an out-of-order segmented that completed the
1500 * MSP. The requested additional data is relative to
1501 * that end.
1502 */
1503 msp->nxtpdu += pinfo->desegment_len;
1504 }
1505 }
1506
1507 /* Since we need at least some more data
1508 * there can be no pdu following in the
1509 * tail of this segment.
1510 */
1511 another_pdu_follows = 0;
1512 offset += last_fragment_len;
1513 seq += last_fragment_len;
1514 if (tvb_captured_length_remaining(tvb, offset) > 0)
1515 goto again;
1516 } else {
1517 proto_item *frag_tree_item;
1518 proto_tree *parent_tree = proto_tree_get_parent(tree);
1519 show_fragment_tree(fh, &quic_stream_fragment_items,
1520 parent_tree, pinfo, next_tvb, &frag_tree_item);
1521 // TODO move tree item if needed.
1522
1523 if(pinfo->desegment_len) {
1524 if (!PINFO_FD_VISITED(pinfo)) {
1525 must_desegment = TRUE;
1526 if (msp)
1527 msp->flags &= ~MSP_FLAGS_GOT_ALL_SEGMENTS;
1528 }
1529 /* See packet-tcp.h for details about this. */
1530 deseg_offset = fh->datalen - pinfo->desegment_offset;
1531 deseg_offset = tvb_reported_length(tvb) - deseg_offset;
1532 }
1533 }
1534 }
1535 }
1536
1537 if (must_desegment && !PINFO_FD_VISITED(pinfo)) {
1538 // TODO handle DESEGMENT_UNTIL_FIN if needed, maybe use the FIN bit?
1539
1540 guint32 deseg_seq = seq + (deseg_offset - offset);
1541
1542 if (((nxtseq - deseg_seq) <= 1024*1024)
1543 && (!PINFO_FD_VISITED(pinfo))) {
1544 if(pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT) {
1545 /* The subdissector asked to reassemble using the
1546 * entire next segment.
1547 * Just ask reassembly for one more byte
1548 * but set this msp flag so we can pick it up
1549 * above.
1550 */
1551 msp = pdu_store_sequencenumber_of_next_pdu(pinfo, deseg_seq,
1552 nxtseq+1, stream->multisegment_pdus);
1553 msp->flags |= MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT;
1554 } else {
1555 msp = pdu_store_sequencenumber_of_next_pdu(pinfo,
1556 deseg_seq, nxtseq+pinfo->desegment_len, stream->multisegment_pdus);
1557 }
1558
1559 /* add this segment as the first one for this new pdu */
1560 fragment_add(&quic_reassembly_table, tvb, deseg_offset,
1561 pinfo, reassembly_id, NULL,
1562 0, nxtseq - deseg_seq,
1563 nxtseq < msp->nxtpdu);
1564 }
1565 }
1566
1567 if (!called_dissector || pinfo->desegment_len != 0) {
1568 if (fh != NULL && fh->reassembled_in != 0 &&
1569 !(fh->flags & FD_PARTIAL_REASSEMBLY)) {
1570 /*
1571 * We know what frame this PDU is reassembled in;
1572 * let the user know.
1573 */
1574 proto_item *item = proto_tree_add_uint(tree, hf_quic_reassembled_in, tvb, 0,
1575 0, fh->reassembled_in);
1576 proto_item_set_generated(item);
1577 }
1578 }
1579 pinfo->can_desegment = 0;
1580 pinfo->desegment_offset = 0;
1581 pinfo->desegment_len = 0;
1582
1583 if (another_pdu_follows) {
1584 /* there was another pdu following this one. */
1585 pinfo->can_desegment = 2;
1586 offset += another_pdu_follows;
1587 seq += another_pdu_follows;
1588 goto again;
1589 }
1590 }
1591
1592 static void
dissect_quic_stream_payload(tvbuff_t * tvb,int offset,int length,packet_info * pinfo,proto_tree * tree,quic_info_data_t * quic_info,quic_stream_info * stream_info,quic_stream_state * stream)1593 dissect_quic_stream_payload(tvbuff_t *tvb, int offset, int length, packet_info *pinfo,
1594 proto_tree *tree, quic_info_data_t *quic_info,
1595 quic_stream_info *stream_info,
1596 quic_stream_state *stream)
1597 {
1598 /* QUIC application data is most likely not properly dissected when
1599 * reassembly is not enabled. Therefore we do not even offer "desegment"
1600 * preference to disable reassembly.
1601 */
1602
1603 pinfo->can_desegment = 2;
1604 desegment_quic_stream(tvb, offset, length, pinfo, tree, quic_info, stream_info, stream);
1605 }
1606 /* QUIC Streams tracking and reassembly. }}} */
1607
1608 void
quic_stream_add_proto_data(packet_info * pinfo,quic_stream_info * stream_info,void * proto_data)1609 quic_stream_add_proto_data(packet_info *pinfo, quic_stream_info *stream_info, void *proto_data)
1610 {
1611 quic_stream_state *stream = quic_get_stream_state(pinfo, stream_info->quic_info, stream_info->from_server, stream_info->stream_id);
1612 stream->subdissector_private = proto_data;
1613 }
1614
quic_stream_get_proto_data(packet_info * pinfo,quic_stream_info * stream_info)1615 void *quic_stream_get_proto_data(packet_info *pinfo, quic_stream_info *stream_info)
1616 {
1617 quic_stream_state *stream = quic_get_stream_state(pinfo, stream_info->quic_info, stream_info->from_server, stream_info->stream_id);
1618 return stream->subdissector_private;
1619 }
1620
1621 static int
dissect_quic_frame_type(tvbuff_t * tvb,packet_info * pinfo,proto_tree * quic_tree,guint offset,quic_info_data_t * quic_info,gboolean from_server)1622 dissect_quic_frame_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree, guint offset, quic_info_data_t *quic_info, gboolean from_server)
1623 {
1624 proto_item *ti_ft, *ti_ftflags, *ti_ftid, *ti;
1625 proto_tree *ft_tree, *ftflags_tree, *ftid_tree;
1626 guint64 frame_type;
1627 gint32 lenft;
1628 guint orig_offset = offset;
1629
1630 ti_ft = proto_tree_add_item(quic_tree, hf_quic_frame, tvb, offset, 1, ENC_NA);
1631 ft_tree = proto_item_add_subtree(ti_ft, ett_quic_ft);
1632
1633 ti_ftflags = proto_tree_add_item_ret_varint(ft_tree, hf_quic_frame_type, tvb, offset, -1, ENC_VARINT_QUIC, &frame_type, &lenft);
1634 proto_item_set_text(ti_ft, "%s", rval_to_str_const((guint32)frame_type, quic_frame_type_vals, "Unknown"));
1635 offset += lenft;
1636
1637 switch(frame_type){
1638 case FT_PADDING:{
1639 guint32 pad_len;
1640
1641 col_append_fstr(pinfo->cinfo, COL_INFO, ", PADDING");
1642
1643 /* A padding frame consists of a single zero octet, but for brevity
1644 * sake let's combine multiple zeroes into a single field. */
1645 pad_len = 1 + tvb_skip_guint8(tvb, offset, tvb_reported_length_remaining(tvb, offset), '\0') - offset;
1646 ti = proto_tree_add_uint(ft_tree, hf_quic_padding_length, tvb, offset, 0, pad_len);
1647 proto_item_set_generated(ti);
1648 proto_item_append_text(ti_ft, " Length: %u", pad_len);
1649 offset += pad_len - 1;
1650 }
1651 break;
1652 case FT_PING:{
1653 col_append_fstr(pinfo->cinfo, COL_INFO, ", PING");
1654 }
1655 break;
1656 case FT_ACK:
1657 case FT_ACK_ECN:
1658 case FT_MP_ACK:
1659 case FT_MP_ACK_ECN:{
1660 guint64 ack_range_count;
1661 gint32 lenvar;
1662
1663 switch(frame_type){
1664 case FT_ACK:
1665 col_append_fstr(pinfo->cinfo, COL_INFO, ", ACK");
1666 break;
1667 case FT_ACK_ECN:
1668 col_append_fstr(pinfo->cinfo, COL_INFO, ", ACK_ECN");
1669 break;
1670 case FT_MP_ACK:
1671 col_append_fstr(pinfo->cinfo, COL_INFO, ", MP_ACK");
1672 proto_tree_add_item_ret_varint(ft_tree, hf_quic_mp_uniflow_id, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1673 offset += lenvar;
1674 break;
1675 case FT_MP_ACK_ECN:
1676 col_append_fstr(pinfo->cinfo, COL_INFO, ", MP_ACK_ECN");
1677 proto_tree_add_item_ret_varint(ft_tree, hf_quic_mp_uniflow_id, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1678 offset += lenvar;
1679 break;
1680 }
1681
1682 proto_tree_add_item_ret_varint(ft_tree, hf_quic_ack_largest_acknowledged, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1683 offset += lenvar;
1684
1685 proto_tree_add_item_ret_varint(ft_tree, hf_quic_ack_ack_delay, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1686 offset += lenvar;
1687
1688 proto_tree_add_item_ret_varint(ft_tree, hf_quic_ack_ack_range_count, tvb, offset, -1, ENC_VARINT_QUIC, &ack_range_count, &lenvar);
1689 offset += lenvar;
1690
1691 proto_tree_add_item_ret_varint(ft_tree, hf_quic_ack_first_ack_range, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1692 offset += lenvar;
1693
1694 /* ACK Ranges - Repeated "Ack Range Count" */
1695 while (ack_range_count) {
1696
1697 /* Gap To Next Block */
1698 proto_tree_add_item_ret_varint(ft_tree, hf_quic_ack_gap, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1699 offset += lenvar;
1700
1701 proto_tree_add_item_ret_varint(ft_tree, hf_quic_ack_ack_range, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1702 offset += lenvar;
1703
1704 ack_range_count--;
1705 }
1706
1707 /* ECN Counts. */
1708 if (frame_type == FT_ACK_ECN) {
1709 proto_tree_add_item_ret_varint(ft_tree, hf_quic_ack_ect0_count, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1710 offset += lenvar;
1711
1712 proto_tree_add_item_ret_varint(ft_tree, hf_quic_ack_ect1_count, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1713 offset += lenvar;
1714
1715 proto_tree_add_item_ret_varint(ft_tree, hf_quic_ack_ecn_ce_count, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1716 offset += lenvar;
1717 }
1718 }
1719 break;
1720 case FT_RESET_STREAM:{
1721 guint64 stream_id, error_code;
1722 gint32 len_streamid = 0, len_finalsize = 0, len_error_code = 0;
1723
1724 col_append_fstr(pinfo->cinfo, COL_INFO, ", RS");
1725
1726 proto_tree_add_item_ret_varint(ft_tree, hf_quic_rsts_stream_id, tvb, offset, -1, ENC_VARINT_QUIC, &stream_id, &len_streamid);
1727 offset += len_streamid;
1728
1729 proto_item_append_text(ti_ft, " id=%" G_GINT64_MODIFIER "u", stream_id);
1730 col_append_fstr(pinfo->cinfo, COL_INFO, "(%" G_GINT64_MODIFIER "u)", stream_id);
1731
1732 proto_tree_add_item_ret_varint(ft_tree, hf_quic_rsts_application_error_code, tvb, offset, -1, ENC_VARINT_QUIC, &error_code, &len_error_code);
1733 offset += len_error_code;
1734
1735 proto_tree_add_item_ret_varint(ft_tree, hf_quic_rsts_final_size, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_finalsize);
1736 offset += len_finalsize;
1737
1738 proto_item_append_text(ti_ft, " Error code: %#" G_GINT64_MODIFIER "x", error_code);
1739 }
1740 break;
1741 case FT_STOP_SENDING:{
1742 gint32 len_streamid;
1743 guint64 stream_id, error_code;
1744 gint32 len_error_code = 0;
1745
1746 col_append_fstr(pinfo->cinfo, COL_INFO, ", SS");
1747
1748 proto_tree_add_item_ret_varint(ft_tree, hf_quic_ss_stream_id, tvb, offset, -1, ENC_VARINT_QUIC, &stream_id, &len_streamid);
1749 offset += len_streamid;
1750
1751 proto_item_append_text(ti_ft, " id=%" G_GINT64_MODIFIER "u", stream_id);
1752 col_append_fstr(pinfo->cinfo, COL_INFO, "(%" G_GINT64_MODIFIER "u)", stream_id);
1753
1754 proto_tree_add_item_ret_varint(ft_tree, hf_quic_ss_application_error_code, tvb, offset, -1, ENC_VARINT_QUIC, &error_code, &len_error_code);
1755 offset += len_error_code;
1756
1757 proto_item_append_text(ti_ft, " Error code: %#" G_GINT64_MODIFIER "x", error_code);
1758 }
1759 break;
1760 case FT_CRYPTO: {
1761 guint64 crypto_offset, crypto_length;
1762 gint32 lenvar;
1763 col_append_fstr(pinfo->cinfo, COL_INFO, ", CRYPTO");
1764 proto_tree_add_item_ret_varint(ft_tree, hf_quic_crypto_offset, tvb, offset, -1, ENC_VARINT_QUIC, &crypto_offset, &lenvar);
1765 offset += lenvar;
1766 proto_tree_add_item_ret_varint(ft_tree, hf_quic_crypto_length, tvb, offset, -1, ENC_VARINT_QUIC, &crypto_length, &lenvar);
1767 offset += lenvar;
1768 proto_tree_add_item(ft_tree, hf_quic_crypto_crypto_data, tvb, offset, (guint32)crypto_length, ENC_NA);
1769 {
1770 tvbuff_t *next_tvb = tvb_new_subset_length(tvb, offset, (int)crypto_length);
1771 col_set_writable(pinfo->cinfo, -1, FALSE);
1772 /*
1773 * Dissect TLS handshake record. The Client/Server Hello (CH/SH)
1774 * are contained in the Initial Packet. 0-RTT keys are ready
1775 * after CH. HS + 1-RTT keys are ready after SH.
1776 * (Note: keys captured from the client might become available
1777 * after capturing the packets due to processing delay.)
1778 * These keys will be loaded in the first HS/0-RTT/1-RTT msg.
1779 */
1780 call_dissector_with_data(tls13_handshake_handle, next_tvb, pinfo, ft_tree, GUINT_TO_POINTER(crypto_offset));
1781 col_set_writable(pinfo->cinfo, -1, TRUE);
1782 }
1783 offset += (guint32)crypto_length;
1784 }
1785 break;
1786 case FT_NEW_TOKEN: {
1787 guint64 token_length;
1788 gint32 lenvar;
1789
1790 col_append_fstr(pinfo->cinfo, COL_INFO, ", NT");
1791
1792 proto_tree_add_item_ret_varint(ft_tree, hf_quic_nt_length, tvb, offset, -1, ENC_VARINT_QUIC, &token_length, &lenvar);
1793 offset += lenvar;
1794
1795 proto_tree_add_item(ft_tree, hf_quic_nt_token, tvb, offset, (guint32)token_length, ENC_NA);
1796 offset += (guint32)token_length;
1797 }
1798 break;
1799 case FT_STREAM_8:
1800 case FT_STREAM_9:
1801 case FT_STREAM_A:
1802 case FT_STREAM_B:
1803 case FT_STREAM_C:
1804 case FT_STREAM_D:
1805 case FT_STREAM_E:
1806 case FT_STREAM_F: {
1807 guint64 stream_id, stream_offset = 0, length;
1808 gint32 lenvar;
1809
1810 offset -= 1;
1811
1812 col_append_fstr(pinfo->cinfo, COL_INFO, ", STREAM");
1813
1814 ftflags_tree = proto_item_add_subtree(ti_ftflags, ett_quic_ftflags);
1815 proto_tree_add_item(ftflags_tree, hf_quic_stream_fin, tvb, offset, 1, ENC_NA);
1816 proto_tree_add_item(ftflags_tree, hf_quic_stream_len, tvb, offset, 1, ENC_NA);
1817 proto_tree_add_item(ftflags_tree, hf_quic_stream_off, tvb, offset, 1, ENC_NA);
1818 offset += 1;
1819
1820 ti_ftid = proto_tree_add_item_ret_varint(ft_tree, hf_quic_stream_stream_id, tvb, offset, -1, ENC_VARINT_QUIC, &stream_id, &lenvar);
1821 ftid_tree = proto_item_add_subtree(ti_ftid, ett_quic_ftid);
1822 proto_tree_add_item_ret_varint(ftid_tree, hf_quic_stream_initiator, tvb, offset, -1, ENC_VARINT_QUIC, NULL, NULL);
1823 proto_tree_add_item_ret_varint(ftid_tree, hf_quic_stream_direction, tvb, offset, -1, ENC_VARINT_QUIC, NULL, NULL);
1824 offset += lenvar;
1825
1826 proto_item_append_text(ti_ft, " id=%" G_GINT64_MODIFIER "u", stream_id);
1827 col_append_fstr(pinfo->cinfo, COL_INFO, "(%" G_GINT64_MODIFIER "u)", stream_id);
1828
1829 proto_item_append_text(ti_ft, " fin=%d", !!(frame_type & FTFLAGS_STREAM_FIN));
1830
1831 if (!PINFO_FD_VISITED(pinfo)) {
1832 quic_streams_add(pinfo, quic_info, stream_id);
1833 }
1834
1835 if (frame_type & FTFLAGS_STREAM_OFF) {
1836 proto_tree_add_item_ret_varint(ft_tree, hf_quic_stream_offset, tvb, offset, -1, ENC_VARINT_QUIC, &stream_offset, &lenvar);
1837 offset += lenvar;
1838 }
1839 proto_item_append_text(ti_ft, " off=%" G_GINT64_MODIFIER "u", stream_offset);
1840
1841 if (frame_type & FTFLAGS_STREAM_LEN) {
1842 proto_tree_add_item_ret_varint(ft_tree, hf_quic_stream_length, tvb, offset, -1, ENC_VARINT_QUIC, &length, &lenvar);
1843 offset += lenvar;
1844 } else {
1845 length = tvb_reported_length_remaining(tvb, offset);
1846 }
1847 proto_item_append_text(ti_ft, " len=%" G_GINT64_MODIFIER "u dir=%s origin=%s", length,
1848 val64_to_str_const(!!(stream_id & FTFLAGS_STREAM_DIRECTION), quic_frame_id_direction, "unknown"),
1849 val64_to_str_const(!!(stream_id & FTFLAGS_STREAM_INITIATOR), quic_frame_id_initiator, "unknown"));
1850
1851 proto_tree_add_item(ft_tree, hf_quic_stream_data, tvb, offset, (int)length, ENC_NA);
1852 if (have_tap_listener(quic_follow_tap)) {
1853 quic_follow_tap_data_t *follow_data = wmem_new0(wmem_packet_scope(), quic_follow_tap_data_t);
1854
1855 follow_data->tvb = tvb_new_subset_remaining(tvb, offset);
1856 follow_data->stream_id = stream_id;
1857
1858 tap_queue_packet(quic_follow_tap, pinfo, follow_data);
1859 }
1860 quic_stream_state *stream = quic_get_stream_state(pinfo, quic_info, from_server, stream_id);
1861 quic_stream_info stream_info = {
1862 .stream_id = stream_id,
1863 .stream_offset = stream_offset,
1864 .quic_info = quic_info,
1865 .from_server = from_server,
1866 };
1867 dissect_quic_stream_payload(tvb, offset, (int)length, pinfo, ft_tree, quic_info, &stream_info, stream);
1868 offset += (int)length;
1869 }
1870 break;
1871 case FT_MAX_DATA:{
1872 gint32 len_maximumdata;
1873
1874 col_append_fstr(pinfo->cinfo, COL_INFO, ", MD");
1875
1876 proto_tree_add_item_ret_varint(ft_tree, hf_quic_md_maximum_data, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_maximumdata);
1877 offset += len_maximumdata;
1878 }
1879 break;
1880 case FT_MAX_STREAM_DATA:{
1881 gint32 len_streamid, len_maximumstreamdata;
1882 guint64 stream_id;
1883
1884 col_append_fstr(pinfo->cinfo, COL_INFO, ", MSD");
1885
1886 proto_tree_add_item_ret_varint(ft_tree, hf_quic_msd_stream_id, tvb, offset, -1, ENC_VARINT_QUIC, &stream_id, &len_streamid);
1887 offset += len_streamid;
1888
1889 proto_item_append_text(ti_ft, " id=%" G_GINT64_MODIFIER "u", stream_id);
1890 col_append_fstr(pinfo->cinfo, COL_INFO, "(%" G_GINT64_MODIFIER "u)", stream_id);
1891
1892 proto_tree_add_item_ret_varint(ft_tree, hf_quic_msd_maximum_stream_data, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_maximumstreamdata);
1893 offset += len_maximumstreamdata;
1894 }
1895 break;
1896 case FT_MAX_STREAMS_BIDI:
1897 case FT_MAX_STREAMS_UNI:{
1898 gint32 len_streamid;
1899
1900 col_append_fstr(pinfo->cinfo, COL_INFO, ", MS");
1901
1902 proto_tree_add_item_ret_varint(ft_tree, hf_quic_ms_max_streams, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_streamid);
1903 offset += len_streamid;
1904 }
1905 break;
1906 case FT_DATA_BLOCKED:{
1907 gint32 len_offset;
1908
1909 col_append_fstr(pinfo->cinfo, COL_INFO, ", DB");
1910
1911 proto_tree_add_item_ret_varint(ft_tree, hf_quic_db_stream_data_limit, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_offset);
1912 offset += len_offset;
1913 }
1914 break;
1915 case FT_STREAM_DATA_BLOCKED:{
1916 gint32 len_streamid, len_offset;
1917 guint64 stream_id;
1918
1919 col_append_fstr(pinfo->cinfo, COL_INFO, ", SDB");
1920
1921 proto_tree_add_item_ret_varint(ft_tree, hf_quic_sdb_stream_id, tvb, offset, -1, ENC_VARINT_QUIC, &stream_id, &len_streamid);
1922 offset += len_streamid;
1923
1924 proto_item_append_text(ti_ft, " id=%" G_GINT64_MODIFIER "u", stream_id);
1925 col_append_fstr(pinfo->cinfo, COL_INFO, "(%" G_GINT64_MODIFIER "u)", stream_id);
1926
1927 proto_tree_add_item_ret_varint(ft_tree, hf_quic_sdb_stream_data_limit, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_offset);
1928 offset += len_offset;
1929 }
1930 break;
1931 case FT_STREAMS_BLOCKED_BIDI:
1932 case FT_STREAMS_BLOCKED_UNI:{
1933 gint32 len_streamid;
1934
1935 col_append_fstr(pinfo->cinfo, COL_INFO, ", SB");
1936
1937 proto_tree_add_item_ret_varint(ft_tree, hf_quic_sb_stream_limit, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_streamid);
1938 offset += len_streamid;
1939 }
1940 break;
1941 case FT_NEW_CONNECTION_ID:
1942 case FT_MP_NEW_CONNECTION_ID:{
1943 gint32 len_sequence;
1944 gint32 len_retire_prior_to;
1945 gint32 nci_length;
1946 gint32 lenvar = 0;
1947 gboolean valid_cid = FALSE;
1948
1949 switch(frame_type){
1950 case FT_NEW_CONNECTION_ID:
1951 col_append_fstr(pinfo->cinfo, COL_INFO, ", NCI");
1952 break;
1953 case FT_MP_NEW_CONNECTION_ID:
1954 col_append_fstr(pinfo->cinfo, COL_INFO, ", MP_NCI");
1955 proto_tree_add_item_ret_varint(ft_tree, hf_quic_mp_uniflow_id, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
1956 offset += lenvar;
1957 break;
1958 }
1959
1960 proto_tree_add_item_ret_varint(ft_tree, hf_quic_nci_sequence, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_sequence);
1961 offset += len_sequence;
1962
1963 proto_tree_add_item_ret_varint(ft_tree, hf_quic_nci_retire_prior_to, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_retire_prior_to);
1964 offset += len_retire_prior_to;
1965
1966 ti = proto_tree_add_item_ret_uint(ft_tree, hf_quic_nci_connection_id_length, tvb, offset, 1, ENC_BIG_ENDIAN, &nci_length);
1967 offset++;
1968
1969 valid_cid = nci_length >= 1 && nci_length <= QUIC_MAX_CID_LENGTH;
1970 if (!valid_cid) {
1971 expert_add_info_format(pinfo, ti, &ei_quic_protocol_violation,
1972 "Connection ID Length must be between 1 and %d bytes", QUIC_MAX_CID_LENGTH);
1973 }
1974
1975 proto_tree_add_item(ft_tree, hf_quic_nci_connection_id, tvb, offset, nci_length, ENC_NA);
1976 if (valid_cid && quic_info) {
1977 quic_cid_t cid = {.len=0};
1978 tvb_memcpy(tvb, cid.cid, offset, nci_length);
1979 cid.len = nci_length;
1980 quic_connection_add_cid(quic_info, &cid, from_server);
1981 }
1982 offset += nci_length;
1983
1984 proto_tree_add_item(ft_tree, hf_quic_nci_stateless_reset_token, tvb, offset, 16, ENC_NA);
1985 offset += 16;
1986 }
1987 break;
1988 case FT_RETIRE_CONNECTION_ID:
1989 case FT_MP_RETIRE_CONNECTION_ID:{
1990 gint32 len_sequence;
1991 gint32 lenvar;
1992
1993 switch(frame_type){
1994 case FT_RETIRE_CONNECTION_ID:
1995 col_append_fstr(pinfo->cinfo, COL_INFO, ", RC");
1996 break;
1997 case FT_MP_RETIRE_CONNECTION_ID:
1998 col_append_fstr(pinfo->cinfo, COL_INFO, ", MP_RC");
1999 proto_tree_add_item_ret_varint(ft_tree, hf_quic_mp_uniflow_id, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &lenvar);
2000 offset += lenvar;
2001 break;
2002 }
2003
2004 proto_tree_add_item_ret_varint(ft_tree, hf_quic_rci_sequence, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_sequence);
2005 offset += len_sequence;
2006 }
2007 break;
2008 case FT_PATH_CHALLENGE:{
2009 col_append_fstr(pinfo->cinfo, COL_INFO, ", PC");
2010
2011 proto_tree_add_item(ft_tree, hf_quic_path_challenge_data, tvb, offset, 8, ENC_NA);
2012 offset += 8;
2013 }
2014 break;
2015 case FT_PATH_RESPONSE:{
2016 col_append_fstr(pinfo->cinfo, COL_INFO, ", PR");
2017
2018 proto_tree_add_item(ft_tree, hf_quic_path_response_data, tvb, offset, 8, ENC_NA);
2019 offset += 8;
2020 }
2021 break;
2022 case FT_CONNECTION_CLOSE_TPT:
2023 case FT_CONNECTION_CLOSE_APP:{
2024 gint32 len_reasonphrase, len_frametype, len_error_code;
2025 guint64 len_reason = 0;
2026 guint64 error_code;
2027 const char *tls_alert = NULL;
2028
2029 col_append_fstr(pinfo->cinfo, COL_INFO, ", CC");
2030
2031 if (frame_type == FT_CONNECTION_CLOSE_TPT) {
2032 proto_tree_add_item_ret_varint(ft_tree, hf_quic_cc_error_code, tvb, offset, -1, ENC_VARINT_QUIC, &error_code, &len_error_code);
2033 if ((error_code >> 8) == 1) { // CRYPTO_ERROR (0x1XX)
2034 tls_alert = try_val_to_str(error_code & 0xff, ssl_31_alert_description);
2035 if (tls_alert) {
2036 proto_tree_add_item(ft_tree, hf_quic_cc_error_code_tls_alert, tvb, offset + len_error_code - 1, 1, ENC_BIG_ENDIAN);
2037 }
2038 }
2039 offset += len_error_code;
2040
2041 proto_tree_add_item_ret_varint(ft_tree, hf_quic_cc_frame_type, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_frametype);
2042 offset += len_frametype;
2043 } else { /* FT_CONNECTION_CLOSE_APP) */
2044 proto_tree_add_item_ret_varint(ft_tree, hf_quic_cc_error_code_app, tvb, offset, -1, ENC_VARINT_QUIC, &error_code, &len_error_code);
2045 offset += len_error_code;
2046 }
2047
2048
2049 proto_tree_add_item_ret_varint(ft_tree, hf_quic_cc_reason_phrase_length, tvb, offset, -1, ENC_VARINT_QUIC, &len_reason, &len_reasonphrase);
2050 offset += len_reasonphrase;
2051
2052 proto_tree_add_item(ft_tree, hf_quic_cc_reason_phrase, tvb, offset, (guint32)len_reason, ENC_ASCII|ENC_NA);
2053 offset += (guint32)len_reason;
2054
2055 // Transport Error codes higher than 0x3fff are for Private Use.
2056 if (frame_type == FT_CONNECTION_CLOSE_TPT && error_code <= 0x3fff) {
2057 proto_item_append_text(ti_ft, " Error code: %s", rval_to_str((guint32)error_code, quic_transport_error_code_vals, "Unknown (%d)"));
2058 } else {
2059 proto_item_append_text(ti_ft, " Error code: %#" G_GINT64_MODIFIER "x", error_code);
2060 }
2061 if (tls_alert) {
2062 proto_item_append_text(ti_ft, " (%s)", tls_alert);
2063 }
2064 }
2065 break;
2066 case FT_HANDSHAKE_DONE:
2067 col_append_fstr(pinfo->cinfo, COL_INFO, ", DONE");
2068 break;
2069 case FT_DATAGRAM:
2070 case FT_DATAGRAM_LENGTH:{
2071 gint32 dg_length;
2072 guint64 length;
2073 col_append_fstr(pinfo->cinfo, COL_INFO, ", DG");
2074 if (frame_type == FT_DATAGRAM_LENGTH) {
2075
2076 proto_tree_add_item_ret_varint(ft_tree, hf_quic_dg_length, tvb, offset, -1, ENC_VARINT_QUIC, &length, &dg_length);
2077 offset += dg_length;
2078 } else {
2079 length = (guint32) tvb_reported_length_remaining(tvb, offset);
2080 }
2081 proto_tree_add_item(ft_tree, hf_quic_dg, tvb, offset, (guint32)length, ENC_NA);
2082 offset += (guint32)length;
2083 }
2084 break;
2085 case FT_ACK_FREQUENCY:{
2086 gint32 length;
2087
2088 col_append_fstr(pinfo->cinfo, COL_INFO, ", ACK_FREQ");
2089 proto_tree_add_item_ret_varint(ft_tree, hf_quic_af_sequence_number, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &length);
2090 offset += (guint32)length;
2091
2092 proto_tree_add_item_ret_varint(ft_tree, hf_quic_af_packet_tolerance, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &length);
2093 offset += (guint32)length;
2094
2095 proto_tree_add_item_ret_varint(ft_tree, hf_quic_af_update_max_ack_delay, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &length);
2096 offset += (guint32)length;
2097 }
2098 break;
2099 case FT_TIME_STAMP:{
2100 gint32 length;
2101
2102 col_append_fstr(pinfo->cinfo, COL_INFO, ", TS");
2103 proto_tree_add_item_ret_varint(ft_tree, hf_quic_ts, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &length);
2104 offset += (guint32)length;
2105
2106 }
2107 break;
2108 case FT_ADD_ADDRESS:{
2109 gint32 length;
2110 guint64 config_bits;
2111
2112 col_append_fstr(pinfo->cinfo, COL_INFO, ", ADD_ADDRESS");
2113
2114 static int * const config_fields[] = {
2115 &hf_quic_mp_add_address_reserved,
2116 &hf_quic_mp_add_address_port_present,
2117 &hf_quic_mp_add_address_ip_version,
2118 NULL
2119 };
2120
2121 proto_tree_add_bitmask_ret_uint64(ft_tree, tvb, offset, hf_quic_mp_add_address_first_byte, ett_quic, config_fields, ENC_BIG_ENDIAN, &config_bits);
2122 offset += 1;
2123
2124 proto_tree_add_item(ft_tree, hf_quic_mp_add_address_id, tvb, offset, 1, ENC_NA);
2125 offset += 1;
2126
2127 proto_tree_add_item_ret_varint(ft_tree, hf_quic_mp_add_address_sq_number, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &length);
2128 offset += (guint32)length;
2129
2130 proto_tree_add_item(ft_tree, hf_quic_mp_add_address_interface_type, tvb, offset, 1, ENC_NA);
2131 offset += 1;
2132
2133 if ((config_bits & 0x06) == 0x06) {
2134 ws_in6_addr addr;
2135 tvb_get_ipv6(tvb, offset, &addr);
2136 proto_tree_add_ipv6(ft_tree, hf_quic_mp_add_address_ip_address_v6, tvb, offset, 16, &addr);
2137 offset += 16;
2138 } else {
2139 guint32 ip_config = tvb_get_ipv4(tvb, offset);
2140 proto_tree_add_ipv4(ft_tree, hf_quic_mp_add_address_ip_address, tvb, offset, 4, ip_config);
2141 offset += 4;
2142 }
2143
2144 if ((config_bits & 0x10 ) == 0x10) {
2145 proto_tree_add_item(ft_tree, hf_quic_mp_add_address_port, tvb, offset, 2, ENC_NA);
2146 offset += 2;
2147 }
2148 }
2149 break;
2150 case FT_REMOVE_ADDRESS:{
2151 gint32 length;
2152
2153 col_append_fstr(pinfo->cinfo, COL_INFO, ", REMOVE_ADDRESS");
2154
2155 proto_tree_add_item(ft_tree, hf_quic_mp_add_address_id, tvb, offset, 1, ENC_NA);
2156 offset += 1;
2157
2158 proto_tree_add_item_ret_varint(ft_tree, hf_quic_mp_add_address_sq_number, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &length);
2159 offset += (guint32)length;
2160 }
2161 break;
2162 case FT_UNIFLOWS:{
2163 gint32 length;
2164 gint32 len_receiving_uniflows;
2165 gint32 len_active_sending_uniflows;
2166 gint32 len_uniflow_id;
2167
2168 guint64 ret_receiving_uniflows;
2169 guint64 ret_active_sending_uniflows;
2170
2171 col_append_fstr(pinfo->cinfo, COL_INFO, ", UNIFLOWS");
2172
2173 proto_tree_add_item_ret_varint(ft_tree, hf_quic_mp_add_address_sq_number, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &length);
2174 offset += (guint32)length;
2175
2176 proto_tree_add_item_ret_varint(ft_tree, hf_quic_mp_receiving_uniflows, tvb, offset, -1, ENC_VARINT_QUIC, &ret_receiving_uniflows, &len_receiving_uniflows);
2177 offset += (guint32)len_receiving_uniflows;
2178
2179 proto_tree_add_item_ret_varint(ft_tree, hf_quic_mp_active_sending_uniflows, tvb, offset, -1, ENC_VARINT_QUIC, &ret_active_sending_uniflows, &len_active_sending_uniflows);
2180 offset += (guint32)len_active_sending_uniflows;
2181
2182 proto_item *receiving_uniflows_ft;
2183 proto_tree *receiving_uniflows_tree;
2184
2185 receiving_uniflows_ft = proto_tree_add_item(ft_tree, hf_quic_mp_receiving_uniflow_info_section , tvb, offset, 1, ENC_NA);
2186 receiving_uniflows_tree = proto_item_add_subtree(receiving_uniflows_ft, ett_quic_ft);
2187
2188 for (guint64 i = 0; i < ret_receiving_uniflows; i++) {
2189 proto_item *item_ft;
2190 proto_tree *item_tree;
2191
2192 item_ft = proto_tree_add_item(receiving_uniflows_tree, hf_quic_mp_uniflow_info_section, tvb, offset, 1, ENC_NA);
2193 item_tree = proto_item_add_subtree(item_ft, ett_quic_ft);
2194
2195 len_uniflow_id = 0;
2196
2197 proto_tree_add_item_ret_varint(item_tree, hf_quic_mp_uniflow_id, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_uniflow_id);
2198 offset += (guint32)len_uniflow_id;
2199
2200 proto_tree_add_item(item_tree, hf_quic_mp_add_local_address_id , tvb, offset, 1, ENC_NA);
2201 offset += 1;
2202 }
2203
2204 proto_item *active_sending_uniflows_ft;
2205 proto_tree *active_sending_uniflows_tree;
2206
2207 active_sending_uniflows_ft = proto_tree_add_item(ft_tree, hf_quic_mp_active_sending_uniflows_info_section, tvb, offset, 1, ENC_NA);
2208 active_sending_uniflows_tree = proto_item_add_subtree(active_sending_uniflows_ft, ett_quic_ft);
2209
2210 for (guint64 i = 0; i < ret_active_sending_uniflows; i++) {
2211 proto_item *item_ft;
2212 proto_tree *item_tree;
2213
2214 item_ft = proto_tree_add_item(active_sending_uniflows_tree, hf_quic_mp_uniflow_info_section, tvb, offset, 1, ENC_NA);
2215 item_tree = proto_item_add_subtree(item_ft, ett_quic_ft);
2216
2217 len_uniflow_id = 0;
2218
2219 proto_tree_add_item_ret_varint(item_tree, hf_quic_mp_uniflow_id, tvb, offset, -1, ENC_VARINT_QUIC, NULL, &len_uniflow_id);
2220 offset += (guint32)len_uniflow_id;
2221
2222 proto_tree_add_item(item_tree, hf_quic_mp_add_local_address_id , tvb, offset, 1, ENC_NA);
2223 offset += 1;
2224 }
2225 }
2226 break;
2227 default:
2228 expert_add_info_format(pinfo, ti_ft, &ei_quic_ft_unknown, "Unknown Frame Type %#" G_GINT64_MODIFIER "x", frame_type);
2229 break;
2230 }
2231
2232 proto_item_set_len(ti_ft, offset - orig_offset);
2233
2234 return offset;
2235 }
2236
2237 static gboolean
2238 quic_hp_cipher_init(quic_hp_cipher *hp_cipher, int hash_algo, guint8 key_length, guint8 *secret);
2239 static gboolean
2240 quic_pp_cipher_init(quic_pp_cipher *pp_cipher, int hash_algo, guint8 key_length, guint8 *secret);
2241
2242
2243 /**
2244 * Given a QUIC message (header + non-empty payload), the actual packet number,
2245 * try to decrypt it using the PP cipher.
2246 * As the header points to the original buffer with an encrypted packet number,
2247 * the (encrypted) packet number length is also included.
2248 *
2249 * The actual packet number must be constructed according to
2250 * https://tools.ietf.org/html/draft-ietf-quic-transport-22#section-12.3
2251 */
2252 static void
quic_decrypt_message(quic_pp_cipher * pp_cipher,tvbuff_t * head,guint header_length,guint8 first_byte,guint pkn_len,guint64 packet_number,quic_decrypt_result_t * result)2253 quic_decrypt_message(quic_pp_cipher *pp_cipher, tvbuff_t *head, guint header_length,
2254 guint8 first_byte, guint pkn_len, guint64 packet_number, quic_decrypt_result_t *result)
2255 {
2256 gcry_error_t err;
2257 guint8 *header;
2258 guint8 nonce[TLS13_AEAD_NONCE_LENGTH];
2259 guint8 *buffer;
2260 guint8 atag[16];
2261 guint buffer_length;
2262 const guchar **error = &result->error;
2263
2264 DISSECTOR_ASSERT(pp_cipher != NULL);
2265 DISSECTOR_ASSERT(pp_cipher->pp_cipher != NULL);
2266 DISSECTOR_ASSERT(pkn_len < header_length);
2267 DISSECTOR_ASSERT(1 <= pkn_len && pkn_len <= 4);
2268 // copy header, but replace encrypted first byte and PKN by plaintext.
2269 header = (guint8 *)tvb_memdup(wmem_packet_scope(), head, 0, header_length);
2270 header[0] = first_byte;
2271 for (guint i = 0; i < pkn_len; i++) {
2272 header[header_length - 1 - i] = (guint8)(packet_number >> (8 * i));
2273 }
2274
2275 /* Input is "header || ciphertext (buffer) || auth tag (16 bytes)" */
2276 buffer_length = tvb_captured_length_remaining(head, header_length + 16);
2277 if (buffer_length == 0) {
2278 *error = "Decryption not possible, ciphertext is too short";
2279 return;
2280 }
2281 buffer = (guint8 *)tvb_memdup(wmem_file_scope(), head, header_length, buffer_length);
2282 tvb_memcpy(head, atag, header_length + buffer_length, 16);
2283
2284 memcpy(nonce, pp_cipher->pp_iv, TLS13_AEAD_NONCE_LENGTH);
2285 /* Packet number is left-padded with zeroes and XORed with write_iv */
2286 phton64(nonce + sizeof(nonce) - 8, pntoh64(nonce + sizeof(nonce) - 8) ^ packet_number);
2287
2288 gcry_cipher_reset(pp_cipher->pp_cipher);
2289 err = gcry_cipher_setiv(pp_cipher->pp_cipher, nonce, TLS13_AEAD_NONCE_LENGTH);
2290 if (err) {
2291 *error = wmem_strdup_printf(wmem_file_scope(), "Decryption (setiv) failed: %s", gcry_strerror(err));
2292 return;
2293 }
2294
2295 /* associated data (A) is the contents of QUIC header */
2296 err = gcry_cipher_authenticate(pp_cipher->pp_cipher, header, header_length);
2297 if (err) {
2298 *error = wmem_strdup_printf(wmem_file_scope(), "Decryption (authenticate) failed: %s", gcry_strerror(err));
2299 return;
2300 }
2301
2302 /* Output ciphertext (C) */
2303 err = gcry_cipher_decrypt(pp_cipher->pp_cipher, buffer, buffer_length, NULL, 0);
2304 if (err) {
2305 *error = wmem_strdup_printf(wmem_file_scope(), "Decryption (decrypt) failed: %s", gcry_strerror(err));
2306 return;
2307 }
2308
2309 err = gcry_cipher_checktag(pp_cipher->pp_cipher, atag, 16);
2310 if (err) {
2311 *error = wmem_strdup_printf(wmem_file_scope(), "Decryption (checktag) failed: %s", gcry_strerror(err));
2312 return;
2313 }
2314
2315 result->error = NULL;
2316 result->data = buffer;
2317 result->data_len = buffer_length;
2318 }
2319
2320 static gboolean
quic_hkdf_expand_label(int hash_algo,guint8 * secret,guint secret_len,const char * label,guint8 * out,guint out_len)2321 quic_hkdf_expand_label(int hash_algo, guint8 *secret, guint secret_len, const char *label, guint8 *out, guint out_len)
2322 {
2323 const StringInfo secret_si = { secret, secret_len };
2324 guchar *out_mem = NULL;
2325 if (tls13_hkdf_expand_label(hash_algo, &secret_si, "tls13 ", label, out_len, &out_mem)) {
2326 memcpy(out, out_mem, out_len);
2327 wmem_free(NULL, out_mem);
2328 return TRUE;
2329 }
2330 return FALSE;
2331 }
2332
2333 /**
2334 * Compute the client and server initial secrets given Connection ID "cid".
2335 *
2336 * On success TRUE is returned and the two initial secrets are set.
2337 * FALSE is returned on error (see "error" parameter for the reason).
2338 */
2339 static gboolean
quic_derive_initial_secrets(const quic_cid_t * cid,guint8 client_initial_secret[HASH_SHA2_256_LENGTH],guint8 server_initial_secret[HASH_SHA2_256_LENGTH],guint32 version,const gchar ** error)2340 quic_derive_initial_secrets(const quic_cid_t *cid,
2341 guint8 client_initial_secret[HASH_SHA2_256_LENGTH],
2342 guint8 server_initial_secret[HASH_SHA2_256_LENGTH],
2343 guint32 version,
2344 const gchar **error)
2345 {
2346 /*
2347 * https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-5.2
2348 *
2349 * initial_salt = 0xafbfec289993d24c9e9786f19c6111e04390a899
2350 * initial_secret = HKDF-Extract(initial_salt, client_dst_connection_id)
2351 *
2352 * client_initial_secret = HKDF-Expand-Label(initial_secret,
2353 * "client in", "", Hash.length)
2354 * server_initial_secret = HKDF-Expand-Label(initial_secret,
2355 * "server in", "", Hash.length)
2356 *
2357 * Hash for handshake packets is SHA-256 (output size 32).
2358 */
2359 static const guint8 handshake_salt_draft_22[20] = {
2360 0x7f, 0xbc, 0xdb, 0x0e, 0x7c, 0x66, 0xbb, 0xe9, 0x19, 0x3a,
2361 0x96, 0xcd, 0x21, 0x51, 0x9e, 0xbd, 0x7a, 0x02, 0x64, 0x4a
2362 };
2363 static const guint8 handshake_salt_draft_23[20] = {
2364 0xc3, 0xee, 0xf7, 0x12, 0xc7, 0x2e, 0xbb, 0x5a, 0x11, 0xa7,
2365 0xd2, 0x43, 0x2b, 0xb4, 0x63, 0x65, 0xbe, 0xf9, 0xf5, 0x02,
2366 };
2367 static const guint8 handshake_salt_draft_29[20] = {
2368 0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c, 0x9e, 0x97,
2369 0x86, 0xf1, 0x9c, 0x61, 0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99
2370 };
2371 static const guint8 handshake_salt_v1[20] = {
2372 0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17,
2373 0x9a, 0xe6, 0xa4, 0xc8, 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a
2374 };
2375 static const guint8 hanshake_salt_draft_q50[20] = {
2376 0x50, 0x45, 0x74, 0xEF, 0xD0, 0x66, 0xFE, 0x2F, 0x9D, 0x94,
2377 0x5C, 0xFC, 0xDB, 0xD3, 0xA7, 0xF0, 0xD3, 0xB5, 0x6B, 0x45
2378 };
2379 static const guint8 hanshake_salt_draft_t50[20] = {
2380 0x7f, 0xf5, 0x79, 0xe5, 0xac, 0xd0, 0x72, 0x91, 0x55, 0x80,
2381 0x30, 0x4c, 0x43, 0xa2, 0x36, 0x7c, 0x60, 0x48, 0x83, 0x10
2382 };
2383 static const gint8 hanshake_salt_draft_t51[20] = {
2384 0x7a, 0x4e, 0xde, 0xf4, 0xe7, 0xcc, 0xee, 0x5f, 0xa4, 0x50,
2385 0x6c, 0x19, 0x12, 0x4f, 0xc8, 0xcc, 0xda, 0x6e, 0x03, 0x3d
2386 };
2387
2388 gcry_error_t err;
2389 guint8 secret[HASH_SHA2_256_LENGTH];
2390
2391 if (version == 0x51303530) {
2392 err = hkdf_extract(GCRY_MD_SHA256, hanshake_salt_draft_q50, sizeof(hanshake_salt_draft_q50),
2393 cid->cid, cid->len, secret);
2394 } else if (version == 0x54303530) {
2395 err = hkdf_extract(GCRY_MD_SHA256, hanshake_salt_draft_t50, sizeof(hanshake_salt_draft_t50),
2396 cid->cid, cid->len, secret);
2397 } else if (version == 0x54303531) {
2398 err = hkdf_extract(GCRY_MD_SHA256, hanshake_salt_draft_t51, sizeof(hanshake_salt_draft_t51),
2399 cid->cid, cid->len, secret);
2400 } else if (is_quic_draft_max(version, 22)) {
2401 err = hkdf_extract(GCRY_MD_SHA256, handshake_salt_draft_22, sizeof(handshake_salt_draft_22),
2402 cid->cid, cid->len, secret);
2403 } else if (is_quic_draft_max(version, 28)) {
2404 err = hkdf_extract(GCRY_MD_SHA256, handshake_salt_draft_23, sizeof(handshake_salt_draft_23),
2405 cid->cid, cid->len, secret);
2406 } else if (is_quic_draft_max(version, 32)) {
2407 err = hkdf_extract(GCRY_MD_SHA256, handshake_salt_draft_29, sizeof(handshake_salt_draft_29),
2408 cid->cid, cid->len, secret);
2409 } else {
2410 err = hkdf_extract(GCRY_MD_SHA256, handshake_salt_v1, sizeof(handshake_salt_v1),
2411 cid->cid, cid->len, secret);
2412 }
2413 if (err) {
2414 *error = wmem_strdup_printf(wmem_packet_scope(), "Failed to extract secrets: %s", gcry_strerror(err));
2415 return FALSE;
2416 }
2417
2418 if (!quic_hkdf_expand_label(GCRY_MD_SHA256, secret, sizeof(secret), "client in",
2419 client_initial_secret, HASH_SHA2_256_LENGTH)) {
2420 *error = "Key expansion (client) failed";
2421 return FALSE;
2422 }
2423
2424 if (!quic_hkdf_expand_label(GCRY_MD_SHA256, secret, sizeof(secret), "server in",
2425 server_initial_secret, HASH_SHA2_256_LENGTH)) {
2426 *error = "Key expansion (server) failed";
2427 return FALSE;
2428 }
2429
2430 *error = NULL;
2431 return TRUE;
2432 }
2433
2434 /**
2435 * Maps a Packet Protection cipher to the Packet Number protection cipher.
2436 * See https://tools.ietf.org/html/draft-ietf-quic-tls-22#section-5.4.3
2437 */
2438 static gboolean
quic_get_pn_cipher_algo(int cipher_algo,int * hp_cipher_mode)2439 quic_get_pn_cipher_algo(int cipher_algo, int *hp_cipher_mode)
2440 {
2441 switch (cipher_algo) {
2442 case GCRY_CIPHER_AES128:
2443 case GCRY_CIPHER_AES256:
2444 *hp_cipher_mode = GCRY_CIPHER_MODE_ECB;
2445 return TRUE;
2446 #ifdef HAVE_LIBGCRYPT_CHACHA20
2447 case GCRY_CIPHER_CHACHA20:
2448 *hp_cipher_mode = GCRY_CIPHER_MODE_STREAM;
2449 return TRUE;
2450 #endif /* HAVE_LIBGCRYPT_CHACHA20 */
2451 default:
2452 return FALSE;
2453 }
2454 }
2455
2456 /*
2457 * (Re)initialize the PNE/PP ciphers using the given cipher algorithm.
2458 * If the optional base secret is given, then its length MUST match the hash
2459 * algorithm output.
2460 */
2461 static gboolean
quic_hp_cipher_prepare(quic_hp_cipher * hp_cipher,int hash_algo,int cipher_algo,guint8 * secret,const char ** error)2462 quic_hp_cipher_prepare(quic_hp_cipher *hp_cipher, int hash_algo, int cipher_algo, guint8 *secret, const char **error)
2463 {
2464 /* Clear previous state (if any). */
2465 quic_hp_cipher_reset(hp_cipher);
2466
2467 int hp_cipher_mode;
2468 if (!quic_get_pn_cipher_algo(cipher_algo, &hp_cipher_mode)) {
2469 *error = "Unsupported cipher algorithm";
2470 return FALSE;
2471 }
2472
2473 if (gcry_cipher_open(&hp_cipher->hp_cipher, cipher_algo, hp_cipher_mode, 0)) {
2474 quic_hp_cipher_reset(hp_cipher);
2475 *error = "Failed to create HP cipher";
2476 return FALSE;
2477 }
2478
2479 if (secret) {
2480 guint cipher_keylen = (guint8) gcry_cipher_get_algo_keylen(cipher_algo);
2481 if (!quic_hp_cipher_init(hp_cipher, hash_algo, cipher_keylen, secret)) {
2482 quic_hp_cipher_reset(hp_cipher);
2483 *error = "Failed to derive key material for HP cipher";
2484 return FALSE;
2485 }
2486 }
2487
2488 return TRUE;
2489 }
2490 static gboolean
quic_pp_cipher_prepare(quic_pp_cipher * pp_cipher,int hash_algo,int cipher_algo,int cipher_mode,guint8 * secret,const char ** error)2491 quic_pp_cipher_prepare(quic_pp_cipher *pp_cipher, int hash_algo, int cipher_algo, int cipher_mode, guint8 *secret, const char **error)
2492 {
2493 /* Clear previous state (if any). */
2494 quic_pp_cipher_reset(pp_cipher);
2495
2496 int hp_cipher_mode;
2497 if (!quic_get_pn_cipher_algo(cipher_algo, &hp_cipher_mode)) {
2498 *error = "Unsupported cipher algorithm";
2499 return FALSE;
2500 }
2501
2502 if (gcry_cipher_open(&pp_cipher->pp_cipher, cipher_algo, cipher_mode, 0)) {
2503 quic_pp_cipher_reset(pp_cipher);
2504 *error = "Failed to create PP cipher";
2505 return FALSE;
2506 }
2507
2508 if (secret) {
2509 guint cipher_keylen = (guint8) gcry_cipher_get_algo_keylen(cipher_algo);
2510 if (!quic_pp_cipher_init(pp_cipher, hash_algo, cipher_keylen, secret)) {
2511 quic_pp_cipher_reset(pp_cipher);
2512 *error = "Failed to derive key material for PP cipher";
2513 return FALSE;
2514 }
2515 }
2516
2517 return TRUE;
2518 }
2519 static gboolean
quic_ciphers_prepare(quic_ciphers * ciphers,int hash_algo,int cipher_algo,int cipher_mode,guint8 * secret,const char ** error)2520 quic_ciphers_prepare(quic_ciphers *ciphers, int hash_algo, int cipher_algo, int cipher_mode, guint8 *secret, const char **error)
2521 {
2522 return quic_hp_cipher_prepare(&ciphers->hp_cipher, hash_algo, cipher_algo, secret, error) &&
2523 quic_pp_cipher_prepare(&ciphers->pp_cipher, hash_algo, cipher_algo, cipher_mode, secret, error);
2524 }
2525
2526
2527 static gboolean
quic_create_initial_decoders(const quic_cid_t * cid,const gchar ** error,quic_info_data_t * quic_info)2528 quic_create_initial_decoders(const quic_cid_t *cid, const gchar **error, quic_info_data_t *quic_info)
2529 {
2530 guint8 client_secret[HASH_SHA2_256_LENGTH];
2531 guint8 server_secret[HASH_SHA2_256_LENGTH];
2532
2533 if (!quic_derive_initial_secrets(cid, client_secret, server_secret, quic_info->version, error)) {
2534 return FALSE;
2535 }
2536
2537 /* Packet numbers are protected with AES128-CTR,
2538 * initial packets are protected with AEAD_AES_128_GCM. */
2539 if (!quic_ciphers_prepare(&quic_info->client_initial_ciphers, GCRY_MD_SHA256,
2540 GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, client_secret, error) ||
2541 !quic_ciphers_prepare(&quic_info->server_initial_ciphers, GCRY_MD_SHA256,
2542 GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, server_secret, error)) {
2543 return FALSE;
2544 }
2545
2546 return TRUE;
2547 }
2548
2549 static gboolean
quic_create_0rtt_decoder(guint i,gchar * early_data_secret,guint early_data_secret_len,quic_ciphers * ciphers,int * cipher_algo)2550 quic_create_0rtt_decoder(guint i, gchar *early_data_secret, guint early_data_secret_len,
2551 quic_ciphers *ciphers, int *cipher_algo)
2552 {
2553 static const guint16 tls13_ciphers[] = {
2554 0x1301, /* TLS_AES_128_GCM_SHA256 */
2555 0x1302, /* TLS_AES_256_GCM_SHA384 */
2556 0x1303, /* TLS_CHACHA20_POLY1305_SHA256 */
2557 0x1304, /* TLS_AES_128_CCM_SHA256 */
2558 0x1305, /* TLS_AES_128_CCM_8_SHA256 */
2559 };
2560 if (i >= G_N_ELEMENTS(tls13_ciphers)) {
2561 // end of list
2562 return FALSE;
2563 }
2564 int cipher_mode = 0, hash_algo = 0;
2565 const char *error_ignored = NULL;
2566 if (tls_get_cipher_info(NULL, tls13_ciphers[i], cipher_algo, &cipher_mode, &hash_algo)) {
2567 guint hash_len = gcry_md_get_algo_dlen(hash_algo);
2568 if (hash_len == early_data_secret_len && quic_ciphers_prepare(ciphers, hash_algo, *cipher_algo, cipher_mode, early_data_secret, &error_ignored)) {
2569 return TRUE;
2570 }
2571 }
2572 /* This cipher failed, but there are more to try. */
2573 quic_ciphers_reset(ciphers);
2574 return TRUE;
2575 }
2576
2577 static gboolean
quic_create_decoders(packet_info * pinfo,quic_info_data_t * quic_info,quic_ciphers * ciphers,gboolean from_server,TLSRecordType type,const char ** error)2578 quic_create_decoders(packet_info *pinfo, quic_info_data_t *quic_info, quic_ciphers *ciphers,
2579 gboolean from_server, TLSRecordType type, const char **error)
2580 {
2581 if (!quic_info->hash_algo) {
2582 if (!tls_get_cipher_info(pinfo, 0, &quic_info->cipher_algo, &quic_info->cipher_mode, &quic_info->hash_algo)) {
2583 #ifndef HAVE_LIBGCRYPT_CHACHA20
2584 /* If this stream uses the ChaCha20-Poly1305 cipher, Libgcrypt 1.7.0
2585 * or newer is required. */
2586 *error = "Unable to retrieve cipher information; try upgrading Libgcrypt >= 1.7.0";
2587 #else
2588 *error = "Unable to retrieve cipher information";
2589 #endif
2590 return FALSE;
2591 }
2592 }
2593
2594 guint hash_len = gcry_md_get_algo_dlen(quic_info->hash_algo);
2595 char *secret = (char *)wmem_alloc0(wmem_packet_scope(), hash_len);
2596
2597 if (!tls13_get_quic_secret(pinfo, from_server, type, hash_len, hash_len, secret)) {
2598 *error = "Secrets are not available";
2599 return FALSE;
2600 }
2601
2602 if (!quic_ciphers_prepare(ciphers, quic_info->hash_algo,
2603 quic_info->cipher_algo, quic_info->cipher_mode, secret, error)) {
2604 return FALSE;
2605 }
2606
2607 return TRUE;
2608 }
2609
2610 /**
2611 * Tries to obtain the QUIC application traffic secrets.
2612 */
2613 static gboolean
quic_get_traffic_secret(packet_info * pinfo,int hash_algo,quic_pp_state_t * pp_state,gboolean from_client)2614 quic_get_traffic_secret(packet_info *pinfo, int hash_algo, quic_pp_state_t *pp_state, gboolean from_client)
2615 {
2616 guint hash_len = gcry_md_get_algo_dlen(hash_algo);
2617 char *secret = (char *)wmem_alloc0(wmem_packet_scope(), hash_len);
2618 if (!tls13_get_quic_secret(pinfo, !from_client, TLS_SECRET_APP, hash_len, hash_len, secret)) {
2619 return FALSE;
2620 }
2621 pp_state->next_secret = (guint8 *)wmem_memdup(wmem_file_scope(), secret, hash_len);
2622 return TRUE;
2623 }
2624
2625 /**
2626 * Expands the secret (length MUST be the same as the "hash_algo" digest size)
2627 * and initialize cipher with the new key.
2628 */
2629 static gboolean
quic_hp_cipher_init(quic_hp_cipher * hp_cipher,int hash_algo,guint8 key_length,guint8 * secret)2630 quic_hp_cipher_init(quic_hp_cipher *hp_cipher, int hash_algo, guint8 key_length, guint8 *secret)
2631 {
2632 guchar hp_key[256/8];
2633 guint hash_len = gcry_md_get_algo_dlen(hash_algo);
2634
2635 if (!quic_hkdf_expand_label(hash_algo, secret, hash_len, "quic hp", hp_key, key_length)) {
2636 return FALSE;
2637 }
2638
2639 return gcry_cipher_setkey(hp_cipher->hp_cipher, hp_key, key_length) == 0;
2640 }
2641 static gboolean
quic_pp_cipher_init(quic_pp_cipher * pp_cipher,int hash_algo,guint8 key_length,guint8 * secret)2642 quic_pp_cipher_init(quic_pp_cipher *pp_cipher, int hash_algo, guint8 key_length, guint8 *secret)
2643 {
2644 guchar write_key[256/8]; /* Maximum key size is for AES256 cipher. */
2645 guint hash_len = gcry_md_get_algo_dlen(hash_algo);
2646
2647 if (key_length > sizeof(write_key)) {
2648 return FALSE;
2649 }
2650
2651 if (!quic_hkdf_expand_label(hash_algo, secret, hash_len, "quic key", write_key, key_length) ||
2652 !quic_hkdf_expand_label(hash_algo, secret, hash_len, "quic iv", pp_cipher->pp_iv, sizeof(pp_cipher->pp_iv))) {
2653 return FALSE;
2654 }
2655
2656 return gcry_cipher_setkey(pp_cipher->pp_cipher, write_key, key_length) == 0;
2657 }
2658
2659
2660 /**
2661 * Updates the packet protection secret to the next one.
2662 */
2663 static void
quic_update_key(guint32 version,int hash_algo,quic_pp_state_t * pp_state)2664 quic_update_key(guint32 version, int hash_algo, quic_pp_state_t *pp_state)
2665 {
2666 guint hash_len = gcry_md_get_algo_dlen(hash_algo);
2667 const char *label = is_quic_draft_max(version, 23) ? "traffic upd" : "quic ku";
2668 gboolean ret = quic_hkdf_expand_label(hash_algo, pp_state->next_secret, hash_len,
2669 label, pp_state->next_secret, hash_len);
2670 /* This must always succeed as our hash algorithm was already validated. */
2671 DISSECTOR_ASSERT(ret);
2672 }
2673
2674 /**
2675 * Retrieves the header protection cipher for short header packets and prepares
2676 * the packet protection cipher. The application layer protocol is also queried.
2677 */
2678 static quic_hp_cipher *
quic_get_1rtt_hp_cipher(packet_info * pinfo,quic_info_data_t * quic_info,gboolean from_server,const char ** error)2679 quic_get_1rtt_hp_cipher(packet_info *pinfo, quic_info_data_t *quic_info, gboolean from_server, const char **error)
2680 {
2681 /* Keys were previously not available. */
2682 if (quic_info->skip_decryption) {
2683 return NULL;
2684 }
2685
2686 quic_pp_state_t *client_pp = &quic_info->client_pp;
2687 quic_pp_state_t *server_pp = &quic_info->server_pp;
2688 quic_pp_state_t *pp_state = !from_server ? client_pp : server_pp;
2689
2690 /* Try to lookup secrets if not available. */
2691 if (!quic_info->client_pp.next_secret) {
2692 /* Query TLS for the cipher suite. */
2693 if (!tls_get_cipher_info(pinfo, 0, &quic_info->cipher_algo, &quic_info->cipher_mode, &quic_info->hash_algo)) {
2694 /* We end up here if:
2695 * no previous TLS handshake is found
2696 * the used ciphers are unsupported
2697 * some (unencrypted) padding is misdetected as SH coalesced packet
2698 Because of the third scenario, we can't set quic_info->skip_decryption
2699 to TRUE; otherwise we will stop decrypting the entire session, even if
2700 we are able to.
2701 Unfortunately, this way, we lost the optimization that allows skipping checks
2702 for future packets in case the capture starts in midst of a
2703 connection where the handshake is not present.
2704 Note that even if we have a basic logic to detect unencrypted padding (via
2705 check_dcid_on_coalesced_packet()), there is not a proper way to detect it
2706 other than checking if the decryption successed
2707 */
2708 *error = "Missing TLS handshake, unsupported ciphers or padding";
2709 return NULL;
2710 }
2711
2712 /* Retrieve secrets for both the client and server. */
2713 if (!quic_get_traffic_secret(pinfo, quic_info->hash_algo, client_pp, TRUE) ||
2714 !quic_get_traffic_secret(pinfo, quic_info->hash_algo, server_pp, FALSE)) {
2715 quic_info->skip_decryption = TRUE;
2716 *error = "Secrets are not available";
2717 return NULL;
2718 }
2719
2720 // Create initial cipher handles for Key Phase 0 using the 1-RTT keys.
2721 if (!quic_hp_cipher_prepare(&client_pp->hp_cipher, quic_info->hash_algo,
2722 quic_info->cipher_algo, client_pp->next_secret, error) ||
2723 !quic_pp_cipher_prepare(&client_pp->pp_ciphers[0], quic_info->hash_algo,
2724 quic_info->cipher_algo, quic_info->cipher_mode, client_pp->next_secret, error) ||
2725 !quic_hp_cipher_prepare(&server_pp->hp_cipher, quic_info->hash_algo,
2726 quic_info->cipher_algo, server_pp->next_secret, error) ||
2727 !quic_pp_cipher_prepare(&server_pp->pp_ciphers[0], quic_info->hash_algo,
2728 quic_info->cipher_algo, quic_info->cipher_mode, server_pp->next_secret, error)) {
2729 quic_info->skip_decryption = TRUE;
2730 return NULL;
2731 }
2732 // Rotate the 1-RTT key for the client and server for the next key update.
2733 quic_update_key(quic_info->version, quic_info->hash_algo, client_pp);
2734 quic_update_key(quic_info->version, quic_info->hash_algo, server_pp);
2735
2736 // For efficiency, look up the application layer protocol once. The
2737 // handshake must have been completed before, so ALPN is known.
2738 const char *proto_name = tls_get_alpn(pinfo);
2739 if (proto_name) {
2740 quic_info->app_handle = dissector_get_string_handle(quic_proto_dissector_table, proto_name);
2741 // If no specific handle is found, alias "h3-*" to "h3" and "doq-*" to "doq"
2742 if (!quic_info->app_handle) {
2743 if (g_str_has_prefix(proto_name, "h3-")) {
2744 quic_info->app_handle = dissector_get_string_handle(quic_proto_dissector_table, "h3");
2745 } else if (g_str_has_prefix(proto_name, "doq-")) {
2746 quic_info->app_handle = dissector_get_string_handle(quic_proto_dissector_table, "doq");
2747 }
2748 }
2749 }
2750 }
2751
2752 // Note: Header Protect cipher does not change after Key Update.
2753 return &pp_state->hp_cipher;
2754 }
2755
2756 /**
2757 * Tries to construct the appropriate cipher for the current key phase.
2758 * See also "PROTECTED PAYLOAD DECRYPTION" comment on top of this file.
2759 */
2760 static quic_pp_cipher *
quic_get_pp_cipher(gboolean key_phase,quic_info_data_t * quic_info,gboolean from_server)2761 quic_get_pp_cipher(gboolean key_phase, quic_info_data_t *quic_info, gboolean from_server)
2762 {
2763 const char *error = NULL;
2764 gboolean success = FALSE;
2765
2766 /* Keys were previously not available. */
2767 if (quic_info->skip_decryption) {
2768 return NULL;
2769 }
2770
2771 quic_pp_state_t *client_pp = &quic_info->client_pp;
2772 quic_pp_state_t *server_pp = &quic_info->server_pp;
2773 quic_pp_state_t *pp_state = !from_server ? client_pp : server_pp;
2774
2775 /*
2776 * If the key phase changed, try to decrypt the packet using the new cipher.
2777 * If that fails, then it is either a malicious packet or out-of-order.
2778 * In that case, try the previous cipher (unless it is the very first KP1).
2779 * '!!' is due to key_phase being a signed bitfield, it forces -1 into 1.
2780 */
2781 if (key_phase != !!pp_state->key_phase) {
2782 quic_pp_cipher new_cipher;
2783
2784 memset(&new_cipher, 0, sizeof(new_cipher));
2785 if (!quic_pp_cipher_prepare(&new_cipher, quic_info->hash_algo,
2786 quic_info->cipher_algo, quic_info->cipher_mode, pp_state->next_secret, &error)) {
2787 /* This should never be reached, if the parameters were wrong
2788 * before, then it should have set "skip_decryption". */
2789 REPORT_DISSECTOR_BUG("quic_pp_cipher_prepare unexpectedly failed: %s", error);
2790 return NULL;
2791 }
2792
2793 // TODO verify decryption before switching keys.
2794 success = TRUE;
2795
2796 if (success) {
2797 /* Verified the cipher, use it from now on and rotate the key. */
2798 /* Note that HP cipher is not touched.
2799 https://tools.ietf.org/html/draft-ietf-quic-tls-32#section-5.4
2800 "The same header protection key is used for the duration of the
2801 connection, with the value not changing after a key update" */
2802 quic_pp_cipher_reset(&pp_state->pp_ciphers[key_phase]);
2803 pp_state->pp_ciphers[key_phase] = new_cipher;
2804 quic_update_key(quic_info->version, quic_info->hash_algo, pp_state);
2805
2806 pp_state->key_phase = key_phase;
2807 //pp_state->changed_in_pkn = pkn;
2808
2809 return &pp_state->pp_ciphers[key_phase];
2810 } else {
2811 // TODO fallback to previous cipher
2812 return NULL;
2813 }
2814 }
2815
2816 return &pp_state->pp_ciphers[key_phase];
2817 }
2818
2819 /**
2820 * Process (protected) payload, adding the encrypted payload to the tree. If
2821 * decryption is possible, frame dissection is also attempted.
2822 *
2823 * The given offset must correspond to the end of the QUIC header and begin of
2824 * the (protected) payload. Dissected frames are appended to "tree" and expert
2825 * info is attached to "ti" (the field with the encrypted payload).
2826 */
2827 static void
quic_process_payload(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,proto_item * ti,guint offset,quic_info_data_t * quic_info,quic_packet_info_t * quic_packet,gboolean from_server,quic_pp_cipher * pp_cipher,guint8 first_byte,guint pkn_len)2828 quic_process_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *ti, guint offset,
2829 quic_info_data_t *quic_info, quic_packet_info_t *quic_packet, gboolean from_server,
2830 quic_pp_cipher *pp_cipher, guint8 first_byte, guint pkn_len)
2831 {
2832 quic_decrypt_result_t *decryption = &quic_packet->decryption;
2833
2834 /*
2835 * If no decryption error has occurred yet, try decryption on the first
2836 * pass and store the result for later use.
2837 */
2838 if (!PINFO_FD_VISITED(pinfo)) {
2839 if (!quic_packet->decryption.error && quic_is_pp_cipher_initialized(pp_cipher)) {
2840 quic_decrypt_message(pp_cipher, tvb, offset, first_byte, pkn_len, quic_packet->packet_number, &quic_packet->decryption);
2841 }
2842 }
2843
2844 if (decryption->error) {
2845 expert_add_info_format(pinfo, ti, &ei_quic_decryption_failed,
2846 "Decryption failed: %s", decryption->error);
2847 } else if (decryption->data_len) {
2848 tvbuff_t *decrypted_tvb = tvb_new_child_real_data(tvb, decryption->data,
2849 decryption->data_len, decryption->data_len);
2850 add_new_data_source(pinfo, decrypted_tvb, "Decrypted QUIC");
2851
2852 guint decrypted_offset = 0;
2853 while (tvb_reported_length_remaining(decrypted_tvb, decrypted_offset) > 0) {
2854 if (quic_info->version == 0x51303530 || quic_info->version == 0x54303530 || quic_info->version == 0x54303531) {
2855 decrypted_offset = dissect_gquic_frame_type(decrypted_tvb, pinfo, tree, decrypted_offset, pkn_len, quic_info->gquic_info);
2856 } else {
2857 decrypted_offset = dissect_quic_frame_type(decrypted_tvb, pinfo, tree, decrypted_offset, quic_info, from_server);
2858 }
2859 }
2860 } else if (quic_info->skip_decryption) {
2861 expert_add_info_format(pinfo, ti, &ei_quic_decryption_failed,
2862 "Decryption skipped because keys are not available.");
2863 }
2864 }
2865
2866 static void
quic_verify_retry_token(tvbuff_t * tvb,quic_packet_info_t * quic_packet,const quic_cid_t * odcid,guint32 version)2867 quic_verify_retry_token(tvbuff_t *tvb, quic_packet_info_t *quic_packet, const quic_cid_t *odcid, guint32 version)
2868 {
2869 /*
2870 * Verify the Retry Integrity Tag using the fixed key from
2871 * https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-5.8
2872 */
2873 static const guint8 key_v1[] = {
2874 0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66, 0x57, 0x5a,
2875 0x1d, 0x76, 0x6b, 0x54, 0xe3, 0x68, 0xc8, 0x4e
2876 };
2877 static const guint8 nonce_v1[] = {
2878 0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb
2879 };
2880 static const guint8 key_draft_29[] = {
2881 0xcc, 0xce, 0x18, 0x7e, 0xd0, 0x9a, 0x09, 0xd0,
2882 0x57, 0x28, 0x15, 0x5a, 0x6c, 0xb9, 0x6b, 0xe1
2883 };
2884 static const guint8 nonce_draft_29[] = {
2885 0xe5, 0x49, 0x30, 0xf9, 0x7f, 0x21, 0x36, 0xf0, 0x53, 0x0a, 0x8c, 0x1c
2886 };
2887 static const guint8 key_draft_25[] = {
2888 0x4d, 0x32, 0xec, 0xdb, 0x2a, 0x21, 0x33, 0xc8,
2889 0x41, 0xe4, 0x04, 0x3d, 0xf2, 0x7d, 0x44, 0x30,
2890 };
2891 static const guint8 nonce_draft_25[] = {
2892 0x4d, 0x16, 0x11, 0xd0, 0x55, 0x13, 0xa5, 0x52, 0xc5, 0x87, 0xd5, 0x75,
2893 };
2894 gcry_cipher_hd_t h = NULL;
2895 gcry_error_t err;
2896 gint pseudo_packet_tail_length = tvb_reported_length(tvb) - 16;
2897
2898 DISSECTOR_ASSERT(pseudo_packet_tail_length > 0);
2899
2900 err = gcry_cipher_open(&h, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, 0);
2901 DISSECTOR_ASSERT_HINT(err == 0, "create cipher");
2902 if (is_quic_draft_max(version, 28)) {
2903 err = gcry_cipher_setkey(h, key_draft_25, sizeof(key_draft_25));
2904 } else if (is_quic_draft_max(version, 32)) {
2905 err = gcry_cipher_setkey(h, key_draft_29, sizeof(key_draft_29));
2906 } else {
2907 err = gcry_cipher_setkey(h, key_v1, sizeof(key_v1));
2908 }
2909 DISSECTOR_ASSERT_HINT(err == 0, "set key");
2910 if (is_quic_draft_max(version, 28)) {
2911 err = gcry_cipher_setiv(h, nonce_draft_25, sizeof(nonce_draft_25));
2912 } else if (is_quic_draft_max(version, 32)) {
2913 err = gcry_cipher_setiv(h, nonce_draft_29, sizeof(nonce_draft_29));
2914 } else {
2915 err = gcry_cipher_setiv(h, nonce_v1, sizeof(nonce_v1));
2916 }
2917 DISSECTOR_ASSERT_HINT(err == 0, "set nonce");
2918 G_STATIC_ASSERT(sizeof(odcid->len) == 1);
2919 err = gcry_cipher_authenticate(h, odcid, 1 + odcid->len);
2920 DISSECTOR_ASSERT_HINT(err == 0, "aad1");
2921 err = gcry_cipher_authenticate(h, tvb_get_ptr(tvb, 0, pseudo_packet_tail_length), pseudo_packet_tail_length);
2922 DISSECTOR_ASSERT_HINT(err == 0, "aad2");
2923 // Plaintext is empty, there is no need to call gcry_cipher_encrypt.
2924 err = gcry_cipher_checktag(h, tvb_get_ptr(tvb, pseudo_packet_tail_length, 16), 16);
2925 if (err) {
2926 quic_packet->retry_integrity_failure = TRUE;
2927 } else {
2928 quic_packet->retry_integrity_success = TRUE;
2929 }
2930 gcry_cipher_close(h);
2931 }
2932 #endif /* HAVE_LIBGCRYPT_AEAD */
2933
2934 void
quic_add_connection(packet_info * pinfo,const quic_cid_t * cid)2935 quic_add_connection(packet_info *pinfo, const quic_cid_t *cid)
2936 {
2937 #ifdef HAVE_LIBGCRYPT_AEAD
2938 quic_datagram *dgram_info;
2939
2940 dgram_info = (quic_datagram *)p_get_proto_data(wmem_file_scope(), pinfo, proto_quic, 0);
2941 if (dgram_info && dgram_info->conn) {
2942 quic_connection_add_cid(dgram_info->conn, cid, dgram_info->from_server);
2943 }
2944 #else
2945 (void)pinfo;
2946 (void)cid;
2947 #endif /* HAVE_LIBGCRYPT_AEAD */
2948 }
2949
2950 void
quic_add_loss_bits(packet_info * pinfo,guint64 value)2951 quic_add_loss_bits(packet_info *pinfo, guint64 value)
2952 {
2953 quic_datagram *dgram_info;
2954 quic_info_data_t *conn;
2955
2956 dgram_info = (quic_datagram *)p_get_proto_data(wmem_file_scope(), pinfo, proto_quic, 0);
2957 if (dgram_info && dgram_info->conn) {
2958 conn = dgram_info->conn;
2959 if (dgram_info->from_server) {
2960 conn->server_loss_bits_recv = TRUE;
2961 if (value == 1) {
2962 conn->server_loss_bits_send = TRUE;
2963 }
2964 } else {
2965 conn->client_loss_bits_recv = TRUE;
2966 if (value == 1) {
2967 conn->client_loss_bits_send = TRUE;
2968 }
2969 }
2970 }
2971 }
2972
2973 static void
quic_add_connection_info(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,quic_info_data_t * conn)2974 quic_add_connection_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, quic_info_data_t *conn)
2975 {
2976 proto_tree *ctree;
2977 proto_item *pi;
2978
2979 ctree = proto_tree_add_subtree(tree, tvb, 0, 0, ett_quic_connection_info, NULL, "QUIC Connection information");
2980 if (!conn) {
2981 expert_add_info(pinfo, ctree, &ei_quic_connection_unknown);
2982 return;
2983 }
2984
2985 pi = proto_tree_add_uint(ctree, hf_quic_connection_number, tvb, 0, 0, conn->number);
2986 proto_item_set_generated(pi);
2987 #if 0
2988 proto_tree_add_debug_text(ctree, "Client CID: %s", cid_to_string(&conn->client_cids.data));
2989 proto_tree_add_debug_text(ctree, "Server CID: %s", cid_to_string(&conn->server_cids.data));
2990 // Note: for Retry, this value has been cleared before.
2991 proto_tree_add_debug_text(ctree, "InitialCID: %s", cid_to_string(&conn->client_dcid_initial));
2992 #endif
2993 }
2994
2995 /**
2996 * Dissects the common part after the first byte for packets using the Long
2997 * Header form.
2998 */
2999 static int
dissect_quic_long_header_common(tvbuff_t * tvb,packet_info * pinfo,proto_tree * quic_tree,guint offset,const quic_packet_info_t * quic_packet _U_,guint32 * version_out,quic_cid_t * dcid,quic_cid_t * scid)3000 dissect_quic_long_header_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree,
3001 guint offset, const quic_packet_info_t *quic_packet _U_,
3002 guint32 *version_out, quic_cid_t *dcid, quic_cid_t *scid)
3003 {
3004 guint32 version;
3005 guint32 dcil, scil;
3006 proto_item *ti;
3007
3008 version = tvb_get_ntohl(tvb, offset);
3009
3010 if (version_out) {
3011 *version_out = version;
3012 }
3013
3014 ti = proto_tree_add_item(quic_tree, hf_quic_version, tvb, offset, 4, ENC_BIG_ENDIAN);
3015 if ((version & 0x0F0F0F0F) == 0x0a0a0a0a) {
3016 proto_item_append_text(ti, " (Forcing Version Negotiation)");
3017 }
3018 offset += 4;
3019
3020 proto_tree_add_item_ret_uint(quic_tree, hf_quic_dcil, tvb, offset, 1, ENC_BIG_ENDIAN, &dcil);
3021 offset++;
3022 if (dcil) {
3023 proto_tree_add_item(quic_tree, hf_quic_dcid, tvb, offset, dcil, ENC_NA);
3024 // TODO expert info on CID mismatch with connection
3025 if (dcil <= QUIC_MAX_CID_LENGTH) {
3026 tvb_memcpy(tvb, dcid->cid, offset, dcil);
3027 dcid->len = dcil;
3028 }
3029 offset += dcil;
3030 }
3031
3032 proto_tree_add_item_ret_uint(quic_tree, hf_quic_scil, tvb, offset, 1, ENC_BIG_ENDIAN, &scil);
3033 offset++;
3034 if (scil) {
3035 proto_tree_add_item(quic_tree, hf_quic_scid, tvb, offset, scil, ENC_NA);
3036 // TODO expert info on CID mismatch with connection
3037 if (scil <= QUIC_MAX_CID_LENGTH) {
3038 tvb_memcpy(tvb, scid->cid, offset, scil);
3039 scid->len = scil;
3040 }
3041 offset += scil;
3042 }
3043
3044 if (dcid->len > 0) {
3045 col_append_fstr(pinfo->cinfo, COL_INFO, ", DCID=%s", cid_to_string(dcid));
3046 }
3047 if (scid->len > 0) {
3048 col_append_fstr(pinfo->cinfo, COL_INFO, ", SCID=%s", cid_to_string(scid));
3049 }
3050 return offset;
3051 }
3052
3053 /* Retry Packet dissection */
3054 static int
dissect_quic_retry_packet(tvbuff_t * tvb,packet_info * pinfo,proto_tree * quic_tree,quic_datagram * dgram_info _U_,quic_packet_info_t * quic_packet,const quic_cid_t * odcid)3055 dissect_quic_retry_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree,
3056 quic_datagram *dgram_info _U_, quic_packet_info_t *quic_packet,
3057 const quic_cid_t *odcid)
3058 {
3059 guint offset = 0;
3060 guint32 version;
3061 quic_cid_t dcid = {.len=0}, scid = {.len=0};
3062 guint32 odcil = 0;
3063 guint retry_token_len;
3064 proto_item *ti;
3065
3066 proto_tree_add_item(quic_tree, hf_quic_long_packet_type, tvb, offset, 1, ENC_NA);
3067 offset += 1;
3068 col_set_str(pinfo->cinfo, COL_INFO, "Retry");
3069
3070 offset = dissect_quic_long_header_common(tvb, pinfo, quic_tree, offset, quic_packet, &version, &dcid, &scid);
3071
3072 if (is_quic_draft_max(version, 24)) {
3073 proto_tree_add_item_ret_uint(quic_tree, hf_quic_odcil, tvb, offset, 1, ENC_NA, &odcil);
3074 offset++;
3075 proto_tree_add_item(quic_tree, hf_quic_odcid, tvb, offset, odcil, ENC_NA);
3076 offset += odcil;
3077 }
3078
3079 retry_token_len = tvb_reported_length_remaining(tvb, offset);
3080 // Remove length of Retry Integrity Tag
3081 if (!is_quic_draft_max(version, 24) && retry_token_len >= 16) {
3082 retry_token_len -= 16;
3083 }
3084 proto_tree_add_item(quic_tree, hf_quic_retry_token, tvb, offset, retry_token_len, ENC_NA);
3085 offset += retry_token_len;
3086
3087 if (!is_quic_draft_max(version, 24)) {
3088 // Verify the Retry Integrity Tag according to
3089 // https://tools.ietf.org/html/draft-ietf-quic-tls-25#section-5.8
3090 ti = proto_tree_add_item(quic_tree, hf_quic_retry_integrity_tag, tvb, offset, 16, ENC_NA);
3091 #ifdef HAVE_LIBGCRYPT_AEAD
3092 if (!PINFO_FD_VISITED(pinfo) && odcid) {
3093 // Skip validation if the Initial Packet is unknown, for example due
3094 // to packet loss in the capture file.
3095 quic_verify_retry_token(tvb, quic_packet, odcid, version);
3096 }
3097 if (quic_packet->retry_integrity_failure) {
3098 expert_add_info(pinfo, ti, &ei_quic_bad_retry);
3099 } else if (!quic_packet->retry_integrity_success) {
3100 expert_add_info_format(pinfo, ti, &ei_quic_bad_retry,
3101 "Cannot verify Retry Packet due to unknown ODCID");
3102 } else {
3103 proto_item_append_text(ti, " [verified]");
3104 }
3105 #else
3106 (void)odcid;
3107 expert_add_info_format(pinfo, ti, &ei_quic_bad_retry,
3108 "Libgcrypt >= 1.6.0 is required for Retry Packet verification");
3109 #endif /* HAVE_LIBGCRYPT_AEAD */
3110 offset += 16;
3111 }
3112
3113 return offset;
3114 }
3115
3116 static int
dissect_quic_long_header(tvbuff_t * tvb,packet_info * pinfo,proto_tree * quic_tree,quic_datagram * dgram_info,quic_packet_info_t * quic_packet)3117 dissect_quic_long_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree,
3118 quic_datagram *dgram_info, quic_packet_info_t *quic_packet)
3119 {
3120 guint offset = 0;
3121 guint8 long_packet_type;
3122 guint32 version;
3123 quic_cid_t dcid = {.len=0}, scid = {.len=0};
3124 gint32 len_token_length;
3125 guint64 token_length;
3126 gint32 len_payload_length;
3127 guint64 payload_length;
3128 guint8 first_byte = 0;
3129 quic_info_data_t *conn = dgram_info->conn;
3130 #ifdef HAVE_LIBGCRYPT_AEAD
3131 const gboolean from_server = dgram_info->from_server;
3132 quic_ciphers *ciphers = NULL;
3133 proto_item *ti;
3134 #endif /* HAVE_LIBGCRYPT_AEAD */
3135
3136 quic_extract_header(tvb, &long_packet_type, &version, &dcid, &scid);
3137 #ifdef HAVE_LIBGCRYPT_AEAD
3138 if (conn) {
3139 if (long_packet_type == QUIC_LPT_INITIAL) {
3140 ciphers = !from_server ? &conn->client_initial_ciphers : &conn->server_initial_ciphers;
3141 } else if (long_packet_type == QUIC_LPT_0RTT && !from_server) {
3142 ciphers = &conn->client_0rtt_ciphers;
3143 } else if (long_packet_type == QUIC_LPT_HANDSHAKE) {
3144 ciphers = !from_server ? &conn->client_handshake_ciphers : &conn->server_handshake_ciphers;
3145 }
3146 }
3147 /* Prepare the Initial/Handshake cipher for header/payload decryption. */
3148 if (!PINFO_FD_VISITED(pinfo) && conn && ciphers) {
3149 #define DIGEST_MIN_SIZE 32 /* SHA256 */
3150 #define DIGEST_MAX_SIZE 48 /* SHA384 */
3151 const gchar *error = NULL;
3152 gchar early_data_secret[DIGEST_MAX_SIZE];
3153 guint early_data_secret_len = 0;
3154 if (long_packet_type == QUIC_LPT_INITIAL && !from_server &&
3155 !memcmp(&dcid, &conn->client_dcid_initial, sizeof(quic_cid_t))) {
3156 /* Create new decryption context based on the Client Connection
3157 * ID from the *very first* Client Initial packet. */
3158 quic_create_initial_decoders(&dcid, &error, conn);
3159 } else if (long_packet_type == QUIC_LPT_0RTT) {
3160 early_data_secret_len = tls13_get_quic_secret(pinfo, FALSE, TLS_SECRET_0RTT_APP, DIGEST_MIN_SIZE, DIGEST_MAX_SIZE, early_data_secret);
3161 if (early_data_secret_len == 0) {
3162 error = "Secrets are not available";
3163 }
3164 } else if (long_packet_type == QUIC_LPT_HANDSHAKE) {
3165 if (!quic_are_ciphers_initialized(ciphers)) {
3166 quic_create_decoders(pinfo, conn, ciphers, from_server, TLS_SECRET_HANDSHAKE, &error);
3167 }
3168 }
3169 if (!error) {
3170 guint32 pkn32 = 0;
3171 int hp_cipher_algo = long_packet_type != QUIC_LPT_INITIAL && conn ? conn->cipher_algo : GCRY_CIPHER_AES128;
3172 // PKN is after type(1) + version(4) + DCIL+DCID + SCIL+SCID
3173 guint pn_offset = 1 + 4 + 1 + dcid.len + 1 + scid.len;
3174 if (long_packet_type == QUIC_LPT_INITIAL) {
3175 pn_offset += tvb_get_varint(tvb, pn_offset, 8, &token_length, ENC_VARINT_QUIC);
3176 pn_offset += (guint)token_length;
3177 }
3178 pn_offset += tvb_get_varint(tvb, pn_offset, 8, &payload_length, ENC_VARINT_QUIC);
3179
3180 // Assume failure unless proven otherwise.
3181 error = "Header deprotection failed";
3182 if (long_packet_type != QUIC_LPT_0RTT) {
3183 if (quic_decrypt_header(tvb, pn_offset, &ciphers->hp_cipher, hp_cipher_algo, &first_byte, &pkn32, FALSE)) {
3184 error = NULL;
3185 }
3186 } else {
3187 // Cipher is not stored with 0-RTT data or key, perform trial decryption.
3188 for (guint i = 0; quic_create_0rtt_decoder(i, early_data_secret, early_data_secret_len, ciphers, &hp_cipher_algo); i++) {
3189 if (quic_is_hp_cipher_initialized(&ciphers->hp_cipher) && quic_decrypt_header(tvb, pn_offset, &ciphers->hp_cipher, hp_cipher_algo, &first_byte, &pkn32, FALSE)) {
3190 error = NULL;
3191 break;
3192 }
3193 }
3194 }
3195 if (!error) {
3196 quic_set_full_packet_number(conn, quic_packet, from_server, first_byte, pkn32);
3197 quic_packet->first_byte = first_byte;
3198 }
3199 }
3200 if (error) {
3201 quic_packet->decryption.error = wmem_strdup(wmem_file_scope(), error);
3202 }
3203 } else if (conn && quic_packet->pkn_len) {
3204 first_byte = quic_packet->first_byte;
3205 }
3206 #endif /* HAVE_LIBGCRYPT_AEAD */
3207
3208 proto_tree_add_item(quic_tree, hf_quic_fixed_bit, tvb, offset, 1, ENC_NA);
3209 proto_tree_add_item(quic_tree, hf_quic_long_packet_type, tvb, offset, 1, ENC_NA);
3210 if (quic_packet->pkn_len) {
3211 proto_tree_add_uint(quic_tree, hf_quic_long_reserved, tvb, offset, 1, first_byte);
3212 proto_tree_add_uint(quic_tree, hf_quic_packet_number_length, tvb, offset, 1, first_byte);
3213 }
3214 offset += 1;
3215 col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(long_packet_type, quic_long_packet_type_vals, "Long Header"));
3216
3217 offset = dissect_quic_long_header_common(tvb, pinfo, quic_tree, offset, quic_packet, NULL, &dcid, &scid);
3218
3219 if (long_packet_type == QUIC_LPT_INITIAL) {
3220 proto_tree_add_item_ret_varint(quic_tree, hf_quic_token_length, tvb, offset, -1, ENC_VARINT_QUIC, &token_length, &len_token_length);
3221 offset += len_token_length;
3222
3223 if (token_length) {
3224 proto_tree_add_item(quic_tree, hf_quic_token, tvb, offset, (guint32)token_length, ENC_NA);
3225 offset += (guint)token_length;
3226 }
3227 }
3228
3229 proto_tree_add_item_ret_varint(quic_tree, hf_quic_length, tvb, offset, -1, ENC_VARINT_QUIC, &payload_length, &len_payload_length);
3230 offset += len_payload_length;
3231
3232 if (quic_packet->decryption.error) {
3233 expert_add_info_format(pinfo, quic_tree, &ei_quic_decryption_failed,
3234 "Failed to create decryption context: %s", quic_packet->decryption.error);
3235 return offset;
3236 }
3237 if (!conn || quic_packet->pkn_len == 0) {
3238 #ifndef HAVE_LIBGCRYPT_AEAD
3239 expert_add_info_format(pinfo, quic_tree, &ei_quic_decryption_failed, "Libgcrypt >= 1.6.0 is required for QUIC decryption");
3240 #else
3241 // if not part of a connection, the full PKN cannot be reconstructed.
3242 expert_add_info_format(pinfo, quic_tree, &ei_quic_decryption_failed, "Failed to decrypt packet number");
3243 #endif /* HAVE_LIBGCRYPT_AEAD */
3244 return offset;
3245 }
3246
3247 proto_tree_add_uint64(quic_tree, hf_quic_packet_number, tvb, offset, quic_packet->pkn_len, quic_packet->packet_number);
3248 offset += quic_packet->pkn_len;
3249 col_append_fstr(pinfo->cinfo, COL_INFO, ", PKN: %" G_GINT64_MODIFIER "u", quic_packet->packet_number);
3250
3251 /* Payload */
3252 #ifdef HAVE_LIBGCRYPT_AEAD
3253 ti = proto_tree_add_item(quic_tree, hf_quic_payload, tvb, offset, -1, ENC_NA);
3254 #else
3255 proto_tree_add_item(quic_tree, hf_quic_payload, tvb, offset, -1, ENC_NA);
3256 #endif /* HAVE_LIBGCRYPT_AEAD */
3257
3258 #ifdef HAVE_LIBGCRYPT_AEAD
3259 if (conn) {
3260 quic_process_payload(tvb, pinfo, quic_tree, ti, offset,
3261 conn, quic_packet, from_server, &ciphers->pp_cipher, first_byte, quic_packet->pkn_len);
3262 }
3263 if (!PINFO_FD_VISITED(pinfo) && !quic_packet->decryption.error) {
3264 // Packet number is verified to be valid, remember it.
3265 *quic_max_packet_number(conn, from_server, first_byte) = quic_packet->packet_number;
3266 }
3267 #endif /* HAVE_LIBGCRYPT_AEAD */
3268 offset += tvb_reported_length_remaining(tvb, offset);
3269
3270 return offset;
3271 }
3272
3273 /* Check if "loss bits" feature has been negotiated */
3274 static gboolean
quic_loss_bits_negotiated(quic_info_data_t * conn,gboolean from_server)3275 quic_loss_bits_negotiated(quic_info_data_t *conn, gboolean from_server)
3276 {
3277 if (from_server) {
3278 return conn->client_loss_bits_recv && conn->server_loss_bits_send;
3279 } else {
3280 return conn->server_loss_bits_recv && conn->client_loss_bits_send;
3281 }
3282 }
3283
3284 static int
dissect_quic_short_header(tvbuff_t * tvb,packet_info * pinfo,proto_tree * quic_tree,quic_datagram * dgram_info,quic_packet_info_t * quic_packet)3285 dissect_quic_short_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree,
3286 quic_datagram *dgram_info, quic_packet_info_t *quic_packet)
3287 {
3288 guint offset = 0;
3289 quic_cid_t dcid = {.len=0};
3290 guint8 first_byte = 0;
3291 gboolean key_phase = FALSE;
3292 #ifdef HAVE_LIBGCRYPT_AEAD
3293 proto_item *ti;
3294 quic_pp_cipher *pp_cipher = NULL;
3295 #endif /* HAVE_LIBGCRYPT_AEAD */
3296 quic_info_data_t *conn = dgram_info->conn;
3297 const gboolean from_server = dgram_info->from_server;
3298 gboolean loss_bits_negotiated = FALSE;
3299
3300 proto_item *pi = proto_tree_add_item(quic_tree, hf_quic_short, tvb, 0, -1, ENC_NA);
3301 proto_tree *hdr_tree = proto_item_add_subtree(pi, ett_quic_short_header);
3302 proto_tree_add_item(hdr_tree, hf_quic_header_form, tvb, 0, 1, ENC_NA);
3303
3304 if (conn) {
3305 dcid.len = from_server ? conn->client_cids.data.len : conn->server_cids.data.len;
3306 loss_bits_negotiated = quic_loss_bits_negotiated(conn, from_server);
3307 }
3308 #ifdef HAVE_LIBGCRYPT_AEAD
3309 if (!PINFO_FD_VISITED(pinfo) && conn) {
3310 const gchar *error = NULL;
3311 guint32 pkn32 = 0;
3312 quic_hp_cipher *hp_cipher = quic_get_1rtt_hp_cipher(pinfo, conn, from_server, &error);
3313 if (quic_is_hp_cipher_initialized(hp_cipher) && quic_decrypt_header(tvb, 1 + dcid.len, hp_cipher, conn->cipher_algo, &first_byte, &pkn32, loss_bits_negotiated)) {
3314 quic_set_full_packet_number(conn, quic_packet, from_server, first_byte, pkn32);
3315 quic_packet->first_byte = first_byte;
3316 }
3317 if (error) {
3318 quic_packet->decryption.error = wmem_strdup(wmem_file_scope(), error);
3319 }
3320 } else if (conn && quic_packet->pkn_len) {
3321 first_byte = quic_packet->first_byte;
3322 }
3323 #endif /* HAVE_LIBGCRYPT_AEAD */
3324 proto_tree_add_item(hdr_tree, hf_quic_fixed_bit, tvb, offset, 1, ENC_NA);
3325 proto_tree_add_item(hdr_tree, hf_quic_spin_bit, tvb, offset, 1, ENC_NA);
3326 /* Q and L bits are not protected by HP cipher */
3327 if (loss_bits_negotiated) {
3328 proto_tree_add_item(hdr_tree, hf_quic_q_bit, tvb, offset, 1, ENC_NA);
3329 proto_tree_add_item(hdr_tree, hf_quic_l_bit, tvb, offset, 1, ENC_NA);
3330 }
3331 if (quic_packet->pkn_len) {
3332 key_phase = (first_byte & SH_KP) != 0;
3333 /* No room for reserved bits with "loss bits" feature is enable */
3334 if (!loss_bits_negotiated) {
3335 proto_tree_add_uint(hdr_tree, hf_quic_short_reserved, tvb, offset, 1, first_byte);
3336 }
3337 proto_tree_add_boolean(hdr_tree, hf_quic_key_phase, tvb, offset, 1, key_phase<<2);
3338 proto_tree_add_uint(hdr_tree, hf_quic_packet_number_length, tvb, offset, 1, first_byte);
3339 }
3340 offset += 1;
3341
3342 col_clear(pinfo->cinfo, COL_INFO);
3343 col_append_fstr(pinfo->cinfo, COL_INFO, "Protected Payload (KP%u)", key_phase);
3344
3345 /* Connection ID */
3346 if (dcid.len > 0) {
3347 proto_tree_add_item(hdr_tree, hf_quic_dcid, tvb, offset, dcid.len, ENC_NA);
3348 tvb_memcpy(tvb, dcid.cid, offset, dcid.len);
3349 offset += dcid.len;
3350 const char *dcid_str = cid_to_string(&dcid);
3351 col_append_fstr(pinfo->cinfo, COL_INFO, ", DCID=%s", dcid_str);
3352 proto_item_append_text(pi, " DCID=%s", dcid_str);
3353 }
3354
3355 #ifdef HAVE_LIBGCRYPT_AEAD
3356 if (!PINFO_FD_VISITED(pinfo) && conn) {
3357 pp_cipher = quic_get_pp_cipher(key_phase, conn, from_server);
3358 }
3359 #endif /* HAVE_LIBGCRYPT_AEAD */
3360
3361 if (quic_packet->decryption.error) {
3362 expert_add_info_format(pinfo, quic_tree, &ei_quic_decryption_failed,
3363 "Failed to create decryption context: %s", quic_packet->decryption.error);
3364 return offset;
3365 }
3366 if (!conn || conn->skip_decryption || quic_packet->pkn_len == 0) {
3367 return offset;
3368 }
3369
3370 /* Packet Number */
3371 proto_tree_add_uint64(hdr_tree, hf_quic_packet_number, tvb, offset, quic_packet->pkn_len, quic_packet->packet_number);
3372 offset += quic_packet->pkn_len;
3373 col_append_fstr(pinfo->cinfo, COL_INFO, ", PKN: %" G_GINT64_MODIFIER "u", quic_packet->packet_number);
3374 proto_item_append_text(pi, " PKN=%" G_GINT64_MODIFIER "u", quic_packet->packet_number);
3375
3376 /* Protected Payload */
3377 #ifdef HAVE_LIBGCRYPT_AEAD
3378 ti = proto_tree_add_item(hdr_tree, hf_quic_protected_payload, tvb, offset, -1, ENC_NA);
3379 #else
3380 proto_tree_add_item(hdr_tree, hf_quic_protected_payload, tvb, offset, -1, ENC_NA);
3381 #endif /* HAVE_LIBGCRYPT_AEAD */
3382
3383 #ifdef HAVE_LIBGCRYPT_AEAD
3384 if (conn) {
3385 quic_process_payload(tvb, pinfo, quic_tree, ti, offset,
3386 conn, quic_packet, from_server, pp_cipher, first_byte, quic_packet->pkn_len);
3387 if (!PINFO_FD_VISITED(pinfo) && !quic_packet->decryption.error) {
3388 // Packet number is verified to be valid, remember it.
3389 *quic_max_packet_number(conn, from_server, first_byte) = quic_packet->packet_number;
3390 }
3391 }
3392 #endif /* HAVE_LIBGCRYPT_AEAD */
3393 offset += tvb_reported_length_remaining(tvb, offset);
3394
3395 return offset;
3396 }
3397
3398 void
quic_proto_tree_add_version(tvbuff_t * tvb,proto_tree * tree,int hfindex,guint offset)3399 quic_proto_tree_add_version(tvbuff_t *tvb, proto_tree *tree, int hfindex, guint offset)
3400 {
3401 guint32 version;
3402 proto_item *ti;
3403
3404 ti = proto_tree_add_item_ret_uint(tree, hfindex, tvb, offset, 4, ENC_BIG_ENDIAN, &version);
3405 if ((version & 0x0F0F0F0F) == 0x0a0a0a0a) {
3406 proto_item_append_text(ti, " (GREASE)");
3407 }
3408 }
3409
3410 static int
dissect_quic_version_negotiation(tvbuff_t * tvb,packet_info * pinfo,proto_tree * quic_tree,const quic_packet_info_t * quic_packet)3411 dissect_quic_version_negotiation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree, const quic_packet_info_t *quic_packet)
3412 {
3413 guint offset = 0;
3414 quic_cid_t dcid = {.len=0}, scid = {.len=0};
3415
3416 col_set_str(pinfo->cinfo, COL_INFO, "Version Negotiation");
3417
3418 proto_tree_add_item(quic_tree, hf_quic_vn_unused, tvb, offset, 1, ENC_NA);
3419 offset += 1;
3420
3421 offset = dissect_quic_long_header_common(tvb, pinfo, quic_tree, offset, quic_packet, NULL, &dcid, &scid);
3422
3423 /* Supported Version */
3424 while(tvb_reported_length_remaining(tvb, offset) > 0){
3425 quic_proto_tree_add_version(tvb, quic_tree, hf_quic_supported_version, offset);
3426 offset += 4;
3427 }
3428
3429 return offset;
3430 }
3431
3432 static tvbuff_t *
quic_get_message_tvb(tvbuff_t * tvb,const guint offset)3433 quic_get_message_tvb(tvbuff_t *tvb, const guint offset)
3434 {
3435 guint64 token_length;
3436 guint64 payload_length;
3437 guint8 packet_type = tvb_get_guint8(tvb, offset);
3438 guint8 long_packet_type = (packet_type & 0x30) >> 4;
3439 // Retry and VN packets cannot be coalesced (clarified in draft -14).
3440 if ((packet_type & 0x80) && long_packet_type != QUIC_LPT_RETRY) {
3441 // long header form, check version
3442 guint version = tvb_get_ntohl(tvb, offset + 1);
3443 // If this is not a VN packet but a valid long form, extract a subset.
3444 // TODO check for valid QUIC versions as future versions might change the format.
3445 if (version != 0) {
3446 guint length = 5; // flag (1 byte) + version (4 bytes)
3447 length += 1 + tvb_get_guint8(tvb, offset + length); // DCID
3448 length += 1 + tvb_get_guint8(tvb, offset + length); // SCID
3449 if (long_packet_type == QUIC_LPT_INITIAL) {
3450 length += tvb_get_varint(tvb, offset + length, 8, &token_length, ENC_VARINT_QUIC);
3451 length += (guint)token_length;
3452 }
3453 length += tvb_get_varint(tvb, offset + length, 8, &payload_length, ENC_VARINT_QUIC);
3454 length += (guint)payload_length;
3455 if (payload_length <= G_MAXINT32 && length < (guint)tvb_reported_length_remaining(tvb, offset)) {
3456 return tvb_new_subset_length(tvb, offset, length);
3457 }
3458 }
3459 }
3460
3461 // short header form, VN or unknown message, return remaining data.
3462 return tvb_new_subset_remaining(tvb, offset);
3463 }
3464
3465 /**
3466 * Extracts necessary information from header to find any existing connection.
3467 * There are two special values for "long_packet_type":
3468 * * QUIC_SHORT_PACKET for short header packets;
3469 * * QUIC_LPT_VER_NEG for Version Negotiation packets.
3470 * DCID and SCID are not modified unless available. For short header packets,
3471 * DCID length is unknown, so the caller should truncate it as needed.
3472 */
3473 static void
quic_extract_header(tvbuff_t * tvb,guint8 * long_packet_type,guint32 * version,quic_cid_t * dcid,quic_cid_t * scid)3474 quic_extract_header(tvbuff_t *tvb, guint8 *long_packet_type, guint32 *version,
3475 quic_cid_t *dcid, quic_cid_t *scid)
3476 {
3477 guint offset = 0;
3478
3479 guint8 packet_type = tvb_get_guint8(tvb, offset);
3480 gboolean is_long_header = packet_type & 0x80;
3481 if (is_long_header) {
3482 // long header form
3483 *long_packet_type = (packet_type & 0x30) >> 4;
3484 } else {
3485 // short header form, store dummy value that is not a long packet type.
3486 *long_packet_type = QUIC_SHORT_PACKET;
3487 }
3488 offset++;
3489
3490 *version = tvb_get_ntohl(tvb, offset);
3491
3492 if (is_long_header) {
3493 /* VN packets don't have any real packet type field, even if they have
3494 a long header: use a dummy value */
3495 if (*version == 0x00000000)
3496 *long_packet_type = QUIC_LPT_VER_NEG;
3497
3498 // skip version
3499 offset += 4;
3500
3501 // read DCID and SCID (both are prefixed by a length byte).
3502 guint8 dcil = tvb_get_guint8(tvb, offset);
3503 offset++;
3504
3505 if (dcil && dcil <= QUIC_MAX_CID_LENGTH) {
3506 tvb_memcpy(tvb, dcid->cid, offset, dcil);
3507 dcid->len = dcil;
3508 }
3509 offset += dcil;
3510
3511 guint8 scil = tvb_get_guint8(tvb, offset);
3512 offset++;
3513 if (scil && scil <= QUIC_MAX_CID_LENGTH) {
3514 tvb_memcpy(tvb, scid->cid, offset, scil);
3515 scid->len = scil;
3516 }
3517 } else {
3518 // Definitely not draft -10, set version to dummy value.
3519 *version = 0;
3520 // For short headers, the DCID length is unknown and could be 0 or
3521 // anything from 1 to 20 bytes. Copy the maximum possible and let the
3522 // consumer truncate it as necessary.
3523 tvb_memcpy(tvb, dcid->cid, offset, QUIC_MAX_CID_LENGTH);
3524 dcid->len = QUIC_MAX_CID_LENGTH;
3525 }
3526 }
3527
3528 /**
3529 * Sanity check on (coalasced) packet.
3530 * https://tools.ietf.org/html/draft-ietf-quic-transport-32#section-12.2
3531 * "Senders MUST NOT coalesce QUIC packets with different connection IDs
3532 * into a single UDP datagram"
3533 * For the first packet of the datagram, we simply save the DCID for later usage (no real check).
3534 * For any subsequent packets, we control if DCID is valid.
3535 */
3536 static gboolean
check_dcid_on_coalesced_packet(tvbuff_t * tvb,const quic_datagram * dgram_info,gboolean is_first_packet,quic_cid_t * first_packet_dcid)3537 check_dcid_on_coalesced_packet(tvbuff_t *tvb, const quic_datagram *dgram_info,
3538 gboolean is_first_packet, quic_cid_t *first_packet_dcid)
3539 {
3540 guint offset = 0;
3541 guint8 first_byte, dcid_len;
3542 quic_cid_t dcid = {.len=0};
3543
3544 first_byte = tvb_get_guint8(tvb, offset);
3545 offset++;
3546 if (first_byte & 0x80) {
3547 offset += 4; /* Skip version */
3548 dcid_len = tvb_get_guint8(tvb, offset);
3549 offset++;
3550 if (dcid_len && dcid_len <= QUIC_MAX_CID_LENGTH) {
3551 dcid.len = dcid_len;
3552 tvb_memcpy(tvb, dcid.cid, offset, dcid.len);
3553 }
3554 } else {
3555 quic_info_data_t *conn = dgram_info->conn;
3556 gboolean from_server = dgram_info->from_server;
3557 if (conn) {
3558 dcid.len = from_server ? conn->client_cids.data.len : conn->server_cids.data.len;
3559 if (dcid.len) {
3560 tvb_memcpy(tvb, dcid.cid, offset, dcid.len);
3561 }
3562 } else {
3563 /* If we don't have a valid quic_info_data_t structure for this flow,
3564 we can't really validate the CID. */
3565 return TRUE;
3566 }
3567 }
3568
3569 if (is_first_packet) {
3570 *first_packet_dcid = dcid;
3571 return TRUE; /* Nothing to check */
3572 }
3573
3574 return quic_connection_equal(&dcid, first_packet_dcid);
3575 }
3576
3577 static int
dissect_quic(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3578 dissect_quic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3579 void *data _U_)
3580 {
3581 proto_item *quic_ti, *ti;
3582 proto_tree *quic_tree;
3583 guint offset = 0;
3584 quic_datagram *dgram_info = NULL;
3585 quic_packet_info_t *quic_packet = NULL;
3586 quic_cid_t real_retry_odcid = {.len=0}, *retry_odcid = NULL;
3587 quic_cid_t first_packet_dcid = {.len=0}; /* DCID of the first packet of the datagram */
3588
3589 col_set_str(pinfo->cinfo, COL_PROTOCOL, "QUIC");
3590
3591 if (PINFO_FD_VISITED(pinfo)) {
3592 dgram_info = (quic_datagram *)p_get_proto_data(wmem_file_scope(), pinfo, proto_quic, 0);
3593 }
3594 if (!dgram_info) {
3595 dgram_info = wmem_new0(wmem_file_scope(), quic_datagram);
3596 p_add_proto_data(wmem_file_scope(), pinfo, proto_quic, 0, dgram_info);
3597 }
3598
3599 quic_ti = proto_tree_add_item(tree, proto_quic, tvb, 0, -1, ENC_NA);
3600 quic_tree = proto_item_add_subtree(quic_ti, ett_quic);
3601
3602 if (!PINFO_FD_VISITED(pinfo)) {
3603 guint8 long_packet_type;
3604 guint32 version;
3605 quic_cid_t dcid = {.len=0}, scid = {.len=0};
3606 gboolean from_server = FALSE;
3607 quic_info_data_t *conn;
3608
3609 quic_extract_header(tvb, &long_packet_type, &version, &dcid, &scid);
3610 conn = quic_connection_find(pinfo, long_packet_type, &dcid, &from_server);
3611 if (conn && long_packet_type == QUIC_LPT_RETRY && conn->client_dcid_set) {
3612 // Save the original client DCID before erasure.
3613 real_retry_odcid = conn->client_dcid_initial;
3614 retry_odcid = &real_retry_odcid;
3615 }
3616 quic_connection_create_or_update(&conn, pinfo, long_packet_type, version, &scid, &dcid, from_server);
3617 dgram_info->conn = conn;
3618 dgram_info->from_server = from_server;
3619 #if 0
3620 proto_tree_add_debug_text(quic_tree, "Connection: %d %p DCID=%s SCID=%s from_server:%d", pinfo->num, dgram_info->conn, cid_to_string(&dcid), cid_to_string(&scid), dgram_info->from_server);
3621 } else {
3622 proto_tree_add_debug_text(quic_tree, "Connection: %d %p from_server:%d", pinfo->num, dgram_info->conn, dgram_info->from_server);
3623 #endif
3624 }
3625
3626 quic_add_connection_info(tvb, pinfo, quic_tree, dgram_info->conn);
3627
3628 do {
3629 if (!quic_packet) {
3630 quic_packet = &dgram_info->first_packet;
3631 } else if (!PINFO_FD_VISITED(pinfo)) {
3632 quic_packet->next = wmem_new0(wmem_file_scope(), quic_packet_info_t);
3633 quic_packet = quic_packet->next;
3634 } else {
3635 quic_packet = quic_packet->next;
3636 DISSECTOR_ASSERT(quic_packet);
3637 }
3638
3639 /* Ensure that coalesced QUIC packets end up separated. */
3640 if (offset > 0) {
3641 quic_ti = proto_tree_add_item(tree, proto_quic, tvb, offset, -1, ENC_NA);
3642 quic_tree = proto_item_add_subtree(quic_ti, ett_quic);
3643 }
3644
3645 tvbuff_t *next_tvb = quic_get_message_tvb(tvb, offset);
3646
3647 if (!check_dcid_on_coalesced_packet(next_tvb, dgram_info, offset == 0, &first_packet_dcid)) {
3648 /* Coalesced packet with unexpected CID; it probably is some kind
3649 of unencrypted padding data added after the valid QUIC payload */
3650 expert_add_info_format(pinfo, quic_tree, &ei_quic_coalesced_padding_data,
3651 "(Random) padding data appended to the datagram");
3652 break;
3653 }
3654
3655 proto_item_set_len(quic_ti, tvb_reported_length(next_tvb));
3656 ti = proto_tree_add_uint(quic_tree, hf_quic_packet_length, next_tvb, 0, 0, tvb_reported_length(next_tvb));
3657 proto_item_set_generated(ti);
3658 guint new_offset = 0;
3659 guint8 first_byte = tvb_get_guint8(next_tvb, 0);
3660 if (first_byte & 0x80) {
3661 guint8 long_packet_type = (first_byte & 0x30) >> 4;
3662 proto_tree_add_item(quic_tree, hf_quic_header_form, next_tvb, 0, 1, ENC_NA);
3663 guint32 version = tvb_get_ntohl(next_tvb, 1);
3664 if (version == 0) {
3665 offset += dissect_quic_version_negotiation(next_tvb, pinfo, quic_tree, quic_packet);
3666 break;
3667 }
3668 if (long_packet_type == QUIC_LPT_RETRY) {
3669 new_offset = dissect_quic_retry_packet(next_tvb, pinfo, quic_tree, dgram_info, quic_packet, retry_odcid);
3670 } else {
3671 new_offset = dissect_quic_long_header(next_tvb, pinfo, quic_tree, dgram_info, quic_packet);
3672 }
3673 } else { /* Note that the "Fixed" bit might have been greased,
3674 so 0x00 is a perfectly valid value as first_byte */
3675 new_offset = dissect_quic_short_header(next_tvb, pinfo, quic_tree, dgram_info, quic_packet);
3676 }
3677 if (tvb_reported_length_remaining(next_tvb, new_offset)) {
3678 // should usually not be present unless decryption is not possible.
3679 proto_tree_add_item(quic_tree, hf_quic_remaining_payload, next_tvb, new_offset, -1, ENC_NA);
3680 }
3681 offset += tvb_reported_length(next_tvb);
3682 } while (tvb_reported_length_remaining(tvb, offset));
3683
3684 return offset;
3685 }
3686
3687 static gboolean
dissect_quic_short_header_heur(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)3688 dissect_quic_short_header_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3689 {
3690 // If this capture does not contain QUIC, skip the more expensive checks.
3691 if (quic_cid_lengths == 0) {
3692 return FALSE;
3693 }
3694
3695 // Is this a SH packet after connection migration? SH (since draft -22):
3696 // Flag (1) + DCID (1-20) + PKN (1/2/4) + encrypted payload (>= 16).
3697 if (tvb_captured_length(tvb) < 1 + 1 + 1 + 16) {
3698 return FALSE;
3699 }
3700
3701 // DCID length is unknown, so extract the maximum and look for a match.
3702 quic_cid_t dcid = {.len = MIN(QUIC_MAX_CID_LENGTH, tvb_captured_length(tvb) - 1 - 1 - 16)};
3703 tvb_memcpy(tvb, dcid.cid, 1, dcid.len);
3704 gboolean from_server;
3705 if (!quic_connection_find(pinfo, QUIC_SHORT_PACKET, &dcid, &from_server)) {
3706 return FALSE;
3707 }
3708
3709 conversation_t *conversation = find_or_create_conversation(pinfo);
3710 conversation_set_dissector(conversation, quic_handle);
3711 dissect_quic(tvb, pinfo, tree, NULL);
3712 return TRUE;
3713 }
3714
dissect_quic_heur(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3715 static gboolean dissect_quic_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3716 {
3717 /*
3718 * Since draft -22:
3719 * Flag (1 byte) + Version (4 bytes) +
3720 * Length (1 byte) + Destination Connection ID (0..255) +
3721 * Length (1 byte) + Source Connection ID (0..255) +
3722 * Payload length (1/2/4/8) + Packet number (1/2/4 bytes) + Payload.
3723 * (absolute minimum: 9 + payload)
3724 * (for Version Negotiation, payload len + PKN + payload is replaced by
3725 * Supported Version (multiple of 4 bytes.)
3726 */
3727 conversation_t *conversation = NULL;
3728 int offset = 0;
3729 guint8 flags, dcid, scid;
3730 guint32 version;
3731 gboolean is_quic = FALSE;
3732
3733 /* Verify packet size (Flag (1 byte) + Connection ID (8 bytes) + Version (4 bytes)) */
3734 if (tvb_captured_length(tvb) < 13)
3735 {
3736 return FALSE;
3737 }
3738
3739 flags = tvb_get_guint8(tvb, offset);
3740 /* Check if long Packet is set */
3741 if((flags & 0x80) == 0) {
3742 // Perhaps this is a short header, check it.
3743 return dissect_quic_short_header_heur(tvb, pinfo, tree);
3744 }
3745 offset += 1;
3746
3747 // check for draft QUIC version (for draft -11 and newer)
3748 version = tvb_get_ntohl(tvb, offset);
3749 is_quic = (quic_draft_version(version) >= 11);
3750 if (!is_quic) {
3751 return FALSE;
3752 }
3753
3754 /* Version check on packet forcing version negotiation is quite weak:
3755 try hardenig it checking packets type, too */
3756 if ((version & 0x0F0F0F0F) == 0x0a0a0a0a &&
3757 (flags & 0x30) != 0x00) { /* Initial Packet */
3758 return FALSE;
3759 }
3760
3761 /* Check that CIDs lengths are valid */
3762 offset += 4;
3763 dcid = tvb_get_guint8(tvb, offset);
3764 if (dcid > QUIC_MAX_CID_LENGTH) {
3765 return FALSE;
3766 }
3767 offset += 1 + dcid;
3768 if (offset >= (int)tvb_captured_length(tvb)) {
3769 return FALSE;
3770 }
3771 scid = tvb_get_guint8(tvb, offset);
3772 if (scid > QUIC_MAX_CID_LENGTH) {
3773 return FALSE;
3774 }
3775
3776 /* Ok! */
3777 conversation = find_or_create_conversation(pinfo);
3778 conversation_set_dissector(conversation, quic_handle);
3779 dissect_quic(tvb, pinfo, tree, data);
3780
3781 return TRUE;
3782 }
3783
3784
3785 /** Initialize QUIC dissection state for a new capture file. */
3786 static void
quic_init(void)3787 quic_init(void)
3788 {
3789 quic_connections = wmem_list_new(wmem_file_scope());
3790 quic_connections_count = 0;
3791 quic_initial_connections = wmem_map_new(wmem_file_scope(), quic_connection_hash, quic_connection_equal);
3792 quic_client_connections = wmem_map_new(wmem_file_scope(), quic_connection_hash, quic_connection_equal);
3793 quic_server_connections = wmem_map_new(wmem_file_scope(), quic_connection_hash, quic_connection_equal);
3794 quic_cid_lengths = 0;
3795 }
3796
3797 /** Release QUIC dissection state on closing a capture file. */
3798 static void
quic_cleanup(void)3799 quic_cleanup(void)
3800 {
3801 wmem_list_foreach(quic_connections, quic_connection_destroy, NULL);
3802 quic_initial_connections = NULL;
3803 quic_client_connections = NULL;
3804 quic_server_connections = NULL;
3805 }
3806
3807 /* Follow QUIC Stream functionality {{{ */
3808 #ifdef HAVE_LIBGCRYPT_AEAD
3809 static void
quic_streams_add(packet_info * pinfo,quic_info_data_t * quic_info,guint64 stream_id)3810 quic_streams_add(packet_info *pinfo, quic_info_data_t *quic_info, guint64 stream_id)
3811 {
3812 /* List: ordered list of Stream IDs in this connection */
3813 if (!quic_info->streams_list) {
3814 quic_info->streams_list = wmem_list_new(wmem_file_scope());
3815 }
3816 if (!wmem_list_find(quic_info->streams_list, GUINT_TO_POINTER(stream_id))) {
3817 wmem_list_insert_sorted(quic_info->streams_list, GUINT_TO_POINTER(stream_id),
3818 uint_compare);
3819 }
3820
3821 /* Map: first Stream ID for each UDP payload */
3822 quic_follow_stream *stream;
3823 if (!quic_info->streams_map) {
3824 quic_info->streams_map = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
3825 }
3826 stream = wmem_map_lookup(quic_info->streams_map, GUINT_TO_POINTER(pinfo->num));
3827 if (!stream) {
3828 stream = wmem_new0(wmem_file_scope(), quic_follow_stream);
3829 stream->num = pinfo->num;
3830 stream->stream_id = stream_id;
3831 wmem_map_insert(quic_info->streams_map, GUINT_TO_POINTER(stream->num), stream);
3832 }
3833 }
3834 #endif
3835
3836 static quic_info_data_t *
get_conn_by_number(guint conn_number)3837 get_conn_by_number(guint conn_number)
3838 {
3839 quic_info_data_t *conn;
3840 wmem_list_frame_t *elem;
3841
3842 elem = wmem_list_head(quic_connections);
3843 while (elem) {
3844 conn = (quic_info_data_t *)wmem_list_frame_data(elem);
3845 if (conn->number == conn_number)
3846 return conn;
3847 elem = wmem_list_frame_next(elem);
3848 }
3849 return NULL;
3850 }
3851
3852 gboolean
quic_get_stream_id_le(guint streamid,guint sub_stream_id,guint * sub_stream_id_out)3853 quic_get_stream_id_le(guint streamid, guint sub_stream_id, guint *sub_stream_id_out)
3854 {
3855 quic_info_data_t *quic_info;
3856 wmem_list_frame_t *curr_entry;
3857 guint prev_stream_id;
3858
3859 quic_info = get_conn_by_number(streamid);
3860 if (!quic_info) {
3861 return FALSE;
3862 }
3863 if (!quic_info->streams_list) {
3864 return FALSE;
3865 }
3866
3867 prev_stream_id = G_MAXUINT32;
3868 curr_entry = wmem_list_head(quic_info->streams_list);
3869 while (curr_entry) {
3870 if (GPOINTER_TO_UINT(wmem_list_frame_data(curr_entry)) > sub_stream_id &&
3871 prev_stream_id != G_MAXUINT32) {
3872 *sub_stream_id_out = (guint)prev_stream_id;
3873 return TRUE;
3874 }
3875 prev_stream_id = GPOINTER_TO_UINT(wmem_list_frame_data(curr_entry));
3876 curr_entry = wmem_list_frame_next(curr_entry);
3877 }
3878
3879 if (prev_stream_id != G_MAXUINT32) {
3880 *sub_stream_id_out = prev_stream_id;
3881 return TRUE;
3882 }
3883
3884 return FALSE;
3885 }
3886
3887 gboolean
quic_get_stream_id_ge(guint streamid,guint sub_stream_id,guint * sub_stream_id_out)3888 quic_get_stream_id_ge(guint streamid, guint sub_stream_id, guint *sub_stream_id_out)
3889 {
3890 quic_info_data_t *quic_info;
3891 wmem_list_frame_t *curr_entry;
3892
3893 quic_info = get_conn_by_number(streamid);
3894 if (!quic_info) {
3895 return FALSE;
3896 }
3897 if (!quic_info->streams_list) {
3898 return FALSE;
3899 }
3900
3901 curr_entry = wmem_list_head(quic_info->streams_list);
3902 while (curr_entry) {
3903 if (GPOINTER_TO_UINT(wmem_list_frame_data(curr_entry)) >= sub_stream_id) {
3904 /* StreamIDs are 64 bits long in QUIC, but "Follow Stream" generic code uses guint variables */
3905 *sub_stream_id_out = GPOINTER_TO_UINT(wmem_list_frame_data(curr_entry));
3906 return TRUE;
3907 }
3908 curr_entry = wmem_list_frame_next(curr_entry);
3909 }
3910
3911 return FALSE;
3912 }
3913
3914 static gchar *
quic_follow_conv_filter(epan_dissect_t * edt _U_,packet_info * pinfo,guint * stream,guint * sub_stream)3915 quic_follow_conv_filter(epan_dissect_t *edt _U_, packet_info *pinfo, guint *stream, guint *sub_stream)
3916 {
3917 if (((pinfo->net_src.type == AT_IPv4 && pinfo->net_dst.type == AT_IPv4) ||
3918 (pinfo->net_src.type == AT_IPv6 && pinfo->net_dst.type == AT_IPv6))) {
3919 gboolean from_server;
3920 quic_info_data_t *conn = quic_connection_find_dcid(pinfo, NULL, &from_server);
3921 if (!conn) {
3922 return NULL;
3923 }
3924
3925 /* First Stream ID in the selected packet */
3926 quic_follow_stream *s;
3927 if (conn->streams_map) {
3928 s = wmem_map_lookup(conn->streams_map, GUINT_TO_POINTER(pinfo->num));
3929 if (s) {
3930 *stream = conn->number;
3931 *sub_stream = (guint)s->stream_id;
3932 return g_strdup_printf("quic.connection.number eq %u and quic.stream.stream_id eq %u", conn->number, *sub_stream);
3933 }
3934 }
3935 }
3936
3937 return NULL;
3938 }
3939
3940 static gchar *
quic_follow_index_filter(guint stream,guint sub_stream)3941 quic_follow_index_filter(guint stream, guint sub_stream)
3942 {
3943 return g_strdup_printf("quic.connection.number eq %u and quic.stream.stream_id eq %u", stream, sub_stream);
3944 }
3945
3946 static gchar *
quic_follow_address_filter(address * src_addr _U_,address * dst_addr _U_,int src_port _U_,int dst_port _U_)3947 quic_follow_address_filter(address *src_addr _U_, address *dst_addr _U_, int src_port _U_, int dst_port _U_)
3948 {
3949 // This appears to be solely used for tshark. Let's not support matching by
3950 // IP addresses and UDP ports for now since that fails after connection
3951 // migration. If necessary, use udp_follow_address_filter.
3952 return NULL;
3953 }
3954
3955 static tap_packet_status
follow_quic_tap_listener(void * tapdata,packet_info * pinfo,epan_dissect_t * edt _U_,const void * data)3956 follow_quic_tap_listener(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *data)
3957 {
3958 follow_info_t *follow_info = (follow_info_t *)tapdata;
3959 const quic_follow_tap_data_t *follow_data = (const quic_follow_tap_data_t *)data;
3960
3961 if (follow_info->substream_id != SUBSTREAM_UNUSED &&
3962 follow_info->substream_id != follow_data->stream_id) {
3963 return TAP_PACKET_DONT_REDRAW;
3964 }
3965
3966 return follow_tvb_tap_listener(tapdata, pinfo, NULL, follow_data->tvb);
3967 }
3968
get_quic_connections_count(void)3969 guint32 get_quic_connections_count(void)
3970 {
3971 return quic_connections_count;
3972 }
3973 /* Follow QUIC Stream functionality }}} */
3974
3975 void
proto_register_quic(void)3976 proto_register_quic(void)
3977 {
3978 expert_module_t *expert_quic;
3979
3980 static hf_register_info hf[] = {
3981 { &hf_quic_connection_number,
3982 { "Connection Number", "quic.connection.number",
3983 FT_UINT32, BASE_DEC, NULL, 0x0,
3984 "Connection identifier within this capture file", HFILL }
3985 },
3986
3987 { &hf_quic_packet_length,
3988 { "Packet Length", "quic.packet_length",
3989 FT_UINT32, BASE_DEC, NULL, 0x0,
3990 "Size of the QUIC packet", HFILL }
3991 },
3992
3993 { &hf_quic_header_form,
3994 { "Header Form", "quic.header_form",
3995 FT_UINT8, BASE_DEC, VALS(quic_short_long_header_vals), 0x80,
3996 "The most significant bit (0x80) of the first octet is set to 1 for long headers and 0 for short headers.", HFILL }
3997 },
3998
3999 { &hf_quic_long_packet_type,
4000 { "Packet Type", "quic.long.packet_type",
4001 FT_UINT8, BASE_DEC, VALS(quic_long_packet_type_vals), 0x30,
4002 "Long Header Packet Type", HFILL }
4003 },
4004 { &hf_quic_long_reserved,
4005 { "Reserved", "quic.long.reserved",
4006 FT_UINT8, BASE_DEC, NULL, 0x0c,
4007 "Reserved bits (protected using header protection)", HFILL }
4008 },
4009 { &hf_quic_packet_number_length,
4010 { "Packet Number Length", "quic.packet_number_length",
4011 FT_UINT8, BASE_DEC, VALS(quic_packet_number_lengths), 0x03,
4012 "Packet Number field length (protected using header protection)", HFILL }
4013 },
4014 { &hf_quic_dcid,
4015 { "Destination Connection ID", "quic.dcid",
4016 FT_BYTES, BASE_NONE, NULL, 0x0,
4017 NULL, HFILL }
4018 },
4019 { &hf_quic_scid,
4020 { "Source Connection ID", "quic.scid",
4021 FT_BYTES, BASE_NONE, NULL, 0x0,
4022 NULL, HFILL }
4023 },
4024 { &hf_quic_dcil,
4025 { "Destination Connection ID Length", "quic.dcil",
4026 FT_UINT8, BASE_DEC, NULL, 0x0,
4027 NULL, HFILL }
4028 },
4029 { &hf_quic_scil,
4030 { "Source Connection ID Length", "quic.scil",
4031 FT_UINT8, BASE_DEC, NULL, 0x0,
4032 NULL, HFILL }
4033 },
4034 { &hf_quic_token_length,
4035 { "Token Length", "quic.token_length",
4036 FT_UINT64, BASE_DEC, NULL, 0x0,
4037 NULL, HFILL }
4038 },
4039 { &hf_quic_token,
4040 { "Token", "quic.token",
4041 FT_BYTES, BASE_NONE, NULL, 0x0,
4042 NULL, HFILL }
4043 },
4044 { &hf_quic_length,
4045 { "Length", "quic.length",
4046 FT_UINT64, BASE_DEC, NULL, 0x0,
4047 "Length of Packet Number and Payload fields", HFILL }
4048 },
4049
4050 { &hf_quic_packet_number,
4051 { "Packet Number", "quic.packet_number",
4052 FT_UINT64, BASE_DEC, NULL, 0x0,
4053 "Decoded packet number", HFILL }
4054 },
4055 { &hf_quic_version,
4056 { "Version", "quic.version",
4057 FT_UINT32, BASE_RANGE_STRING | BASE_HEX, RVALS(quic_version_vals), 0x0,
4058 NULL, HFILL }
4059 },
4060 { &hf_quic_supported_version,
4061 { "Supported Version", "quic.supported_version",
4062 FT_UINT32, BASE_RANGE_STRING | BASE_HEX, RVALS(quic_version_vals), 0x0,
4063 NULL, HFILL }
4064 },
4065 { &hf_quic_vn_unused,
4066 { "Unused", "quic.vn.unused",
4067 FT_UINT8, BASE_HEX, NULL, 0x7F,
4068 NULL, HFILL }
4069 },
4070 { &hf_quic_short,
4071 { "QUIC Short Header", "quic.short",
4072 FT_NONE, BASE_NONE, NULL, 0x0,
4073 NULL, HFILL }
4074 },
4075 { &hf_quic_fixed_bit,
4076 { "Fixed Bit", "quic.fixed_bit",
4077 FT_BOOLEAN, 8, NULL, 0x40,
4078 "Must be 1", HFILL }
4079 },
4080 { &hf_quic_spin_bit,
4081 { "Spin Bit", "quic.spin_bit",
4082 FT_BOOLEAN, 8, NULL, 0x20,
4083 "Latency Spin Bit", HFILL }
4084 },
4085 { &hf_quic_mp_add_address_first_byte,
4086 { "Config", "quic.mp_first_byte",
4087 FT_UINT8, BASE_HEX, NULL, 0,
4088 NULL, HFILL }
4089 },
4090 { &hf_quic_mp_add_address_reserved,
4091 { "Reserved", "quic.mp_reserved_bit",
4092 FT_UINT8, BASE_DEC, NULL, 0xE0,
4093 NULL, HFILL }
4094 },
4095 { &hf_quic_mp_add_address_port_present,
4096 { "Port presence", "quic.port_presence_bit",
4097 FT_BOOLEAN, 8, NULL, 0x10,
4098 "Must be 1", HFILL }
4099 },
4100 { &hf_quic_mp_add_address_ip_version,
4101 { "IP Version", "quic.ip_version",
4102 FT_UINT8, BASE_DEC, NULL, 0x0f,
4103 NULL, HFILL }
4104 },
4105 { &hf_quic_mp_add_address_id,
4106 { "Address ID", "quic.mp_address_id",
4107 FT_UINT64, BASE_DEC, NULL, 0x0,
4108 NULL, HFILL }
4109 },
4110 { &hf_quic_mp_add_address_sq_number,
4111 { "Sequence Number", "quic.mp_sequence_number",
4112 FT_UINT64, BASE_DEC, NULL, 0x0,
4113 NULL, HFILL }
4114 },
4115 { &hf_quic_mp_add_address_interface_type,
4116 { "Interface Type", "quic.mp_interface_type",
4117 FT_UINT64, BASE_DEC, NULL, 0x0,
4118 NULL, HFILL }
4119 },
4120 { &hf_quic_mp_add_address_ip_address,
4121 { "IP Address", "quic.mp_ip_address",
4122 FT_IPv4, BASE_NONE,
4123 NULL, 0x0, NULL, HFILL }
4124 },
4125 { &hf_quic_mp_add_address_ip_address_v6,
4126 { "IP Address", "quic.mp_ip_address_v6",
4127 FT_IPv6, BASE_NONE,
4128 NULL, 0x0, NULL, HFILL }
4129 },
4130 { &hf_quic_mp_add_address_port,
4131 { "Port", "quic.mp_port",
4132 FT_UINT32, BASE_DEC, NULL, 0x0,
4133 NULL, HFILL }
4134 },
4135 { &hf_quic_mp_uniflow_id,
4136 { "Uniflow ID", "quic.mp_uniflow_id",
4137 FT_UINT64, BASE_DEC, NULL, 0x0,
4138 NULL, HFILL }
4139 },
4140 { &hf_quic_mp_receiving_uniflows,
4141 { "Receiving uniflows", "quic.mp_receiving_uniflows",
4142 FT_UINT64, BASE_DEC, NULL, 0x0,
4143 NULL, HFILL }
4144 },
4145 { &hf_quic_mp_active_sending_uniflows,
4146 { "Active sending uniflows", "quic.mp_act_send_uf",
4147 FT_UINT64, BASE_DEC, NULL, 0x0,
4148 NULL, HFILL }
4149 },
4150 { &hf_quic_mp_receiving_uniflow_info_section,
4151 { "Receiving uniflows", "quic.mp_receiving_uniflows_section",
4152 FT_NONE, BASE_NONE, NULL, 0x0,
4153 NULL, HFILL }
4154 },
4155 { &hf_quic_mp_active_sending_uniflows_info_section,
4156 { "Active sending uniflows", "quic.mp_act_send_uf_section",
4157 FT_NONE, BASE_NONE, NULL, 0x0,
4158 NULL, HFILL }
4159 },
4160 { &hf_quic_mp_uniflow_info_section,
4161 { "Uniflow Info Section", "quic.mp_uniflow_info_section",
4162 FT_NONE, BASE_NONE, NULL, 0x0,
4163 NULL, HFILL }
4164 },
4165 { &hf_quic_mp_add_local_address_id ,
4166 { "Local address id", "quic.mp_add_local_address_id",
4167 FT_UINT64, BASE_DEC, NULL, 0x0,
4168 NULL, HFILL }
4169 },
4170 { &hf_quic_short_reserved,
4171 { "Reserved", "quic.short.reserved",
4172 FT_UINT8, BASE_DEC, NULL, 0x18,
4173 "Reserved bits (protected using header protection)", HFILL }
4174 },
4175 { &hf_quic_q_bit,
4176 { "Square Signal Bit (Q)", "quic.q_bit",
4177 FT_BOOLEAN, 8, NULL, 0x10,
4178 "Square Signal Bit (used to measure and locate the source of packet loss)", HFILL }
4179 },
4180 { &hf_quic_l_bit,
4181 { "Loss Event Bit (L)", "quic.l_bit",
4182 FT_BOOLEAN, 8, NULL, 0x08,
4183 "Loss Event Bit (used to measure and locate the source of packet loss)", HFILL }
4184 },
4185 { &hf_quic_key_phase,
4186 { "Key Phase Bit", "quic.key_phase",
4187 FT_BOOLEAN, 8, NULL, SH_KP,
4188 "Selects the packet protection keys to use (protected using header protection)", HFILL }
4189 },
4190
4191 { &hf_quic_payload,
4192 { "Payload", "quic.payload",
4193 FT_BYTES, BASE_NONE, NULL, 0x0,
4194 "(Encrypted) payload of a packet", HFILL }
4195 },
4196 { &hf_quic_protected_payload,
4197 { "Protected Payload", "quic.protected_payload",
4198 FT_BYTES, BASE_NONE, NULL, 0x0,
4199 "1-RTT protected payload", HFILL }
4200 },
4201 { &hf_quic_remaining_payload,
4202 { "Remaining Payload", "quic.remaining_payload",
4203 FT_BYTES, BASE_NONE, NULL, 0x0,
4204 "Remaining payload in a packet (possibly PKN followed by encrypted payload)", HFILL }
4205 },
4206
4207 { &hf_quic_odcil,
4208 { "Original Destination Connection ID Length", "quic.odcil",
4209 FT_UINT8, BASE_DEC, NULL, 0x0,
4210 NULL, HFILL }
4211 },
4212 { &hf_quic_odcid,
4213 { "Original Destination Connection ID", "quic.odcid",
4214 FT_BYTES, BASE_NONE, NULL, 0x0,
4215 NULL, HFILL }
4216 },
4217 { &hf_quic_retry_token,
4218 { "Retry Token", "quic.retry_token",
4219 FT_BYTES, BASE_NONE, NULL, 0x0,
4220 NULL, HFILL }
4221 },
4222 { &hf_quic_retry_integrity_tag,
4223 { "Retry Integrity Tag", "quic.retry_integrity_tag",
4224 FT_BYTES, BASE_NONE, NULL, 0x0,
4225 NULL, HFILL }
4226 },
4227
4228 { &hf_quic_frame,
4229 { "Frame", "quic.frame",
4230 FT_NONE, BASE_NONE, NULL, 0x0,
4231 NULL, HFILL }
4232 },
4233 { &hf_quic_frame_type,
4234 { "Frame Type", "quic.frame_type",
4235 FT_UINT64, BASE_RANGE_STRING | BASE_HEX, RVALS(quic_frame_type_vals), 0x0,
4236 NULL, HFILL }
4237 },
4238
4239 /* PADDING */
4240 { &hf_quic_padding_length,
4241 { "Padding Length", "quic.padding_length",
4242 FT_UINT32, BASE_DEC, NULL, 0x0,
4243 NULL, HFILL }
4244 },
4245 /* ACK */
4246 { &hf_quic_ack_largest_acknowledged,
4247 { "Largest Acknowledged", "quic.ack.largest_acknowledged",
4248 FT_UINT64, BASE_DEC, NULL, 0x0,
4249 "Largest packet number the peer is acknowledging in this packet", HFILL }
4250 },
4251 { &hf_quic_ack_ack_delay,
4252 { "ACK Delay", "quic.ack.ack_delay",
4253 FT_UINT64, BASE_DEC, NULL, 0x0,
4254 "Time from when the largest acknowledged packet, as indicated in the Largest Acknowledged field, was received by this peer to when this ACK was sent", HFILL }
4255 },
4256 { &hf_quic_ack_ack_range_count,
4257 { "ACK Range Count", "quic.ack.ack_range_count",
4258 FT_UINT64, BASE_DEC, NULL, 0x0,
4259 "Number of Gap and ACK Range fields in the frame", HFILL }
4260 },
4261 { &hf_quic_ack_first_ack_range,
4262 { "First ACK Range", "quic.ack.first_ack_range",
4263 FT_UINT64, BASE_DEC, NULL, 0x0,
4264 "Number of contiguous packets preceding the Largest Acknowledged that are being acknowledged", HFILL }
4265 },
4266 { &hf_quic_ack_gap,
4267 { "Gap", "quic.ack.gap",
4268 FT_UINT64, BASE_DEC, NULL, 0x0,
4269 "Number of contiguous unacknowledged packets preceding the packet number one lower than the smallest in the preceding ACK Range", HFILL }
4270 },
4271 { &hf_quic_ack_ack_range,
4272 { "ACK Range", "quic.ack.ack_range",
4273 FT_UINT64, BASE_DEC, NULL, 0x0,
4274 "Number of contiguous acknowledged packets preceding the largest packet number, as determined by the preceding Gap", HFILL }
4275 },
4276 { &hf_quic_ack_ect0_count,
4277 { "ECT(0) Count", "quic.ack.ect0_count",
4278 FT_UINT64, BASE_DEC, NULL, 0x0,
4279 "Total number of packets received with the ECT(0) codepoint", HFILL }
4280 },
4281 { &hf_quic_ack_ect1_count,
4282 { "ECT(1) Count", "quic.ack.ect1_count",
4283 FT_UINT64, BASE_DEC, NULL, 0x0,
4284 "Total number of packets received with the ECT(1) codepoint", HFILL }
4285 },
4286 { &hf_quic_ack_ecn_ce_count,
4287 { "ECN-CE Count", "quic.ack.ecn_ce_count",
4288 FT_UINT64, BASE_DEC, NULL, 0x0,
4289 "Total number of packets received with the CE codepoint", HFILL }
4290 },
4291 /* RESET_STREAM */
4292 { &hf_quic_rsts_stream_id,
4293 { "Stream ID", "quic.rsts.stream_id",
4294 FT_UINT64, BASE_DEC, NULL, 0x0,
4295 "Stream ID of the stream being terminated", HFILL }
4296 },
4297 { &hf_quic_rsts_application_error_code,
4298 { "Application Error code", "quic.rsts.application_error_code",
4299 FT_UINT64, BASE_DEC, NULL, 0x0,
4300 "Indicates why the stream is being closed", HFILL }
4301 },
4302 { &hf_quic_rsts_final_size,
4303 { "Final Size", "quic.rsts.final_size",
4304 FT_UINT64, BASE_DEC, NULL, 0x0,
4305 "The final size of the stream by the RESET_STREAM sender (in bytes)", HFILL }
4306 },
4307 /* STOP_SENDING */
4308 { &hf_quic_ss_stream_id,
4309 { "Stream ID", "quic.ss.stream_id",
4310 FT_UINT64, BASE_DEC, NULL, 0x0,
4311 "Stream ID of the stream being ignored", HFILL }
4312 },
4313 { &hf_quic_ss_application_error_code,
4314 { "Application Error code", "quic.ss.application_error_code",
4315 FT_UINT64, BASE_DEC, NULL, 0x0,
4316 "Indicates why the sender is ignoring the stream", HFILL }
4317 },
4318 /* CRYPTO */
4319 { &hf_quic_crypto_offset,
4320 { "Offset", "quic.crypto.offset",
4321 FT_UINT64, BASE_DEC, NULL, 0x0,
4322 "Byte offset into the stream", HFILL }
4323 },
4324 { &hf_quic_crypto_length,
4325 { "Length", "quic.crypto.length",
4326 FT_UINT64, BASE_DEC, NULL, 0x0,
4327 "Length of the Crypto Data field", HFILL }
4328 },
4329 { &hf_quic_crypto_crypto_data,
4330 { "Crypto Data", "quic.crypto.crypto_data",
4331 FT_NONE, BASE_NONE, NULL, 0x0,
4332 "The cryptographic message data", HFILL }
4333 },
4334 /* NEW_TOKEN */
4335 { &hf_quic_nt_length,
4336 { "(Token) Length", "quic.nt.length",
4337 FT_UINT64, BASE_DEC, NULL, 0x0,
4338 "Specifying the length of the token", HFILL }
4339 },
4340 { &hf_quic_nt_token,
4341 { "Token", "quic.nt.token",
4342 FT_BYTES, BASE_NONE, NULL, 0x0,
4343 "An opaque blob that the client may use with a future Initial packet", HFILL }
4344 },
4345 /* STREAM */
4346 { &hf_quic_stream_fin,
4347 { "Fin", "quic.stream.fin",
4348 FT_BOOLEAN, 8, NULL, FTFLAGS_STREAM_FIN,
4349 NULL, HFILL }
4350 },
4351 { &hf_quic_stream_len,
4352 { "Len(gth)", "quic.stream.len",
4353 FT_BOOLEAN, 8, NULL, FTFLAGS_STREAM_LEN,
4354 NULL, HFILL }
4355 },
4356 { &hf_quic_stream_off,
4357 { "Off(set)", "quic.stream.off",
4358 FT_BOOLEAN, 8, NULL, FTFLAGS_STREAM_OFF,
4359 NULL, HFILL }
4360 },
4361 { &hf_quic_stream_stream_id,
4362 { "Stream ID", "quic.stream.stream_id",
4363 FT_UINT64, BASE_DEC, NULL, 0x0,
4364 NULL, HFILL }
4365 },
4366 { &hf_quic_stream_initiator,
4367 { "Stream initiator", "quic.stream.initiator",
4368 FT_UINT64, BASE_DEC | BASE_VAL64_STRING, VALS64(quic_frame_id_initiator), FTFLAGS_STREAM_INITIATOR,
4369 NULL, HFILL }
4370 },
4371 { &hf_quic_stream_direction,
4372 { "Stream direction", "quic.stream.direction",
4373 FT_UINT64, BASE_DEC | BASE_VAL64_STRING, VALS64(quic_frame_id_direction), FTFLAGS_STREAM_DIRECTION,
4374 NULL, HFILL }
4375 },
4376 { &hf_quic_stream_offset,
4377 { "Offset", "quic.stream.offset",
4378 FT_UINT64, BASE_DEC, NULL, 0x0,
4379 NULL, HFILL }
4380 },
4381 { &hf_quic_stream_length,
4382 { "Length", "quic.stream.length",
4383 FT_UINT64, BASE_DEC, NULL, 0x0,
4384 NULL, HFILL }
4385 },
4386 { &hf_quic_stream_data,
4387 { "Stream Data", "quic.stream_data",
4388 FT_BYTES, BASE_NONE, NULL, 0x0,
4389 NULL, HFILL }
4390 },
4391
4392 /* MAX_DATA */
4393 { &hf_quic_md_maximum_data,
4394 { "Maximum Data", "quic.md.maximum_data",
4395 FT_UINT64, BASE_DEC, NULL, 0x0,
4396 "Indicating the maximum amount of data that can be sent on the entire connection, in units of 1024 octets", HFILL }
4397 },
4398 /* MAX_STREAM_DATA */
4399 { &hf_quic_msd_stream_id,
4400 { "Stream ID", "quic.msd.stream_id",
4401 FT_UINT64, BASE_DEC, NULL, 0x0,
4402 "The stream ID of the stream that is affected", HFILL }
4403 },
4404 { &hf_quic_msd_maximum_stream_data,
4405 { "Maximum Stream Data", "quic.msd.maximum_stream_data",
4406 FT_UINT64, BASE_DEC, NULL, 0x0,
4407 "Indicating the maximum amount of data that can be sent on the identified stream, in units of octets", HFILL }
4408 },
4409 /* MAX_STREAMS */
4410 { &hf_quic_ms_max_streams,
4411 { "Max Streams", "quic.ms.max_streams",
4412 FT_UINT64, BASE_DEC, NULL, 0x0,
4413 "A count of the cumulative number of streams of the corresponding type that can be opened over the lifetime of the connection", HFILL }
4414 },
4415 /* DATA_BLOCKED */
4416 { &hf_quic_db_stream_data_limit,
4417 { "Stream Data Limit", "quic.sb.stream_data_limit",
4418 FT_UINT64, BASE_DEC, NULL, 0x0,
4419 "Indicating the connection-level limit at which the blocking occurred", HFILL }
4420 },
4421 /* STREAM_DATA_BLOCKED */
4422 { &hf_quic_sdb_stream_id,
4423 { "Stream ID", "quic.sdb.stream_id",
4424 FT_UINT64, BASE_DEC, NULL, 0x0,
4425 "Indicating the stream which is flow control blocked", HFILL }
4426 },
4427 { &hf_quic_sdb_stream_data_limit,
4428 { "Stream Data Limit", "quic.sb.stream_data_limit",
4429 FT_UINT64, BASE_DEC, NULL, 0x0,
4430 "Indicating the offset of the stream at which the blocking occurred", HFILL }
4431 },
4432 /* STREAMS_BLOCKED */
4433 { &hf_quic_sb_stream_limit,
4434 { "Stream Limit", "quic.sib.stream_limit",
4435 FT_UINT64, BASE_DEC, NULL, 0x0,
4436 "Indicating the stream limit at the time the frame was sent", HFILL }
4437 },
4438 /* NEW_CONNECTION_ID */
4439 { &hf_quic_nci_retire_prior_to,
4440 { "Retire Prior To", "quic.nci.retire_prior_to",
4441 FT_UINT64, BASE_DEC, NULL, 0x0,
4442 "A variable-length integer indicating which connection IDs should be retired", HFILL }
4443 },
4444 { &hf_quic_nci_sequence,
4445 { "Sequence", "quic.nci.sequence",
4446 FT_UINT64, BASE_DEC, NULL, 0x0,
4447 "Increases by 1 for each connection ID that is provided by the server", HFILL }
4448 },
4449 { &hf_quic_nci_connection_id_length,
4450 { "Connection ID Length", "quic.nci.connection_id.length",
4451 FT_UINT8, BASE_DEC, NULL, 0x0,
4452 NULL, HFILL }
4453 },
4454 { &hf_quic_nci_connection_id,
4455 { "Connection ID", "quic.nci.connection_id",
4456 FT_BYTES, BASE_NONE, NULL, 0x0,
4457 NULL, HFILL }
4458 },
4459 { &hf_quic_nci_stateless_reset_token,
4460 { "Stateless Reset Token", "quic.stateless_reset_token",
4461 FT_BYTES, BASE_NONE, NULL, 0x0,
4462 NULL, HFILL }
4463 },
4464 /* RETIRE_CONNECTION_ID */
4465 { &hf_quic_rci_sequence,
4466 { "Sequence", "quic.rci.sequence",
4467 FT_UINT64, BASE_DEC, NULL, 0x0,
4468 "The sequence number of the connection ID being retired", HFILL }
4469 },
4470 /* PATH_CHALLENGE */
4471 { &hf_quic_path_challenge_data,
4472 { "Data", "quic.path_challenge.data",
4473 FT_BYTES, BASE_NONE, NULL, 0x0,
4474 "Arbitrary data that must be matched by a PATH_RESPONSE frame", HFILL }
4475 },
4476 /* PATH_RESPONSE */
4477 { &hf_quic_path_response_data,
4478 { "Data", "quic.path_response.data",
4479 FT_BYTES, BASE_NONE, NULL, 0x0,
4480 "Arbitrary data that must match a PATH_CHALLENGE frame", HFILL }
4481 },
4482 /* CONNECTION_CLOSE */
4483 { &hf_quic_cc_error_code,
4484 { "Error code", "quic.cc.error_code",
4485 FT_UINT64, BASE_DEC|BASE_RANGE_STRING, RVALS(quic_transport_error_code_vals), 0x0,
4486 "Indicates the reason for closing this connection", HFILL }
4487 },
4488 { &hf_quic_cc_error_code_app,
4489 { "Application Error code", "quic.cc.error_code.app",
4490 FT_UINT64, BASE_DEC, NULL, 0x0,
4491 "Indicates the reason for closing this application", HFILL }
4492 },
4493 { &hf_quic_cc_error_code_tls_alert,
4494 { "TLS Alert Description", "quic.cc.error_code.tls_alert",
4495 FT_UINT8, BASE_DEC, VALS(ssl_31_alert_description), 0x0,
4496 NULL, HFILL }
4497 },
4498 { &hf_quic_cc_frame_type,
4499 { "Frame Type", "quic.cc.frame_type",
4500 FT_UINT64, BASE_DEC, NULL, 0x0,
4501 "The type of frame that triggered the error", HFILL }
4502 },
4503 { &hf_quic_cc_reason_phrase_length,
4504 { "Reason phrase Length", "quic.cc.reason_phrase.length",
4505 FT_UINT64, BASE_DEC, NULL, 0x0,
4506 "Specifying the length of the reason phrase", HFILL }
4507 },
4508 { &hf_quic_cc_reason_phrase,
4509 { "Reason phrase", "quic.cc.reason_phrase",
4510 FT_STRING, BASE_NONE, NULL, 0x0,
4511 "A human-readable explanation for why the connection was closed", HFILL }
4512 },
4513 /* DATAGRAM */
4514 { &hf_quic_dg_length,
4515 { "Datagram Length", "quic.dg.length",
4516 FT_UINT64, BASE_DEC, NULL, 0x0,
4517 "Specifying the length of the the datagram in bytes", HFILL }
4518 },
4519 { &hf_quic_dg,
4520 { "Datagram", "quic.dg",
4521 FT_BYTES, BASE_NONE, NULL, 0x0,
4522 "The bytes of the datagram to be delivered", HFILL }
4523 },
4524 /* ACK-FREQUENCY */
4525 { &hf_quic_af_sequence_number,
4526 { "Sequence Number", "quic.af.sequence_number",
4527 FT_UINT64, BASE_DEC, NULL, 0x0,
4528 "Sequence number assigned to the ACK-FREQUENCY frame by the sender to allow receivers to ignore obsolete frames", HFILL }
4529 },
4530 { &hf_quic_af_packet_tolerance,
4531 { "Packet Tolerance", "quic.af.packet_tolerance",
4532 FT_UINT64, BASE_DEC, NULL, 0x0,
4533 "Representing the maximum number of ack-eliciting packets after which the receiver sends an acknowledgement", HFILL }
4534 },
4535 { &hf_quic_af_update_max_ack_delay,
4536 { "Update Max Ack Delay", "quic.af.update_max_ack_delay",
4537 FT_UINT64, BASE_DEC, NULL, 0x0,
4538 "Representing an update to the peer's 'max_ack_delay' transport parameter", HFILL }
4539 },
4540 { &hf_quic_ts,
4541 { "Time Stamp", "quic.ts",
4542 FT_UINT64, BASE_DEC, NULL, 0x0,
4543 NULL, HFILL }
4544 },
4545
4546 /* Fields for QUIC Stream data reassembly. */
4547 { &hf_quic_fragment_overlap,
4548 { "Fragment overlap", "quic.fragment.overlap",
4549 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4550 "Fragment overlaps with other fragments", HFILL }
4551 },
4552 { &hf_quic_fragment_overlap_conflict,
4553 { "Conflicting data in fragment overlap", "quic.fragment.overlap.conflict",
4554 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4555 "Overlapping fragments contained conflicting data", HFILL }
4556 },
4557 { &hf_quic_fragment_multiple_tails,
4558 { "Multiple tail fragments found", "quic.fragment.multipletails",
4559 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4560 "Several tails were found when reassembling the pdu", HFILL }
4561 },
4562 { &hf_quic_fragment_too_long_fragment,
4563 { "Fragment too long", "quic.fragment.toolongfragment",
4564 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
4565 "Fragment contained data past end of the pdu", HFILL }
4566 },
4567 { &hf_quic_fragment_error,
4568 { "Reassembling error", "quic.fragment.error",
4569 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4570 "Reassembling error due to illegal fragments", HFILL }
4571 },
4572 { &hf_quic_fragment_count,
4573 { "Fragment count", "quic.fragment.count",
4574 FT_UINT32, BASE_DEC, NULL, 0x0,
4575 NULL, HFILL }
4576 },
4577 { &hf_quic_fragment,
4578 { "QUIC STREAM Data Fragment", "quic.fragment",
4579 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4580 NULL, HFILL }
4581 },
4582 { &hf_quic_fragments,
4583 { "Reassembled QUIC STREAM Data Fragments", "quic.fragments",
4584 FT_NONE, BASE_NONE, NULL, 0x0,
4585 "QUIC STREAM Data Fragments", HFILL }
4586 },
4587 { &hf_quic_reassembled_in,
4588 { "Reassembled PDU in frame", "quic.reassembled_in",
4589 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4590 "The PDU that doesn't end in this fragment is reassembled in this frame", HFILL }
4591 },
4592 { &hf_quic_reassembled_length,
4593 { "Reassembled QUIC STREAM Data length", "quic.reassembled.length",
4594 FT_UINT32, BASE_DEC, NULL, 0x0,
4595 "The total length of the reassembled payload", HFILL }
4596 },
4597 { &hf_quic_reassembled_data,
4598 { "Reassembled QUIC STREAM Data", "quic.reassembled.data",
4599 FT_BYTES, BASE_NONE, NULL, 0x0,
4600 "The reassembled payload", HFILL }
4601 },
4602 };
4603
4604 static gint *ett[] = {
4605 &ett_quic,
4606 &ett_quic_short_header,
4607 &ett_quic_connection_info,
4608 &ett_quic_ft,
4609 &ett_quic_ftflags,
4610 &ett_quic_ftid,
4611 &ett_quic_fragments,
4612 &ett_quic_fragment,
4613 };
4614
4615 static ei_register_info ei[] = {
4616 { &ei_quic_connection_unknown,
4617 { "quic.connection.unknown", PI_PROTOCOL, PI_NOTE,
4618 "Unknown QUIC connection. Missing Initial Packet or migrated connection?", EXPFILL }
4619 },
4620 { &ei_quic_ft_unknown,
4621 { "quic.ft.unknown", PI_UNDECODED, PI_NOTE,
4622 "Unknown Frame Type", EXPFILL }
4623 },
4624 { &ei_quic_decryption_failed,
4625 { "quic.decryption_failed", PI_DECRYPTION, PI_WARN,
4626 "Failed to decrypt handshake", EXPFILL }
4627 },
4628 { &ei_quic_protocol_violation,
4629 { "quic.protocol_violation", PI_PROTOCOL, PI_WARN,
4630 "Invalid data according to the protocol", EXPFILL }
4631 },
4632 { &ei_quic_bad_retry,
4633 { "quic.bad_retry", PI_PROTOCOL, PI_WARN,
4634 "Retry Integrity Tag verification failure", EXPFILL }
4635 },
4636 { &ei_quic_coalesced_padding_data,
4637 { "quic.coalesced_padding_data", PI_PROTOCOL, PI_NOTE,
4638 "Coalesced Padding Data", EXPFILL }
4639 },
4640 };
4641
4642 proto_quic = proto_register_protocol("QUIC IETF", "QUIC", "quic");
4643
4644 proto_register_field_array(proto_quic, hf, array_length(hf));
4645 proto_register_subtree_array(ett, array_length(ett));
4646
4647 expert_quic = expert_register_protocol(proto_quic);
4648 expert_register_field_array(expert_quic, ei, array_length(ei));
4649
4650 quic_handle = register_dissector("quic", dissect_quic, proto_quic);
4651
4652 register_init_routine(quic_init);
4653 register_cleanup_routine(quic_cleanup);
4654
4655 register_follow_stream(proto_quic, "quic_follow", quic_follow_conv_filter, quic_follow_index_filter, quic_follow_address_filter,
4656 udp_port_to_display, follow_quic_tap_listener);
4657
4658 // TODO implement custom reassembly functions that uses the QUIC Connection
4659 // ID instead of address and port numbers.
4660 reassembly_table_register(&quic_reassembly_table,
4661 &addresses_ports_reassembly_table_functions);
4662
4663 /*
4664 * Application protocol. QUIC with TLS uses ALPN.
4665 * https://tools.ietf.org/html/draft-ietf-quic-transport-23#section-7
4666 * This could in theory be an arbitrary octet string with embedded NUL
4667 * bytes, but in practice these do not exist yet.
4668 */
4669 quic_proto_dissector_table = register_dissector_table("quic.proto", "QUIC Protocol", proto_quic, FT_STRING, FALSE);
4670 }
4671
4672 void
proto_reg_handoff_quic(void)4673 proto_reg_handoff_quic(void)
4674 {
4675 tls13_handshake_handle = find_dissector("tls13-handshake");
4676 dissector_add_uint_with_preference("udp.port", 0, quic_handle);
4677 heur_dissector_add("udp", dissect_quic_heur, "QUIC", "quic", proto_quic, HEURISTIC_ENABLE);
4678 quic_follow_tap = register_tap("quic_follow");
4679 }
4680
4681 /*
4682 * Editor modelines - https://www.wireshark.org/tools/modelines.html
4683 *
4684 * Local variables:
4685 * c-basic-offset: 4
4686 * tab-width: 8
4687 * indent-tabs-mode: nil
4688 * End:
4689 *
4690 * vi: set shiftwidth=4 tabstop=8 expandtab:
4691 * :indentSize=4:tabSize=8:noTabs=true:
4692 */
4693