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