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