diff options
author | Peter Wu <peter@lekensteyn.nl> | 2014-07-19 10:54:19 +0200 |
---|---|---|
committer | Evan Huus <eapache@gmail.com> | 2014-07-23 17:09:01 +0000 |
commit | ee231c526373b1c2e8c750fec0fc42befbfe3a97 (patch) | |
tree | de7f83029f1554a095e7c7542ca6b5d74f7cb91f /epan/dissectors/packet-ssl-utils.c | |
parent | aa09feaf52f842adcf70aca60409281e5739ec08 (diff) |
ssl,dtls: move ClientHello to ssl-utils
Changes to ClientHello dissection:
- Move ssl_find_private_key (and its pre-req, ssl_set_server) outside
ssl_dissect_hnd_cli_hello. It has not really something to do with
dissection, but state tracking and decoder param feeding.
- dtls: add expert info for bad cipher suites len.
- ssl: remove bad cipher suites len text label which is also
available as expert info. Attach expert info to a the length proto
item (which is converted to use add_item instead of add_uint).
- Remove `if (tree || ssl)` since expert info seems not to apply
otherwise (this also needs changes in common and handshake
dissection).
- ssl: remove tvb_ensure_bytes_exist so we can dissect more
compression methods and cipher suites.
- Since DTLS has an additional Cookie field which TLS does not have,
pass these additional header fields through a struct whose type is
defined in ssl-utils.
Change-Id: I41bef04c1c3353e582e30f561d1d246a744e1d60
Reviewed-on: https://code.wireshark.org/review/3021
Reviewed-by: Evan Huus <eapache@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-ssl-utils.c')
-rw-r--r-- | epan/dissectors/packet-ssl-utils.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/epan/dissectors/packet-ssl-utils.c b/epan/dissectors/packet-ssl-utils.c index d2c860df81..ee8c81b6e1 100644 --- a/epan/dissectors/packet-ssl-utils.c +++ b/epan/dissectors/packet-ssl-utils.c @@ -5237,6 +5237,124 @@ ssl_dissect_hnd_hello_common(ssl_common_dissect_t *hf, tvbuff_t *tvb, } void +ssl_dissect_hnd_cli_hello(ssl_common_dissect_t *hf, tvbuff_t *tvb, + packet_info *pinfo, proto_tree *tree, guint32 offset, + guint32 length, SslSession *session, + SslDecryptSession *ssl, dtls_hfs_t *dtls_hfs) +{ + /* struct { + * ProtocolVersion client_version; + * Random random; + * SessionID session_id; + * opaque cookie<0..32>; //new field for DTLS + * CipherSuite cipher_suites<2..2^16-1>; + * CompressionMethod compression_methods<1..2^8-1>; + * Extension client_hello_extension_list<0..2^16-1>; + * } ClientHello; + * + */ + proto_item *ti; + proto_tree *cs_tree; + guint16 cipher_suite_length; + guint8 compression_methods_length; + guint8 compression_method; + guint16 start_offset = offset; + + /* show the client version */ + proto_tree_add_item(tree, hf->hf.hs_client_version, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + /* dissect fields that are also present in ClientHello */ + offset = ssl_dissect_hnd_hello_common(hf, tvb, tree, offset, ssl, FALSE); + + /* fields specific for DTLS (cookie_len, cookie) */ + if (dtls_hfs != NULL) { + /* look for a cookie */ + guint8 cookie_length = tvb_get_guint8(tvb, offset); + + proto_tree_add_uint(tree, dtls_hfs->hf_dtls_handshake_cookie_len, + tvb, offset, 1, cookie_length); + offset++; + if (cookie_length > 0) { + proto_tree_add_item(tree, dtls_hfs->hf_dtls_handshake_cookie, + tvb, offset, cookie_length, ENC_NA); + offset += cookie_length; + } + } + + /* tell the user how many cipher suites there are */ + cipher_suite_length = tvb_get_ntohs(tvb, offset); + ti = proto_tree_add_item(tree, hf->hf.hs_cipher_suites_len, + tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + if (cipher_suite_length > 0) { + if (cipher_suite_length % 2) { + expert_add_info_format(pinfo, ti, &hf->ei.hs_cipher_suites_len_bad, + "Cipher suite length (%d) must be a multiple of 2", + cipher_suite_length); + return; + } + ti = proto_tree_add_none_format(tree, + hf->hf.hs_cipher_suites, + tvb, offset, cipher_suite_length, + "Cipher Suites (%d suite%s)", + cipher_suite_length / 2, + plurality(cipher_suite_length/2, "", "s")); + + /* make this a subtree */ + cs_tree = proto_item_add_subtree(ti, hf->ett.cipher_suites); + + while (cipher_suite_length > 0) { + proto_tree_add_item(cs_tree, hf->hf.hs_cipher_suite, + tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + cipher_suite_length -= 2; + } + } + /* tell the user how many compression methods there are */ + compression_methods_length = tvb_get_guint8(tvb, offset); + proto_tree_add_uint(tree, hf->hf.hs_comp_methods_len, + tvb, offset, 1, compression_methods_length); + offset += 1; + if (compression_methods_length > 0) { + ti = proto_tree_add_none_format(tree, + hf->hf.hs_comp_methods, + tvb, offset, compression_methods_length, + "Compression Methods (%u method%s)", + compression_methods_length, + plurality(compression_methods_length, + "", "s")); + + /* make this a subtree */ + cs_tree = proto_item_add_subtree(ti, hf->ett.comp_methods); + + while (compression_methods_length > 0) { + compression_method = tvb_get_guint8(tvb, offset); + /* TODO: make reserved/private comp meth. fields selectable */ + if (compression_method < 64) + proto_tree_add_uint(cs_tree, hf->hf.hs_comp_method, + tvb, offset, 1, compression_method); + else if (compression_method > 63 && compression_method < 193) + proto_tree_add_text(cs_tree, tvb, offset, 1, + "Compression Method: Reserved - to be assigned by IANA (%u)", + compression_method); + else + proto_tree_add_text(cs_tree, tvb, offset, 1, + "Compression Method: Private use range (%u)", + compression_method); + offset++; + compression_methods_length--; + } + } + if (length > offset - start_offset) { + ssl_dissect_hnd_hello_ext(hf, tvb, tree, offset, + length - (offset - start_offset), TRUE, + session, ssl); + } +} + +void ssl_dissect_hnd_srv_hello(ssl_common_dissect_t *hf, tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 length, SslSession *session, SslDecryptSession *ssl) |