aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ssl.c
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2012-01-28 15:50:59 +0000
committerAnders Broman <anders.broman@ericsson.com>2012-01-28 15:50:59 +0000
commitcde63b2001af90a9bc8c72e84b902bf76a16518a (patch)
tree50df07551e0438a768242f4d77272bbd29c14628 /epan/dissectors/packet-ssl.c
parent6be62cd7531854c7cf65915887a1235fb2b2ebcd (diff)
From Michael:
Enhance SSL Key Exchange dissection. https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6716 svn path=/trunk/; revision=40748
Diffstat (limited to 'epan/dissectors/packet-ssl.c')
-rw-r--r--epan/dissectors/packet-ssl.c355
1 files changed, 327 insertions, 28 deletions
diff --git a/epan/dissectors/packet-ssl.c b/epan/dissectors/packet-ssl.c
index 96acfc313e..7e26472184 100644
--- a/epan/dissectors/packet-ssl.c
+++ b/epan/dissectors/packet-ssl.c
@@ -181,12 +181,24 @@ static gint hf_ssl_handshake_cert_type = -1;
static gint hf_ssl_handshake_server_keyex_p_len = -1;
static gint hf_ssl_handshake_server_keyex_g_len = -1;
static gint hf_ssl_handshake_server_keyex_ys_len = -1;
+static gint hf_ssl_handshake_server_keyex_point_len = -1;
static gint hf_ssl_handshake_client_keyex_yc_len = -1;
+static gint hf_ssl_handshake_client_keyex_point_len = -1;
+static gint hf_ssl_handshake_client_keyex_epms_len = -1;
+static gint hf_ssl_handshake_server_keyex_modulus_len = -1;
+static gint hf_ssl_handshake_server_keyex_exponent_len = -1;
static gint hf_ssl_handshake_server_keyex_sig_len = -1;
static gint hf_ssl_handshake_server_keyex_p = -1;
static gint hf_ssl_handshake_server_keyex_g = -1;
static gint hf_ssl_handshake_server_keyex_ys = -1;
static gint hf_ssl_handshake_client_keyex_yc = -1;
+static gint hf_ssl_handshake_server_keyex_curve_type = -1;
+static gint hf_ssl_handshake_server_keyex_named_curve = -1;
+static gint hf_ssl_handshake_server_keyex_point = -1;
+static gint hf_ssl_handshake_client_keyex_epms = -1;
+static gint hf_ssl_handshake_client_keyex_point = -1;
+static gint hf_ssl_handshake_server_keyex_modulus = -1;
+static gint hf_ssl_handshake_server_keyex_exponent = -1;
static gint hf_ssl_handshake_server_keyex_sig = -1;
static gint hf_ssl_handshake_sig_hash_alg_len = -1;
static gint hf_ssl_handshake_sig_hash_algs = -1;
@@ -460,14 +472,32 @@ static void dissect_ssl3_hnd_cert_req(tvbuff_t *tvb,
guint32 offset, packet_info *pinfo,
const guint* conv_version);
+static void dissect_ssl3_hnd_srv_keyex_ecdh(tvbuff_t *tvb,
+ proto_tree *tree,
+ guint32 offset, guint32 length);
+
+
static void dissect_ssl3_hnd_srv_keyex_dh(tvbuff_t *tvb,
proto_tree *tree,
guint32 offset, guint32 length);
+static void dissect_ssl3_hnd_srv_keyex_rsa(tvbuff_t *tvb,
+ proto_tree *tree,
+ guint32 offset, guint32 length);
+
+static void dissect_ssl3_hnd_cli_keyex_ecdh(tvbuff_t *tvb,
+ proto_tree *tree,
+ guint32 offset, guint32 length);
+
static void dissect_ssl3_hnd_cli_keyex_dh(tvbuff_t *tvb,
proto_tree *tree,
guint32 offset, guint32 length);
+static void dissect_ssl3_hnd_cli_keyex_rsa(tvbuff_t *tvb,
+ proto_tree *tree,
+ guint32 offset, guint32 length);
+
+
static void dissect_ssl3_hnd_finished(tvbuff_t *tvb,
proto_tree *tree,
const guint32 offset,
@@ -1880,14 +1910,20 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo,
break;
case SSL_HND_SERVER_KEY_EXCHG:
- /* Only supports (a couple) Diffie-Hellman key exchanges.
- Have to keep some state if you want to also support RSA
- (server key exchange is optional and appears to be rare for RSA)
- */
{
- if (conv_cipher == 0x39 || conv_cipher == 0x33) {
- dissect_ssl3_hnd_srv_keyex_dh(tvb, ssl_hand_tree, offset, length);
- }
+ switch(ssl_get_keyex_alg(conv_cipher)) {
+ case KEX_DH:
+ dissect_ssl3_hnd_srv_keyex_dh(tvb, ssl_hand_tree, offset, length);
+ break;
+ case KEX_RSA:
+ dissect_ssl3_hnd_srv_keyex_rsa(tvb, ssl_hand_tree, offset, length);
+ break;
+ case KEX_ECDH:
+ dissect_ssl3_hnd_srv_keyex_ecdh(tvb, ssl_hand_tree, offset, length);
+ break;
+ default:
+ break;
+ }
}
break;
@@ -1904,9 +1940,19 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo,
break;
case SSL_HND_CLIENT_KEY_EXCHG:
- if (conv_cipher == 0x39 || conv_cipher == 0x33) {
- dissect_ssl3_hnd_cli_keyex_dh(tvb, ssl_hand_tree, offset, length);
- }
+ switch(ssl_get_keyex_alg(conv_cipher)) {
+ case KEX_DH:
+ dissect_ssl3_hnd_cli_keyex_dh(tvb, ssl_hand_tree, offset, length);
+ break;
+ case KEX_RSA:
+ dissect_ssl3_hnd_cli_keyex_rsa(tvb, ssl_hand_tree, offset, length);
+ break;
+ case KEX_ECDH:
+ dissect_ssl3_hnd_cli_keyex_ecdh(tvb, ssl_hand_tree, offset, length);
+ break;
+ default:
+ break;
+ }
{
/* PAOLO: here we can have all the data to build session key*/
@@ -2729,7 +2775,108 @@ dissect_ssl3_hnd_cert_req(tvbuff_t *tvb,
}
static void
-dissect_ssl3_hnd_srv_keyex_dh(tvbuff_t *tvb, proto_tree *tree,
+dissect_ssl3_hnd_srv_keyex_ecdh(tvbuff_t *tvb, proto_tree *tree,
+ guint32 offset, guint32 length)
+{
+ gint curve_type, curve_type_offset;
+ gint named_curve, named_curve_offset;
+ gint point_len, point_len_offset;
+ gint sig_len, sig_len_offset;
+ proto_item *ti_ecdh;
+ proto_tree *ssl_ecdh_tree;
+ guint32 orig_offset;
+
+ orig_offset = offset;
+
+ curve_type_offset = offset;
+ curve_type = tvb_get_guint8(tvb, offset);
+ if (curve_type != 3)
+ return; /* only named_curves are supported */
+ offset++;
+ if ((offset - orig_offset) > length) {
+ return;
+ }
+
+ named_curve_offset = offset;
+ named_curve = tvb_get_ntohs(tvb, offset);
+ offset += 2;
+ if ((offset - orig_offset) > length) {
+ return;
+ }
+
+ point_len_offset = offset;
+ point_len = tvb_get_guint8(tvb, offset);
+ if ((offset + point_len - orig_offset) > length) {
+ return;
+ }
+ offset += 1 + point_len;
+
+ sig_len_offset = offset;
+ sig_len = tvb_get_ntohs(tvb, offset);
+ offset += 2 + sig_len;
+ if ((offset - orig_offset) != length) {
+ /* Lengths don't line up (wasn't what we expected?) */
+ return;
+ }
+
+ ti_ecdh = proto_tree_add_text(tree, tvb, orig_offset,
+ (offset - orig_offset), "EC Diffie-Hellman Server Params");
+ ssl_ecdh_tree = proto_item_add_subtree(ti_ecdh, ett_ssl_keyex_params);
+
+ /* curve_type */
+ proto_tree_add_uint(ssl_ecdh_tree, hf_ssl_handshake_server_keyex_curve_type,
+ tvb, curve_type_offset, 1, curve_type);
+
+ /* named_curve */
+ proto_tree_add_uint(ssl_ecdh_tree, hf_ssl_handshake_server_keyex_named_curve,
+ tvb, named_curve_offset, 2, named_curve);
+
+ /* point */
+ proto_tree_add_uint(ssl_ecdh_tree, hf_ssl_handshake_server_keyex_point_len,
+ tvb, point_len_offset, 1, point_len);
+ proto_tree_add_item(ssl_ecdh_tree, hf_ssl_handshake_server_keyex_point,
+ tvb, point_len_offset+1, point_len, ENC_NA);
+
+ /* Sig */
+ proto_tree_add_uint(ssl_ecdh_tree, hf_ssl_handshake_server_keyex_sig_len,
+ tvb, sig_len_offset, 2, sig_len);
+ proto_tree_add_item(ssl_ecdh_tree, hf_ssl_handshake_server_keyex_sig,
+ tvb, sig_len_offset + 2, sig_len, ENC_NA);
+
+}
+
+static void
+dissect_ssl3_hnd_cli_keyex_ecdh(tvbuff_t *tvb, proto_tree *tree,
+ guint32 offset, guint32 length)
+{
+ gint point_len, point_len_offset;
+ proto_item *ti_ecdh;
+ proto_tree *ssl_ecdh_tree;
+ guint32 orig_offset;
+
+ orig_offset = offset;
+
+ point_len_offset = offset;
+ point_len = tvb_get_guint8(tvb, offset);
+ if ((offset + point_len - orig_offset) > length) {
+ return;
+ }
+ offset += 1 + point_len;
+
+ ti_ecdh = proto_tree_add_text(tree, tvb, orig_offset,
+ (offset - orig_offset), "EC Diffie-Hellman Client Params");
+ ssl_ecdh_tree = proto_item_add_subtree(ti_ecdh, ett_ssl_keyex_params);
+
+ /* point */
+ proto_tree_add_uint(ssl_ecdh_tree, hf_ssl_handshake_client_keyex_point_len,
+ tvb, point_len_offset, 1, point_len);
+ proto_tree_add_item(ssl_ecdh_tree, hf_ssl_handshake_client_keyex_point,
+ tvb, point_len_offset+1, point_len, ENC_NA);
+
+}
+
+static void
+dissect_ssl3_hnd_srv_keyex_dh(tvbuff_t *tvb, proto_tree *tree,
guint32 offset, guint32 length)
{
gint p_len, p_len_offset;
@@ -2739,30 +2886,30 @@ dissect_ssl3_hnd_srv_keyex_dh(tvbuff_t *tvb, proto_tree *tree,
proto_item *ti_dh;
proto_tree *ssl_dh_tree;
guint32 orig_offset;
-
+
orig_offset = offset;
-
+
p_len_offset = offset;
p_len = tvb_get_ntohs(tvb, offset);
offset += 2 + p_len;
if ((offset - orig_offset) > length) {
return;
}
-
+
g_len_offset = offset;
g_len = tvb_get_ntohs(tvb, offset);
offset += 2 + g_len;
if ((offset - orig_offset) > length) {
return;
}
-
+
ys_len_offset = offset;
ys_len = tvb_get_ntohs(tvb, offset);
offset += 2 + ys_len;
if ((offset - orig_offset) > length) {
return;
}
-
+
sig_len_offset = offset;
sig_len = tvb_get_ntohs(tvb, offset);
offset += 2 + sig_len;
@@ -2770,37 +2917,98 @@ dissect_ssl3_hnd_srv_keyex_dh(tvbuff_t *tvb, proto_tree *tree,
/* Lengths don't line up (wasn't what we expected?) */
return;
}
-
- ti_dh = proto_tree_add_text(tree, tvb, orig_offset,
+
+ ti_dh = proto_tree_add_text(tree, tvb, orig_offset,
(offset - orig_offset), "Diffie-Hellman Server Params");
ssl_dh_tree = proto_item_add_subtree(ti_dh, ett_ssl_keyex_params);
-
+
/* p */
proto_tree_add_uint(ssl_dh_tree, hf_ssl_handshake_server_keyex_p_len,
tvb, p_len_offset, 2, p_len);
proto_tree_add_item(ssl_dh_tree, hf_ssl_handshake_server_keyex_p,
tvb, p_len_offset + 2, p_len, ENC_NA);
-
+
/* g */
proto_tree_add_uint(ssl_dh_tree, hf_ssl_handshake_server_keyex_g_len,
tvb, g_len_offset, 2, g_len);
proto_tree_add_item(ssl_dh_tree, hf_ssl_handshake_server_keyex_g,
tvb, g_len_offset + 2, g_len, ENC_NA);
-
+
/* Ys */
proto_tree_add_uint(ssl_dh_tree, hf_ssl_handshake_server_keyex_ys_len,
tvb, ys_len_offset, 2, ys_len);
proto_tree_add_item(ssl_dh_tree, hf_ssl_handshake_server_keyex_ys,
tvb, ys_len_offset + 2, ys_len, ENC_NA);
-
+
/* Sig */
proto_tree_add_uint(ssl_dh_tree, hf_ssl_handshake_server_keyex_sig_len,
tvb, sig_len_offset, 2, sig_len);
proto_tree_add_item(ssl_dh_tree, hf_ssl_handshake_server_keyex_sig,
tvb, sig_len_offset + 2, sig_len, ENC_NA);
+
+}
+
+/* Only used in RSA-EXPORT cipher suites */
+static void
+dissect_ssl3_hnd_srv_keyex_rsa(tvbuff_t *tvb, proto_tree *tree,
+ guint32 offset, guint32 length)
+{
+ gint modulus_len, modulus_len_offset;
+ gint exponent_len, exponent_len_offset;
+ gint sig_len, sig_len_offset;
+ proto_item *ti_rsa;
+ proto_tree *ssl_rsa_tree;
+ guint32 orig_offset;
+
+ orig_offset = offset;
+
+ modulus_len_offset = offset;
+ modulus_len = tvb_get_ntohs(tvb, offset);
+ offset += 2 + modulus_len;
+ if ((offset - orig_offset) > length) {
+ return;
+ }
+
+ exponent_len_offset = offset;
+ exponent_len = tvb_get_ntohs(tvb, offset);
+ offset += 2 + exponent_len;
+ if ((offset - orig_offset) > length) {
+ return;
+ }
+
+ sig_len_offset = offset;
+ sig_len = tvb_get_ntohs(tvb, offset);
+ offset += 2 + sig_len;
+ if ((offset - orig_offset) != length) {
+ /* Lengths don't line up (wasn't what we expected?) */
+ return;
+ }
+
+ ti_rsa = proto_tree_add_text(tree, tvb, orig_offset,
+ (offset - orig_offset), "RSA-EXPORT Server Params");
+ ssl_rsa_tree = proto_item_add_subtree(ti_rsa, ett_ssl_keyex_params);
+
+ /* modulus */
+ proto_tree_add_uint(ssl_rsa_tree, hf_ssl_handshake_server_keyex_modulus_len,
+ tvb, modulus_len_offset, 2, modulus_len);
+ proto_tree_add_item(ssl_rsa_tree, hf_ssl_handshake_server_keyex_modulus,
+ tvb, modulus_len_offset + 2, modulus_len, ENC_NA);
+
+ /* exponent */
+ proto_tree_add_uint(ssl_rsa_tree, hf_ssl_handshake_server_keyex_exponent_len,
+ tvb, exponent_len_offset, 2, exponent_len);
+ proto_tree_add_item(ssl_rsa_tree, hf_ssl_handshake_server_keyex_exponent,
+ tvb, exponent_len_offset + 2, exponent_len, ENC_NA);
+
+ /* Sig */
+ proto_tree_add_uint(ssl_rsa_tree, hf_ssl_handshake_server_keyex_sig_len,
+ tvb, sig_len_offset, 2, sig_len);
+ proto_tree_add_item(ssl_rsa_tree, hf_ssl_handshake_server_keyex_sig,
+ tvb, sig_len_offset + 2, sig_len, ENC_NA);
}
+
static void
dissect_ssl3_hnd_cli_keyex_dh(tvbuff_t *tvb, proto_tree *tree,
guint32 offset, guint32 length)
@@ -2809,26 +3017,56 @@ dissect_ssl3_hnd_cli_keyex_dh(tvbuff_t *tvb, proto_tree *tree,
proto_item *ti_dh;
proto_tree *ssl_dh_tree;
guint32 orig_offset;
-
+
orig_offset = offset;
-
+
yc_len_offset = offset;
yc_len = tvb_get_ntohs(tvb, offset);
offset += 2 + yc_len;
if ((offset - orig_offset) != length) {
return;
}
-
- ti_dh = proto_tree_add_text(tree, tvb, orig_offset,
+
+ ti_dh = proto_tree_add_text(tree, tvb, orig_offset,
(offset - orig_offset), "Diffie-Hellman Client Params");
ssl_dh_tree = proto_item_add_subtree(ti_dh, ett_ssl_keyex_params);
-
- /* Yc */
+
+ /* encrypted PreMaster secret */
proto_tree_add_uint(ssl_dh_tree, hf_ssl_handshake_client_keyex_yc_len,
tvb, yc_len_offset, 2, yc_len);
proto_tree_add_item(ssl_dh_tree, hf_ssl_handshake_client_keyex_yc,
tvb, yc_len_offset + 2, yc_len, ENC_NA);
}
+
+static void
+dissect_ssl3_hnd_cli_keyex_rsa(tvbuff_t *tvb, proto_tree *tree,
+ guint32 offset, guint32 length)
+{
+ gint epms_len, epms_len_offset;
+ proto_item *ti_rsa;
+ proto_tree *ssl_rsa_tree;
+ guint32 orig_offset;
+
+ orig_offset = offset;
+
+ epms_len_offset = offset;
+ epms_len = tvb_get_ntohs(tvb, offset);
+ offset += 2 + epms_len;
+ if ((offset - orig_offset) != length) {
+ return;
+ }
+
+ ti_rsa = proto_tree_add_text(tree, tvb, orig_offset,
+ (offset - orig_offset), "RSA Encrypted PreMaster Secret");
+ ssl_rsa_tree = proto_item_add_subtree(ti_rsa, ett_ssl_keyex_params);
+
+ /* Yc */
+ proto_tree_add_uint(ssl_rsa_tree, hf_ssl_handshake_client_keyex_epms_len,
+ tvb, epms_len_offset, 2, epms_len);
+ proto_tree_add_item(ssl_rsa_tree, hf_ssl_handshake_client_keyex_epms,
+ tvb, epms_len_offset + 2, epms_len, ENC_NA);
+}
+
@@ -4648,6 +4886,36 @@ proto_register_ssl(void)
FT_UINT16, BASE_DEC, NULL, 0x0,
"Length of client's Diffie-Hellman public key", HFILL }
},
+ { &hf_ssl_handshake_client_keyex_point_len,
+ { "Pubkey Length", "ssl.handshake.client_point_len",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "Length of client's EC Diffie-Hellman public key", HFILL }
+ },
+ { &hf_ssl_handshake_server_keyex_point_len,
+ { "Pubkey Length", "ssl.handshake.server_point_len",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "Length of server's EC Diffie-Hellman public key", HFILL }
+ },
+ { &hf_ssl_handshake_client_keyex_epms_len,
+ { "Encrypted PreMaster length", "ssl.handshake.epms_len",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "Length of encrypted PreMaster secret", HFILL }
+ },
+ { &hf_ssl_handshake_client_keyex_epms,
+ { "Encrypted PreMaster", "ssl.handshake.epms",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ "Encrypted PreMaster secret", HFILL }
+ },
+ { &hf_ssl_handshake_server_keyex_modulus_len,
+ { "modulus Length", "ssl.handshake.modulus_len",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "Length of RSA-EXPORT modulus", HFILL }
+ },
+ { &hf_ssl_handshake_server_keyex_exponent_len,
+ { "exponent Length", "ssl.handshake.exponent_len",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "Length of RSA-EXPORT exponent", HFILL }
+ },
{ &hf_ssl_handshake_server_keyex_sig_len,
{ "Signature Length", "ssl.handshake.sig_len",
FT_UINT16, BASE_DEC, NULL, 0x0,
@@ -4663,6 +4931,16 @@ proto_register_ssl(void)
FT_BYTES, BASE_NONE, NULL, 0x0,
"Diffie-Hellman g", HFILL }
},
+ { &hf_ssl_handshake_server_keyex_curve_type,
+ { "curve_type", "ssl.handshake.server_curve_type",
+ FT_UINT8, BASE_HEX, VALS(ssl_curve_types), 0x0,
+ "Server curve_type", HFILL }
+ },
+ { &hf_ssl_handshake_server_keyex_named_curve,
+ { "named_curve", "ssl.handshake.server_named_curve",
+ FT_UINT16, BASE_HEX, VALS(ssl_extension_curves), 0x0,
+ "Server named_curve", HFILL }
+ },
{ &hf_ssl_handshake_server_keyex_ys,
{ "pubkey", "ssl.handshake.ys",
FT_BYTES, BASE_NONE, NULL, 0x0,
@@ -4673,6 +4951,26 @@ proto_register_ssl(void)
FT_BYTES, BASE_NONE, NULL, 0x0,
"Diffie-Hellman client pubkey", HFILL }
},
+ { &hf_ssl_handshake_server_keyex_point,
+ { "pubkey", "ssl.handshake.server_point",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ "EC Diffie-Hellman server pubkey", HFILL }
+ },
+ { &hf_ssl_handshake_client_keyex_point,
+ { "pubkey", "ssl.handshake.client_point",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ "EC Diffie-Hellman client pubkey", HFILL }
+ },
+ { &hf_ssl_handshake_server_keyex_modulus,
+ { "modulus", "ssl.handshake.modulus",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ "RSA-EXPORT modulus", HFILL }
+ },
+ { &hf_ssl_handshake_server_keyex_exponent,
+ { "exponent", "ssl.handshake.exponent",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ "RSA-EXPORT exponent", HFILL }
+ },
{ &hf_ssl_handshake_server_keyex_sig,
{ "signature", "ssl.handshake.sig",
FT_BYTES, BASE_NONE, NULL, 0x0,
@@ -4954,6 +5252,7 @@ proto_register_ssl(void)
&ett_ssl_keyex_params,
&ett_ssl_cert_status,
&ett_ssl_ocsp_resp,
+ &ett_ssl_keyex_params,
&ett_pct_cipher_suites,
&ett_pct_hash_suites,
&ett_pct_cert_suites,