forked from osmocom/wireshark
From Eric Wustrow:
TLS Diffie-Hellman key exchange dissection support. https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6277 svn path=/trunk/; revision=38858
This commit is contained in:
parent
3cc9cabaa0
commit
af65dc50ab
|
@ -191,6 +191,16 @@ static gint hf_ssl_handshake_certificate_len = -1;
|
|||
static gint hf_ssl_handshake_cert_types_count = -1;
|
||||
static gint hf_ssl_handshake_cert_types = -1;
|
||||
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_client_keyex_yc_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_sig = -1;
|
||||
static gint hf_ssl_handshake_sig_hash_alg_len = -1;
|
||||
static gint hf_ssl_handshake_sig_hash_algs = -1;
|
||||
static gint hf_ssl_handshake_sig_hash_alg = -1;
|
||||
|
@ -260,6 +270,7 @@ static gint ett_ssl_sig_hash_algs = -1;
|
|||
static gint ett_ssl_sig_hash_alg = -1;
|
||||
static gint ett_ssl_dnames = -1;
|
||||
static gint ett_ssl_random = -1;
|
||||
static gint ett_ssl_keyex_params = -1;
|
||||
static gint ett_ssl_cert_status = -1;
|
||||
static gint ett_ssl_ocsp_resp = -1;
|
||||
static gint ett_pct_cipher_suites = -1;
|
||||
|
@ -411,7 +422,7 @@ ssl_parse(void)
|
|||
/* record layer dissector */
|
||||
static gint dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo,
|
||||
proto_tree *tree, guint32 offset,
|
||||
guint *conv_version,
|
||||
guint *conv_version, guint conv_cipher,
|
||||
gboolean *need_desegmentation,
|
||||
SslDecryptSession *conv_data,
|
||||
const gboolean first_record_in_frame);
|
||||
|
@ -431,7 +442,7 @@ static void dissect_ssl3_alert(tvbuff_t *tvb, packet_info *pinfo,
|
|||
static void dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo,
|
||||
proto_tree *tree, guint32 offset,
|
||||
guint32 record_length,
|
||||
guint *conv_version,
|
||||
guint *conv_version, guint conv_cipher,
|
||||
SslDecryptSession *conv_data, const guint8 content_type);
|
||||
|
||||
/* hello extension dissector */
|
||||
|
@ -459,6 +470,14 @@ 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_dh(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_finished(tvbuff_t *tvb,
|
||||
proto_tree *tree,
|
||||
const guint32 offset,
|
||||
|
@ -555,6 +574,7 @@ dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
gboolean need_desegmentation;
|
||||
SslDecryptSession* ssl_session;
|
||||
guint* conv_version;
|
||||
guint conv_cipher;
|
||||
|
||||
ti = NULL;
|
||||
ssl_tree = NULL;
|
||||
|
@ -592,6 +612,7 @@ dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
conversation_add_proto_data(conversation, proto_ssl, ssl_session);
|
||||
}
|
||||
conv_version =& ssl_session->version;
|
||||
conv_cipher = ssl_session->cipher;
|
||||
|
||||
/* try decryption only the first time we see this packet
|
||||
* (to keep cipher synchronized) */
|
||||
|
@ -670,6 +691,7 @@ dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
{
|
||||
offset = dissect_ssl3_record(tvb, pinfo, ssl_tree,
|
||||
offset, conv_version,
|
||||
conv_cipher,
|
||||
&need_desegmentation,
|
||||
ssl_session,
|
||||
first_record_in_frame);
|
||||
|
@ -694,6 +716,7 @@ dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
/* looks like sslv3 or tls */
|
||||
offset = dissect_ssl3_record(tvb, pinfo, ssl_tree,
|
||||
offset, conv_version,
|
||||
conv_cipher,
|
||||
&need_desegmentation,
|
||||
ssl_session,
|
||||
first_record_in_frame);
|
||||
|
@ -1279,7 +1302,8 @@ dissect_ssl_payload(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *t
|
|||
static gint
|
||||
dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo,
|
||||
proto_tree *tree, guint32 offset,
|
||||
guint *conv_version, gboolean *need_desegmentation,
|
||||
guint *conv_version, guint conv_cipher,
|
||||
gboolean *need_desegmentation,
|
||||
SslDecryptSession* ssl, const gboolean first_record_in_frame)
|
||||
{
|
||||
|
||||
|
@ -1561,10 +1585,10 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo,
|
|||
/* add desegmented data to the data source list */
|
||||
add_new_data_source(pinfo, decrypted, "Decrypted SSL record");
|
||||
dissect_ssl3_handshake(decrypted, pinfo, ssl_record_tree, 0,
|
||||
tvb_length(decrypted), conv_version, ssl, content_type);
|
||||
tvb_length(decrypted), conv_version, conv_cipher, ssl, content_type);
|
||||
} else {
|
||||
dissect_ssl3_handshake(tvb, pinfo, ssl_record_tree, offset,
|
||||
record_length, conv_version, ssl, content_type);
|
||||
record_length, conv_version, conv_cipher, ssl, content_type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1711,7 +1735,7 @@ dissect_ssl3_alert(tvbuff_t *tvb, packet_info *pinfo,
|
|||
static void
|
||||
dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo,
|
||||
proto_tree *tree, guint32 offset,
|
||||
guint32 record_length, guint *conv_version,
|
||||
guint32 record_length, guint *conv_version, guint conv_cipher,
|
||||
SslDecryptSession* ssl, const guint8 content_type)
|
||||
{
|
||||
/* struct {
|
||||
|
@ -1859,7 +1883,15 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo,
|
|||
break;
|
||||
|
||||
case SSL_HND_SERVER_KEY_EXCHG:
|
||||
/* unimplemented */
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SSL_HND_CERT_REQUEST:
|
||||
|
@ -1875,6 +1907,9 @@ 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);
|
||||
}
|
||||
{
|
||||
/* PAOLO: here we can have all the data to build session key*/
|
||||
|
||||
|
@ -2696,6 +2731,110 @@ dissect_ssl3_hnd_cert_req(tvbuff_t *tvb,
|
|||
|
||||
}
|
||||
|
||||
static void
|
||||
dissect_ssl3_hnd_srv_keyex_dh(tvbuff_t *tvb, proto_tree *tree,
|
||||
guint32 offset, guint32 length)
|
||||
{
|
||||
gint p_len, p_len_offset;
|
||||
gint g_len, g_len_offset;
|
||||
gint ys_len, ys_len_offset;
|
||||
gint sig_len, sig_len_offset;
|
||||
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;
|
||||
if ((offset - orig_offset) != length) {
|
||||
/* Lengths don't line up (wasn't what we expected?) */
|
||||
return;
|
||||
}
|
||||
|
||||
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, FALSE);
|
||||
|
||||
/* 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, FALSE);
|
||||
|
||||
/* 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, FALSE);
|
||||
|
||||
/* 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, FALSE);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
dissect_ssl3_hnd_cli_keyex_dh(tvbuff_t *tvb, proto_tree *tree,
|
||||
guint32 offset, guint32 length)
|
||||
{
|
||||
gint yc_len, yc_len_offset;
|
||||
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,
|
||||
(offset - orig_offset), "Diffie-Hellman Client Params");
|
||||
ssl_dh_tree = proto_item_add_subtree(ti_dh, ett_ssl_keyex_params);
|
||||
|
||||
/* Yc */
|
||||
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, FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
dissect_ssl3_hnd_finished(tvbuff_t *tvb,
|
||||
proto_tree *tree, const guint32 offset,
|
||||
|
@ -4492,6 +4631,56 @@ proto_register_ssl(void)
|
|||
FT_UINT8, BASE_DEC, VALS(ssl_31_client_certificate_type), 0x0,
|
||||
NULL, HFILL }
|
||||
},
|
||||
{ &hf_ssl_handshake_server_keyex_p_len,
|
||||
{ "p Length", "ssl.handshake.p_len",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x0,
|
||||
"Length of p", HFILL }
|
||||
},
|
||||
{ &hf_ssl_handshake_server_keyex_g_len,
|
||||
{ "g Length", "ssl.handshake.g_len",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x0,
|
||||
"Length of g", HFILL }
|
||||
},
|
||||
{ &hf_ssl_handshake_server_keyex_ys_len,
|
||||
{ "Pubkey Length", "ssl.handshake.ys_len",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x0,
|
||||
"Length of server's Diffie-Hellman public key", HFILL }
|
||||
},
|
||||
{ &hf_ssl_handshake_client_keyex_yc_len,
|
||||
{ "Pubkey Length", "ssl.handshake.yc_len",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x0,
|
||||
"Length of client's Diffie-Hellman public key", HFILL }
|
||||
},
|
||||
{ &hf_ssl_handshake_server_keyex_sig_len,
|
||||
{ "Signature Length", "ssl.handshake.sig_len",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x0,
|
||||
"Length of Signature", HFILL }
|
||||
},
|
||||
{ &hf_ssl_handshake_server_keyex_p,
|
||||
{ "p", "ssl.handshake.p",
|
||||
FT_BYTES, BASE_NONE, NULL, 0x0,
|
||||
"Diffie-Hellman p", HFILL }
|
||||
},
|
||||
{ &hf_ssl_handshake_server_keyex_g,
|
||||
{ "g", "ssl.handshake.g",
|
||||
FT_BYTES, BASE_NONE, NULL, 0x0,
|
||||
"Diffie-Hellman g", HFILL }
|
||||
},
|
||||
{ &hf_ssl_handshake_server_keyex_ys,
|
||||
{ "pubkey", "ssl.handshake.ys",
|
||||
FT_BYTES, BASE_NONE, NULL, 0x0,
|
||||
"Diffie-Hellman server pubkey", HFILL }
|
||||
},
|
||||
{ &hf_ssl_handshake_client_keyex_yc,
|
||||
{ "pubkey", "ssl.handshake.yc",
|
||||
FT_BYTES, BASE_NONE, NULL, 0x0,
|
||||
"Diffie-Hellman client pubkey", HFILL }
|
||||
},
|
||||
{ &hf_ssl_handshake_server_keyex_sig,
|
||||
{ "signature", "ssl.handshake.sig",
|
||||
FT_BYTES, BASE_NONE, NULL, 0x0,
|
||||
"Diffie-Hellman server signature", HFILL }
|
||||
},
|
||||
{ &hf_ssl_handshake_sig_hash_alg_len,
|
||||
{ "Signature Hash Algorithms Length", "ssl.handshake.sig_hash_alg_len",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x0,
|
||||
|
@ -4765,6 +4954,7 @@ proto_register_ssl(void)
|
|||
&ett_ssl_sig_hash_alg,
|
||||
&ett_ssl_dnames,
|
||||
&ett_ssl_random,
|
||||
&ett_ssl_keyex_params,
|
||||
&ett_ssl_cert_status,
|
||||
&ett_ssl_ocsp_resp,
|
||||
&ett_pct_cipher_suites,
|
||||
|
|
Loading…
Reference in New Issue