diff options
author | Alexis La Goutte <alexis.lagoutte@gmail.com> | 2017-12-31 08:51:42 +0100 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2018-01-02 05:34:23 +0000 |
commit | 8c87af98801626cb557eb3b06ab47cda853ec3e2 (patch) | |
tree | 42e2814ca79eeee794e58ed5eced59a9ed4197e4 | |
parent | 1a7d65d08557c2b1ad9a4a563fc4dc86ed1af269 (diff) |
QUIC: Add decrypt Handshake Packet
From/to Server/Client
Store the port destination to found key need to be used
Change-Id: If7f2edcdb21f5b5aa9de28431db8dc3ec6d76602
Reviewed-on: https://code.wireshark.org/review/25083
Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r-- | epan/dissectors/packet-quic.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/epan/dissectors/packet-quic.c b/epan/dissectors/packet-quic.c index 021697f0ff..d83b0673b4 100644 --- a/epan/dissectors/packet-quic.c +++ b/epan/dissectors/packet-quic.c @@ -128,6 +128,7 @@ static dissector_handle_t ssl_handle; typedef struct quic_info_data { guint32 version; + guint16 server_port; tls13_cipher *client_cleartext_cipher; tls13_cipher *server_cleartext_cipher; } quic_info_data_t; @@ -1128,11 +1129,18 @@ dissect_quic_long_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tre ti = proto_tree_add_item(quic_tree, hf_quic_initial_payload, tvb, offset, -1, ENC_NA); + /* Initial Packet is always send by client */ + if(pinfo->destport != 443) { + quic_info->server_port = pinfo->destport; + } + #ifdef HAVE_LIBGCRYPT_AEAD tls13_cipher *cipher = NULL; const gchar *error = NULL; tvbuff_t *decrypted_tvb; + cipher = quic_info->client_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)) { @@ -1140,8 +1148,6 @@ dissect_quic_long_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tre return offset; } - cipher = quic_info->client_cleartext_cipher; - if (cipher) { /* quic_decrypt_message expects exactly one header + ciphertext as tvb. */ DISSECTOR_ASSERT(offset == QUIC_LONG_HEADER_LENGTH); @@ -1163,8 +1169,38 @@ dissect_quic_long_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tre /* Handshake (>= draft-08) */ } else if (long_packet_type == 0x7D ) { + 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; + + if(pinfo->destport == quic_info->server_port) { + cipher = quic_info->client_cleartext_cipher; + } else { + cipher = quic_info->server_cleartext_cipher; + } - proto_tree_add_item(quic_tree, hf_quic_handshake_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); + + 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); } else { @@ -1235,6 +1271,7 @@ dissect_quic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, if (!quic_info) { quic_info = wmem_new0(wmem_file_scope(), quic_info_data_t); quic_info->version = 0; + quic_info->server_port = 443; conversation_add_proto_data(conv, proto_quic, quic_info); } |