diff --git a/epan/dissectors/packet-tls-utils.c b/epan/dissectors/packet-tls-utils.c index 666c1807cd..85161d123f 100644 --- a/epan/dissectors/packet-tls-utils.c +++ b/epan/dissectors/packet-tls-utils.c @@ -1215,6 +1215,7 @@ const value_string tls_hello_extension_types[] = { { SSL_HND_HELLO_EXT_GREASE_2A2A, "Reserved (GREASE)" }, /* RFC 8701 */ { SSL_HND_HELLO_EXT_NPN, "next_protocol_negotiation"}, /* https://tools.ietf.org/id/draft-agl-tls-nextprotoneg-03.html */ { SSL_HND_HELLO_EXT_GREASE_3A3A, "Reserved (GREASE)" }, /* RFC 8701 */ + { SSL_HND_HELLO_EXT_ALPS, "application_settings" }, /* draft-vvv-tls-alps-01 */ { SSL_HND_HELLO_EXT_GREASE_4A4A, "Reserved (GREASE)" }, /* RFC 8701 */ { SSL_HND_HELLO_EXT_GREASE_5A5A, "Reserved (GREASE)" }, /* RFC 8701 */ { SSL_HND_HELLO_EXT_GREASE_6A6A, "Reserved (GREASE)" }, /* RFC 8701 */ @@ -6674,6 +6675,65 @@ ssl_dissect_hnd_ext_delegated_credentials(ssl_common_dissect_t *hf, tvbuff_t *tv return ssl_dissect_hash_alg_list(hf, tvb, tree, pinfo, offset, offset_end); } +static gint +ssl_dissect_hnd_hello_ext_alps(ssl_common_dissect_t *hf, tvbuff_t *tvb, + packet_info *pinfo, proto_tree *tree, + guint32 offset, guint32 offset_end, + guint8 hnd_type) +{ + + /* https://datatracker.ietf.org/doc/html/draft-vvv-tls-alps-01#section-4 */ + + switch (hnd_type) { + case SSL_HND_CLIENT_HELLO: { + proto_tree *alps_tree; + proto_item *ti; + guint32 next_offset, alps_length, name_length; + + /* + * opaque ProtocolName<1..2^8-1>; + * struct { + * ProtocolName supported_protocols<2..2^16-1> + * } ApplicationSettingsSupport; + */ + + if (!ssl_add_vector(hf, tvb, pinfo, tree, offset, offset_end, &alps_length, + hf->hf.hs_ext_alps_len, 2, G_MAXUINT16)) { + return offset_end; + } + offset += 2; + next_offset = offset + alps_length; + + ti = proto_tree_add_item(tree, hf->hf.hs_ext_alps_alpn_list, + tvb, offset, alps_length, ENC_NA); + alps_tree = proto_item_add_subtree(ti, hf->ett.hs_ext_alps); + + /* Parse list (note missing check for end of vector, ssl_add_vector below + * ensures that data is always available.) */ + while (offset < next_offset) { + if (!ssl_add_vector(hf, tvb, pinfo, alps_tree, offset, next_offset, &name_length, + hf->hf.hs_ext_alps_alpn_str_len, 1, G_MAXUINT8)) { + return next_offset; + } + offset++; + + proto_tree_add_item(alps_tree, hf->hf.hs_ext_alps_alpn_str, + tvb, offset, name_length, ENC_ASCII|ENC_NA); + offset += name_length; + } + + return offset; + } + case SSL_HND_ENCRYPTED_EXTS: + /* Opaque blob */ + proto_tree_add_item(tree, hf->hf.hs_ext_alps_settings, + tvb, offset, offset_end - offset, ENC_ASCII|ENC_NA); + break; + } + + return offset_end; +} + static gint ssl_dissect_hnd_hello_ext_alpn(ssl_common_dissect_t *hf, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, @@ -9563,6 +9623,9 @@ ssl_dissect_hnd_extension(ssl_common_dissect_t *hf, tvbuff_t *tvb, proto_tree *t case SSL_HND_HELLO_EXT_NPN: offset = ssl_dissect_hnd_hello_ext_npn(hf, tvb, pinfo, ext_tree, offset, next_offset); break; + case SSL_HND_HELLO_EXT_ALPS: + offset = ssl_dissect_hnd_hello_ext_alps(hf, tvb, pinfo, ext_tree, offset, next_offset, hnd_type); + break; case SSL_HND_HELLO_EXT_RENEGOTIATION_INFO: offset = ssl_dissect_hnd_hello_ext_reneg_info(hf, tvb, pinfo, ext_tree, offset, next_offset); break; diff --git a/epan/dissectors/packet-tls-utils.h b/epan/dissectors/packet-tls-utils.h index b3d1912bac..799632020b 100644 --- a/epan/dissectors/packet-tls-utils.h +++ b/epan/dissectors/packet-tls-utils.h @@ -130,6 +130,7 @@ typedef enum { #define SSL_HND_HELLO_EXT_GREASE_2A2A 10794 #define SSL_HND_HELLO_EXT_NPN 13172 /* 0x3374 */ #define SSL_HND_HELLO_EXT_GREASE_3A3A 14906 +#define SSL_HND_HELLO_EXT_ALPS 17513 /* draft-vvv-tls-alps-01, temporary value used in BoringSSL implementation */ #define SSL_HND_HELLO_EXT_GREASE_4A4A 19018 #define SSL_HND_HELLO_EXT_GREASE_5A5A 23130 #define SSL_HND_HELLO_EXT_GREASE_6A6A 27242 @@ -1036,6 +1037,12 @@ typedef struct ssl_common_dissect { gint esni_encrypted_sni; gint esni_nonce; + gint hs_ext_alps_len; + gint hs_ext_alps_alpn_list; + gint hs_ext_alps_alpn_str; + gint hs_ext_alps_alpn_str_len; + gint hs_ext_alps_settings; + /* do not forget to update SSL_COMMON_LIST_T and SSL_COMMON_HF_LIST! */ } hf; struct { @@ -1068,6 +1075,7 @@ typedef struct ssl_common_dissect { gint cert_status; gint ocsp_response; gint uncompressed_certificates; + gint hs_ext_alps; /* do not forget to update SSL_COMMON_LIST_T and SSL_COMMON_ETT_LIST! */ } ett; @@ -1260,11 +1268,12 @@ 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, -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, \ - -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 \ }, \ /* ei */ { \ EI_INIT, EI_INIT, EI_INIT, EI_INIT, EI_INIT, EI_INIT, EI_INIT \ @@ -2390,6 +2399,31 @@ ssl_common_dissect_t name = { \ { "Nonce", prefix ".esni.nonce", \ FT_BYTES, BASE_NONE, NULL, 0x00, \ "Contents of ClientESNIInner.nonce", HFILL } \ + }, \ + { & name .hf.hs_ext_alps_len, \ + { "ALPS Extension Length", prefix ".handshake.extensions_alps_len", \ + FT_UINT16, BASE_DEC, NULL, 0x0, \ + "Length of the ALPS Extension", HFILL } \ + }, \ + { & name .hf.hs_ext_alps_alpn_list, \ + { "Supported ALPN List", prefix ".handshake.extensions_alps_alpn_list", \ + FT_NONE, BASE_NONE, NULL, 0x0, \ + "List of supported ALPN by ALPS", HFILL } \ + }, \ + { & name .hf.hs_ext_alps_alpn_str_len, \ + { "Supported ALPN Length", prefix ".handshake.extensions_alps_alpn_str_len", \ + FT_UINT8, BASE_DEC, NULL, 0x0, \ + "Length of ALPN string", HFILL } \ + }, \ + { & name .hf.hs_ext_alps_alpn_str, \ + { "Supported ALPN", prefix ".handshake.extensions_alps_alpn_str", \ + FT_STRING, BASE_NONE, NULL, 0x00, \ + "ALPN supported by ALPS", HFILL } \ + }, \ + { & name .hf.hs_ext_alps_settings, \ + { "ALPN Opaque Settings", prefix ".handshake.extensions_alps.settings", \ + FT_BYTES, BASE_NONE, NULL, 0x00, \ + "ALPN Opaque Settings", HFILL } \ } /* }}} */ @@ -2424,6 +2458,7 @@ ssl_common_dissect_t name = { \ & name .ett.cert_status, \ & name .ett.ocsp_response, \ & name .ett.uncompressed_certificates, \ + & name .ett.hs_ext_alps, \ /* }}} */ /* {{{ */