diff options
-rw-r--r-- | epan/dissectors/packet-quic.c | 169 |
1 files changed, 91 insertions, 78 deletions
diff --git a/epan/dissectors/packet-quic.c b/epan/dissectors/packet-quic.c index 99ee361ff2..e31cbdf9d8 100644 --- a/epan/dissectors/packet-quic.c +++ b/epan/dissectors/packet-quic.c @@ -794,111 +794,124 @@ quic_create_cleartext_decoders(guint64 cid, const gchar **error, quic_info_data_ } #endif /* HAVE_LIBGCRYPT_AEAD */ - static int -dissect_quic_long_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree, guint offset, quic_info_data_t *quic_info){ - guint32 long_packet_type, pkn; - guint64 cid; - - proto_tree_add_item_ret_uint(quic_tree, hf_quic_long_packet_type, tvb, offset, 1, ENC_NA, &long_packet_type); - offset += 1; +dissect_quic_initial(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree, guint offset, quic_info_data_t *quic_info, guint32 pkn, guint64 cid){ + proto_item *ti; - proto_tree_add_item_ret_uint64(quic_tree, hf_quic_connection_id, tvb, offset, 8, ENC_BIG_ENDIAN, &cid); - offset += 8; + ti = proto_tree_add_item(quic_tree, hf_quic_initial_payload, tvb, offset, -1, ENC_NA); - proto_tree_add_item_ret_uint(quic_tree, hf_quic_version, tvb, offset, 4, ENC_BIG_ENDIAN, &quic_info->version); - offset += 4; + /* Initial Packet is always send by client */ + if(pinfo->destport != 443) { + quic_info->server_port = pinfo->destport; + } - proto_tree_add_item_ret_uint(quic_tree, hf_quic_packet_number, tvb, offset, 4, ENC_BIG_ENDIAN, &pkn); - offset += 4; +#ifdef HAVE_LIBGCRYPT_AEAD + tls13_cipher *cipher = NULL; + const gchar *error = NULL; + tvbuff_t *decrypted_tvb; - col_append_fstr(pinfo->cinfo, COL_INFO, "%s, PKN: %u, CID: 0x%" G_GINT64_MODIFIER "x", val_to_str(long_packet_type, quic_long_packet_type_vals, "Unknown Packet Type"), pkn, cid); + cipher = quic_info->client_cleartext_cipher; - /* Payload */ - if (long_packet_type == QUIC_LPT_INITIAL) { - proto_item *ti; + /* Create new decryption context based on the Client Connection + * ID from the Client Initial packet. */ + if (!quic_create_cleartext_decoders(cid, &error, quic_info)) { + expert_add_info_format(pinfo, ti, &ei_quic_decryption_failed, "Failed to create decryption context: %s", error); + return offset; + } - ti = proto_tree_add_item(quic_tree, hf_quic_initial_payload, tvb, offset, -1, ENC_NA); + if (cipher) { + /* quic_decrypt_message expects exactly one header + ciphertext as tvb. */ + DISSECTOR_ASSERT(offset == QUIC_LONG_HEADER_LENGTH); - /* Initial Packet is always send by client */ - if(pinfo->destport != 443) { - quic_info->server_port = pinfo->destport; + decrypted_tvb = quic_decrypt_message(cipher, tvb, pinfo, QUIC_LONG_HEADER_LENGTH, pkn, &error); + if (decrypted_tvb) { + guint decrypted_offset = 0; + while (tvb_reported_length_remaining(decrypted_tvb, decrypted_offset) > 0){ + decrypted_offset = dissect_quic_frame_type(decrypted_tvb, pinfo, quic_tree, decrypted_offset, quic_info); + } + } else { + expert_add_info_format(pinfo, ti, &ei_quic_decryption_failed, "Failed to decrypt handshake: %s", error); } + } +#else /* !HAVE_LIBGCRYPT_AEAD */ + expert_add_info_format(pinfo, ti, &ei_quic_decryption_failed, "Libgcrypt >= 1.6.0 is required for QUIC decryption"); +#endif /* !HAVE_LIBGCRYPT_AEAD */ + offset += tvb_reported_length_remaining(tvb, offset); + + return offset; +} + +static int +dissect_quic_handshake(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree, guint offset, quic_info_data_t *quic_info, guint32 pkn){ + proto_item *ti; + + ti = proto_tree_add_item(quic_tree, hf_quic_handshake_payload, tvb, offset, -1, ENC_NA); #ifdef HAVE_LIBGCRYPT_AEAD - tls13_cipher *cipher = NULL; - const gchar *error = NULL; - tvbuff_t *decrypted_tvb; + tls13_cipher *cipher = NULL; + const gchar *error = NULL; + tvbuff_t *decrypted_tvb; + if(pinfo->destport == quic_info->server_port) { cipher = quic_info->client_cleartext_cipher; + } else { + cipher = quic_info->server_cleartext_cipher; + } - /* Create new decryption context based on the Client Connection - * ID from the Client Initial packet. */ - if (!quic_create_cleartext_decoders(cid, &error, quic_info)) { - expert_add_info_format(pinfo, ti, &ei_quic_decryption_failed, "Failed to create decryption context: %s", error); - return offset; - } - - if (cipher) { - /* quic_decrypt_message expects exactly one header + ciphertext as tvb. */ - DISSECTOR_ASSERT(offset == QUIC_LONG_HEADER_LENGTH); + if (cipher) { + /* quic_decrypt_message expects exactly one header + ciphertext as tvb. */ + DISSECTOR_ASSERT(offset == QUIC_LONG_HEADER_LENGTH); - decrypted_tvb = quic_decrypt_message(cipher, tvb, pinfo, QUIC_LONG_HEADER_LENGTH, pkn, &error); - if (decrypted_tvb) { - guint decrypted_offset = 0; - while (tvb_reported_length_remaining(decrypted_tvb, decrypted_offset) > 0){ - decrypted_offset = dissect_quic_frame_type(decrypted_tvb, pinfo, quic_tree, decrypted_offset, quic_info); - } - } else { - expert_add_info_format(pinfo, ti, &ei_quic_decryption_failed, "Failed to decrypt handshake: %s", error); + decrypted_tvb = quic_decrypt_message(cipher, tvb, pinfo, QUIC_LONG_HEADER_LENGTH, pkn, &error); + if (decrypted_tvb) { + guint decrypted_offset = 0; + while (tvb_reported_length_remaining(decrypted_tvb, decrypted_offset) > 0){ + decrypted_offset = dissect_quic_frame_type(decrypted_tvb, pinfo, quic_tree, decrypted_offset, quic_info); } + } else { + expert_add_info_format(pinfo, ti, &ei_quic_decryption_failed, "Failed to decrypt handshake: %s", error); } + } #else /* !HAVE_LIBGCRYPT_AEAD */ - expert_add_info_format(pinfo, ti, &ei_quic_decryption_failed, "Libgcrypt >= 1.6.0 is required for QUIC decryption"); + expert_add_info_format(pinfo, ti, &ei_quic_decryption_failed, "Libgcrypt >= 1.6.0 is required for QUIC decryption"); #endif /* !HAVE_LIBGCRYPT_AEAD */ - offset += tvb_reported_length_remaining(tvb, offset); + offset += tvb_reported_length_remaining(tvb, offset); - /* Handshake (>= draft-08) */ - } else if (long_packet_type == QUIC_LPT_HANDSHAKE ) { - proto_item *ti; + return offset; +} - ti = proto_tree_add_item(quic_tree, hf_quic_handshake_payload, tvb, offset, -1, ENC_NA); +static int +dissect_quic_long_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree, guint offset, quic_info_data_t *quic_info){ + guint32 long_packet_type, pkn; + guint64 cid; -#ifdef HAVE_LIBGCRYPT_AEAD - tls13_cipher *cipher = NULL; - const gchar *error = NULL; - tvbuff_t *decrypted_tvb; + proto_tree_add_item_ret_uint(quic_tree, hf_quic_long_packet_type, tvb, offset, 1, ENC_NA, &long_packet_type); + offset += 1; - if(pinfo->destport == quic_info->server_port) { - cipher = quic_info->client_cleartext_cipher; - } else { - cipher = quic_info->server_cleartext_cipher; - } + proto_tree_add_item_ret_uint64(quic_tree, hf_quic_connection_id, tvb, offset, 8, ENC_BIG_ENDIAN, &cid); + offset += 8; - if (cipher) { - /* quic_decrypt_message expects exactly one header + ciphertext as tvb. */ - DISSECTOR_ASSERT(offset == QUIC_LONG_HEADER_LENGTH); + proto_tree_add_item_ret_uint(quic_tree, hf_quic_version, tvb, offset, 4, ENC_BIG_ENDIAN, &quic_info->version); + offset += 4; - decrypted_tvb = quic_decrypt_message(cipher, tvb, pinfo, QUIC_LONG_HEADER_LENGTH, pkn, &error); - if (decrypted_tvb) { - guint decrypted_offset = 0; - while (tvb_reported_length_remaining(decrypted_tvb, decrypted_offset) > 0){ - decrypted_offset = dissect_quic_frame_type(decrypted_tvb, pinfo, quic_tree, decrypted_offset, quic_info); - } - } else { - expert_add_info_format(pinfo, ti, &ei_quic_decryption_failed, "Failed to decrypt handshake: %s", error); - } - } -#else /* !HAVE_LIBGCRYPT_AEAD */ - expert_add_info_format(pinfo, ti, &ei_quic_decryption_failed, "Libgcrypt >= 1.6.0 is required for QUIC decryption"); -#endif /* !HAVE_LIBGCRYPT_AEAD */ - offset += tvb_reported_length_remaining(tvb, offset); + proto_tree_add_item_ret_uint(quic_tree, hf_quic_packet_number, tvb, offset, 4, ENC_BIG_ENDIAN, &pkn); + offset += 4; - } else { - /* Protected (Encrypted) Payload */ - proto_tree_add_item(quic_tree, hf_quic_protected_payload, tvb, offset, -1, ENC_NA); - offset += tvb_reported_length_remaining(tvb, offset); + col_append_fstr(pinfo->cinfo, COL_INFO, "%s, PKN: %u, CID: 0x%" G_GINT64_MODIFIER "x", val_to_str(long_packet_type, quic_long_packet_type_vals, "Unknown Packet Type"), pkn, cid); + /* Payload */ + switch(long_packet_type) { + case QUIC_LPT_INITIAL: /* Initial */ + offset = dissect_quic_initial(tvb, pinfo, quic_tree, offset, quic_info, pkn, cid); + break; + case QUIC_LPT_HANDSHAKE: /* Handshake */ + offset = dissect_quic_handshake(tvb, pinfo, quic_tree, offset, quic_info, pkn); + break; + default: + /* Protected (Encrypted) Payload */ + proto_tree_add_item(quic_tree, hf_quic_protected_payload, tvb, offset, -1, ENC_NA); + offset += tvb_reported_length_remaining(tvb, offset); + break; } return offset; |