diff --git a/epan/dissectors/packet-ssl-utils.h b/epan/dissectors/packet-ssl-utils.h index aaadbe7..ccac6ae 100644 --- a/epan/dissectors/packet-ssl-utils.h +++ b/epan/dissectors/packet-ssl-utils.h @@ -151,6 +151,7 @@ #define SSL_HND_HELLO_EXT_SERVER_NAME 0x0 #define SSL_HND_HELLO_EXT_ELLIPTIC_CURVES 0x000a #define SSL_HND_HELLO_EXT_EC_POINT_FORMATS 0x000b +#define SSL_HND_HELLO_EXT_SIG_HASH_ALGS 0x000d #define SSL_HND_HELLO_EXT_HEARTBEAT 0x000f #define SSL_HND_HELLO_EXT_RENEG_INFO 0xff01 #define SSL_HND_HELLO_EXT_NPN 0x3374 diff --git a/epan/dissectors/packet-ssl.c b/epan/dissectors/packet-ssl.c index d75a3cc..b50ca22 100644 --- a/epan/dissectors/packet-ssl.c +++ b/epan/dissectors/packet-ssl.c @@ -542,6 +542,9 @@ static gint dissect_ssl3_hnd_hello_ext_elliptic_curves(tvbuff_t *tvb, static gint dissect_ssl3_hnd_hello_ext_ec_point_formats(tvbuff_t *tvb, proto_tree *tree, guint32 offset); +static gint dissect_ssl3_hnd_hello_ext_sig_hash_algs(tvbuff_t *tvb, + proto_tree *tree, guint32 offset, guint32 ext_len); + static gint dissect_ssl3_hnd_hello_ext_npn(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 ext_len); @@ -674,6 +677,10 @@ static gint ssl_looks_like_valid_v2_handshake(tvbuff_t *tvb, static gint ssl_looks_like_valid_pct_handshake(tvbuff_t *tvb, const guint32 offset, const guint32 record_length); + +static gint dissect_ssl_hash_alg_list(tvbuff_t *tvb, proto_tree *tree, + guint32 offset, guint16 len); + /********************************************************************* * * Main dissector @@ -2439,6 +2446,9 @@ dissect_ssl3_hnd_hello_ext(tvbuff_t *tvb, case SSL_HND_HELLO_EXT_EC_POINT_FORMATS: offset = dissect_ssl3_hnd_hello_ext_ec_point_formats(tvb, ext_tree, offset); break; + case SSL_HND_HELLO_EXT_SIG_HASH_ALGS: + offset = dissect_ssl3_hnd_hello_ext_sig_hash_algs(tvb, ext_tree, offset, ext_len); + break; case SSL_HND_HELLO_EXT_NPN: offset = dissect_ssl3_hnd_hello_ext_npn(tvb, ext_tree, offset, ext_len); break; @@ -2502,6 +2512,29 @@ dissect_ssl3_hnd_hello_ext_npn(tvbuff_t *tvb, } static gint +dissect_ssl3_hnd_hello_ext_sig_hash_algs(tvbuff_t *tvb, + proto_tree *tree, guint32 offset, guint32 ext_len) +{ + guint16 sh_alg_length; + gint ret; + + sh_alg_length = tvb_get_ntohs(tvb, offset); + proto_tree_add_uint(tree, hf_ssl_handshake_sig_hash_alg_len, + tvb, offset, 2, sh_alg_length); + offset += 2; + if (ext_len<2 || sh_alg_length!=ext_len-2) { + /* ERROR: sh_alg_length must be 2 less than ext_len */ + return offset; + } + + ret = dissect_ssl_hash_alg_list(tvb, tree, offset, sh_alg_length); + if (ret >=0) + offset += ret; + + return offset; +} + +static gint dissect_ssl3_hnd_hello_ext_reneg_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 ext_len) { @@ -4957,6 +4990,51 @@ ssl_looks_like_valid_pct_handshake(tvbuff_t *tvb, const guint32 offset, return ret; } +/* dissect a list of hash algorithms, return the number of bytes dissected + * this is used for the signature algorithms extension and for the + * TLS1.2 certificate request */ +static gint +dissect_ssl_hash_alg_list(tvbuff_t *tvb, proto_tree *tree, + guint32 offset, guint16 len) +{ + guint32 offset_start; + proto_tree *subtree, *alg_tree; + proto_tree *ti; + + offset_start = offset; + if (len==0) + return 0; + + ti = proto_tree_add_none_format(tree, + hf_ssl_handshake_sig_hash_algs, + tvb, offset, len, + "Signature Hash Algorithms (%u algorithm%s)", + len/2, + plurality(len/2, "", "s")); + subtree = proto_item_add_subtree(ti, ett_ssl_sig_hash_algs); + + if (len % 2) { + proto_tree_add_text(tree, tvb, offset, 2, + "Invalid Signature Hash Algorithm length: %d", len); + return offset-offset_start; + } + + while (len > 0) { + ti = proto_tree_add_item(subtree, hf_ssl_handshake_sig_hash_alg, + tvb, offset, 2, ENC_BIG_ENDIAN); + alg_tree = proto_item_add_subtree(ti, ett_ssl_sig_hash_alg); + + proto_tree_add_item(alg_tree, hf_ssl_handshake_sig_hash_hash, + tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(alg_tree, hf_ssl_handshake_sig_hash_sig, + tvb, offset+1, 1, ENC_BIG_ENDIAN); + + offset += 2; + len -= 2; + } + return offset-offset_start; +} + /* UAT */ #ifdef HAVE_LIBGNUTLS