diff options
author | Alexis La Goutte <alexis.lagoutte@gmail.com> | 2018-02-24 17:53:33 +0100 |
---|---|---|
committer | Alexis La Goutte <alexis.lagoutte@gmail.com> | 2018-03-01 06:44:31 +0000 |
commit | c332f6e1f9f90df90cd62c4108f95a85515f34a4 (patch) | |
tree | 875680c9eea40d6c54d62be9a5b0741b7e188c6b | |
parent | 8c85f0c35c4383919e0467b44cd3f208f280404d (diff) |
QUIC: Add dissection of RETRY
Bug: 13881
Change-Id: I49075dc227c0b132ef4bc37d1ff28b14bbfd3e4f
Reviewed-on: https://code.wireshark.org/review/26083
Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
-rw-r--r-- | epan/dissectors/packet-quic.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/epan/dissectors/packet-quic.c b/epan/dissectors/packet-quic.c index e31cbdf9d8..1125e26f7d 100644 --- a/epan/dissectors/packet-quic.c +++ b/epan/dissectors/packet-quic.c @@ -46,6 +46,7 @@ static int hf_quic_short_kp_flag = -1; static int hf_quic_short_packet_type = -1; static int hf_quic_initial_payload = -1; static int hf_quic_handshake_payload = -1; +static int hf_quic_retry_payload = -1; static int hf_quic_protected_payload = -1; static int hf_quic_frame = -1; @@ -881,6 +882,43 @@ dissect_quic_handshake(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree, } static int +dissect_quic_retry(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_retry_payload, tvb, offset, -1, ENC_NA); + +#ifdef HAVE_LIBGCRYPT_AEAD + tls13_cipher *cipher = NULL; + const gchar *error = NULL; + tvbuff_t *decrypted_tvb; + + /* Retry coming always from server */ + cipher = quic_info->server_cleartext_cipher; + + 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 retry: %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_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; @@ -907,6 +945,9 @@ dissect_quic_long_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tre case QUIC_LPT_HANDSHAKE: /* Handshake */ offset = dissect_quic_handshake(tvb, pinfo, quic_tree, offset, quic_info, pkn); break; + case QUIC_LPT_RETRY: /* Retry */ + offset = dissect_quic_retry(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); @@ -1099,6 +1140,11 @@ proto_register_quic(void) FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, + { &hf_quic_retry_payload, + { "Retry Payload", "quic.retry_payload", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, { &hf_quic_protected_payload, { "Protected Payload", "quic.protected_payload", |