From 196c2b1284464239a47bc910c0d6abaac99ee007 Mon Sep 17 00:00:00 2001 From: Alexis La Goutte Date: Thu, 6 Oct 2016 12:44:43 +0200 Subject: [PATCH] TLS(1.3): Add Hello Retry Request (6) extension Add also special case on hello key_share extension Ping-Bug: 12779 Change-Id: Ib8e2dd060f322c2404a8afa9b8cb70de7c2c65b7 Reviewed-on: https://code.wireshark.org/review/18093 Petri-Dish: Alexis La Goutte Reviewed-by: Peter Wu Tested-by: Petri Dish Buildbot Reviewed-by: Michael Mann --- epan/dissectors/packet-dtls.c | 5 +++++ epan/dissectors/packet-ssl-utils.c | 29 +++++++++++++++++++++++++++++ epan/dissectors/packet-ssl-utils.h | 14 +++++++++++++- epan/dissectors/packet-ssl.c | 5 +++++ 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/epan/dissectors/packet-dtls.c b/epan/dissectors/packet-dtls.c index 1f2bc3204f..f813278a58 100644 --- a/epan/dissectors/packet-dtls.c +++ b/epan/dissectors/packet-dtls.c @@ -1291,6 +1291,11 @@ dissect_dtls_handshake(tvbuff_t *tvb, packet_info *pinfo, dtls_master_key_map.tickets); break; + case SSL_HND_HELLO_RETRY_REQUEST: + ssl_dissect_hnd_hello_retry_request(&dissect_dtls_hf, sub_tvb, pinfo, ssl_hand_tree, + 0, length, session, ssl); + break; + case SSL_HND_CERTIFICATE: ssl_dissect_hnd_cert(&dissect_dtls_hf, sub_tvb, ssl_hand_tree, 0, pinfo, session, ssl, dtls_key_hash, is_from_server); diff --git a/epan/dissectors/packet-ssl-utils.c b/epan/dissectors/packet-ssl-utils.c index 7aafa99fd7..f412148c5e 100644 --- a/epan/dissectors/packet-ssl-utils.c +++ b/epan/dissectors/packet-ssl-utils.c @@ -5518,6 +5518,10 @@ ssl_dissect_hnd_hello_ext_key_share(ssl_common_dissect_t *hf, tvbuff_t *tvb, case SSL_HND_SERVER_HELLO: offset = ssl_dissect_hnd_hello_ext_key_share_entry(hf, tvb, key_share_tree, offset, offset_end); break; + case SSL_HND_HELLO_RETRY_REQUEST: + proto_tree_add_item(key_share_tree, hf->hf.hs_ext_key_share_selected_group, tvb, offset, 2, ENC_BIG_ENDIAN ); + offset += 2; + break; default: /* no default */ break; } @@ -6015,6 +6019,7 @@ ssl_is_valid_handshake_type(guint8 hs_type, gboolean is_dtls) case SSL_HND_CLIENT_HELLO: case SSL_HND_SERVER_HELLO: case SSL_HND_NEWSESSION_TICKET: + case SSL_HND_HELLO_RETRY_REQUEST: case SSL_HND_CERTIFICATE: case SSL_HND_SERVER_KEY_EXCHG: case SSL_HND_CERT_REQUEST: @@ -6337,6 +6342,30 @@ ssl_dissect_hnd_new_ses_ticket(ssl_common_dissect_t *hf, tvbuff_t *tvb, #endif } /* }}} */ +void +ssl_dissect_hnd_hello_retry_request(ssl_common_dissect_t *hf, tvbuff_t *tvb, + packet_info* pinfo, proto_tree *tree, guint32 offset, guint32 length, + SslSession *session, SslDecryptSession *ssl) +{ + /* struct { + * ProtocolVersion server_version; + * Extension extensions<2..2^16-1>; + * } HelloRetryRequest; + */ + guint16 start_offset = offset; + + proto_tree_add_item(tree, hf->hf.hs_server_version, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + /* remaining data are extensions */ + if (length > offset - start_offset) { + ssl_dissect_hnd_hello_ext(hf, tvb, tree, pinfo, offset, + length - (offset - start_offset), SSL_HND_HELLO_RETRY_REQUEST, + session, ssl); + } +} + /* Certificate and Certificate Request dissections. {{{ */ void ssl_dissect_hnd_cert(ssl_common_dissect_t *hf, tvbuff_t *tvb, proto_tree *tree, diff --git a/epan/dissectors/packet-ssl-utils.h b/epan/dissectors/packet-ssl-utils.h index 1e589a137c..0c416e2669 100644 --- a/epan/dissectors/packet-ssl-utils.h +++ b/epan/dissectors/packet-ssl-utils.h @@ -62,6 +62,7 @@ typedef enum { SSL_HND_SERVER_HELLO = 2, SSL_HND_HELLO_VERIFY_REQUEST = 3, SSL_HND_NEWSESSION_TICKET = 4, + SSL_HND_HELLO_RETRY_REQUEST = 6, SSL_HND_CERTIFICATE = 11, SSL_HND_SERVER_KEY_EXCHG = 12, SSL_HND_CERT_REQUEST = 13, @@ -672,6 +673,7 @@ typedef struct ssl_common_dissect { gint hs_ext_key_share_group; gint hs_ext_key_share_key_exchange_length; gint hs_ext_key_share_key_exchange; + gint hs_ext_key_share_selected_group; gint hs_ext_psk_identities_length; gint hs_ext_psk_identity_ke_modes_length; gint hs_ext_psk_identity_ke_mode; @@ -830,6 +832,11 @@ ssl_dissect_hnd_srv_hello(ssl_common_dissect_t *hf, tvbuff_t *tvb, packet_info* SslSession *session, SslDecryptSession *ssl, gboolean is_dtls); +extern void +ssl_dissect_hnd_hello_retry_request(ssl_common_dissect_t *hf, tvbuff_t *tvb, packet_info* pinfo, + proto_tree *tree, guint32 offset, guint32 length, + SslSession *session, SslDecryptSession *ssl); + extern void ssl_dissect_hnd_new_ses_ticket(ssl_common_dissect_t *hf, tvbuff_t *tvb, proto_tree *tree, guint32 offset, @@ -881,7 +888,7 @@ ssl_common_dissect_t name = { \ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \ - -1, -1, -1, \ + -1, -1, -1, -1, \ }, \ /* ett */ { \ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \ @@ -1005,6 +1012,11 @@ ssl_common_dissect_t name = { \ FT_BYTES, BASE_NONE, NULL, 0x0, \ NULL, HFILL } \ }, \ + { & name .hf.hs_ext_key_share_selected_group, \ + { "Selected Group", prefix ".handshake.extensions_key_share_selected_group", \ + FT_UINT16, BASE_DEC, VALS(ssl_extension_curves), 0x00, \ + NULL, HFILL } \ + }, \ { & name .hf.hs_ext_psk_identities_length, \ { "Identities Length", prefix ".handshake.extensions.psk.identities.length", \ FT_UINT16, BASE_DEC, NULL, 0x0, \ diff --git a/epan/dissectors/packet-ssl.c b/epan/dissectors/packet-ssl.c index c0450dedc2..c50d4bca3b 100644 --- a/epan/dissectors/packet-ssl.c +++ b/epan/dissectors/packet-ssl.c @@ -2055,6 +2055,11 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo, ssl_master_key_map.tickets); break; + case SSL_HND_HELLO_RETRY_REQUEST: + ssl_dissect_hnd_hello_retry_request(&dissect_ssl3_hf, tvb, pinfo, ssl_hand_tree, + offset, length, session, ssl); + break; + case SSL_HND_CERTIFICATE: ssl_dissect_hnd_cert(&dissect_ssl3_hf, tvb, ssl_hand_tree, offset, pinfo, session, ssl, ssl_key_hash, is_from_server);