aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ssl.c
diff options
context:
space:
mode:
authorMichael Tüxen <tuexen@fh-muenster.de>2012-02-26 13:50:52 +0000
committerMichael Tüxen <tuexen@fh-muenster.de>2012-02-26 13:50:52 +0000
commite929fdfdeef753a8844bf3075f824926fd1244db (patch)
tree70e56fe559911b22da16a0717584f3b7ade97fbb /epan/dissectors/packet-ssl.c
parent83bf13e1e609e3fa3a935876e707aecfda4635de (diff)
From Robin Seggelmann: Add support for RFC 6520.
From me: Some cleanup Initial work was done by Denis Jaeger and Lukas Scharlau, but the code got rewritten by Robin. svn path=/trunk/; revision=41189
Diffstat (limited to 'epan/dissectors/packet-ssl.c')
-rw-r--r--epan/dissectors/packet-ssl.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/epan/dissectors/packet-ssl.c b/epan/dissectors/packet-ssl.c
index 87c04065ca..0abf6d48bf 100644
--- a/epan/dissectors/packet-ssl.c
+++ b/epan/dissectors/packet-ssl.c
@@ -254,11 +254,19 @@ static int hf_ssl_segment_too_long_fragment = -1;
static int hf_ssl_segment_error = -1;
static int hf_ssl_segment_count = -1;
+static gint hf_ssl_heartbeat_extension_mode = -1;
+static gint hf_ssl_heartbeat_message = -1;
+static gint hf_ssl_heartbeat_message_type = -1;
+static gint hf_ssl_heartbeat_message_payload_length = -1;
+static gint hf_ssl_heartbeat_message_payload = -1;
+static gint hf_ssl_heartbeat_message_padding = -1;
+
/* Initialize the subtree pointers */
static gint ett_ssl = -1;
static gint ett_ssl_record = -1;
static gint ett_ssl_alert = -1;
static gint ett_ssl_handshake = -1;
+static gint ett_ssl_heartbeat = -1;
static gint ett_ssl_cipher_suites = -1;
static gint ett_ssl_comp_methods = -1;
static gint ett_ssl_extension = -1;
@@ -455,6 +463,11 @@ static void dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo,
guint *conv_version, guint conv_cipher,
SslDecryptSession *conv_data, const guint8 content_type);
+/* heartbeat message dissector */
+static void dissect_ssl3_heartbeat(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *tree, guint32 offset,
+ guint *conv_version, guint32 record_length);
+
/* hello extension dissector */
static gint dissect_ssl3_hnd_hello_ext_elliptic_curves(tvbuff_t *tvb,
proto_tree *tree, guint32 offset);
@@ -1659,6 +1672,25 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo,
dissect_ssl_payload(tvb, pinfo, offset, tree, association);
break;
+ case SSL_ID_HEARTBEAT:
+ {
+ tvbuff_t* decrypted;
+
+ if (ssl && decrypt_ssl3_record(tvb, pinfo, offset,
+ record_length, content_type, ssl, FALSE))
+ ssl_add_record_info(proto_ssl, pinfo, ssl_decrypted_data.data,
+ ssl_decrypted_data_avail, offset);
+
+ /* try to retrieve and use decrypted handshake record, if any. */
+ decrypted = ssl_get_record_info(tvb, proto_ssl, pinfo, offset);
+ if (decrypted) {
+ add_new_data_source(pinfo, decrypted, "Decrypted SSL record");
+ dissect_ssl3_heartbeat(decrypted, pinfo, ssl_record_tree, 0, conv_version, record_length);
+ } else {
+ dissect_ssl3_heartbeat(tvb, pinfo, ssl_record_tree, offset, conv_version, record_length);
+ }
+ break;
+ }
default:
/* shouldn't get here since we check above for valid types */
@@ -2107,6 +2139,86 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo,
}
}
+/* dissects the heartbeat message, filling in the tree */
+static void
+dissect_ssl3_heartbeat(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *tree, guint32 offset,
+ guint* conv_version, guint32 record_length)
+{
+ /* struct {
+ * HeartbeatMessageType type;
+ * uint16 payload_length;
+ * opaque payload;
+ * opaque padding;
+ * } HeartbeatMessage;
+ */
+
+ proto_tree *ti;
+ proto_tree *tls_heartbeat_tree;
+ const gchar *type;
+ guint8 byte;
+ guint16 payload_length;
+ guint16 padding_length;
+
+ tls_heartbeat_tree = NULL;
+
+ if (tree) {
+ ti = proto_tree_add_item(tree, hf_ssl_heartbeat_message, tvb,
+ offset, record_length - 32, ENC_NA);
+ tls_heartbeat_tree = proto_item_add_subtree(ti, ett_ssl_heartbeat);
+ }
+
+ /*
+ * set the record layer label
+ */
+
+ /* first lookup the names for the message type and the payload length */
+ byte = tvb_get_guint8(tvb, offset);
+ type = match_strval(byte, tls_heartbeat_type);
+
+ payload_length = tvb_get_ntohs(tvb, offset + 1);
+ padding_length = record_length - 3 - payload_length;
+
+ /* now set the text in the record layer line */
+ if (type && (payload_length <= record_length - 16 - 3)) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, "Heartbeat %s", type);
+ } else {
+ col_append_str(pinfo->cinfo, COL_INFO, "Encrypted Heartbeat");
+ }
+
+ if (tree) {
+ if (type && (payload_length <= record_length - 16 - 3)) {
+ proto_item_set_text(tree, "%s Record Layer: Heartbeat "
+ "%s",
+ val_to_str_const(*conv_version, ssl_version_short_names, "SSL"),
+ type);
+ proto_tree_add_item(tls_heartbeat_tree, hf_ssl_heartbeat_message_type,
+ tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ proto_tree_add_uint(tls_heartbeat_tree, hf_ssl_heartbeat_message_payload_length,
+ tvb, offset, 2, payload_length);
+ offset += 2;
+ proto_tree_add_bytes_format(tls_heartbeat_tree, hf_ssl_heartbeat_message_payload,
+ tvb, offset, payload_length,
+ NULL, "Payload (%u byte%s)",
+ payload_length,
+ plurality(payload_length, "", "s"));
+ offset += payload_length;
+ proto_tree_add_bytes_format(tls_heartbeat_tree, hf_ssl_heartbeat_message_padding,
+ tvb, offset, padding_length,
+ NULL, "Padding and HMAC (%u byte%s)",
+ padding_length,
+ plurality(padding_length, "", "s"));
+ } else {
+ proto_item_set_text(tree,
+ "%s Record Layer: Encrypted Heartbeat",
+ val_to_str_const(*conv_version, ssl_version_short_names, "SSL"));
+ proto_item_set_text(tls_heartbeat_tree,
+ "Encrypted Heartbeat Message");
+ }
+ }
+}
+
static gint
dissect_ssl3_hnd_hello_common(tvbuff_t *tvb, proto_tree *tree,
guint32 offset, SslDecryptSession* ssl, gint from_server)
@@ -2233,6 +2345,10 @@ 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_HEARTBEAT:
+ proto_tree_add_item(ext_tree, hf_ssl_heartbeat_extension_mode,
+ tvb, offset, 1, ENC_BIG_ENDIAN);
+ break;
default:
proto_tree_add_bytes_format(ext_tree, hf_ssl_handshake_extension_data,
tvb, offset, ext_len, NULL,
@@ -5064,6 +5180,33 @@ proto_register_ssl(void)
FT_NONE, BASE_NONE, NULL, 0x0,
"Distinguished name of a CA that server trusts", HFILL }
},
+ { &hf_ssl_heartbeat_extension_mode,
+ { "Mode", "ssl.handshake.extension.heartbeat.mode",
+ FT_UINT8, BASE_DEC, VALS(tls_heartbeat_mode), 0x0,
+ "Heartbeat extension mode", HFILL }
+ },
+ { &hf_ssl_heartbeat_message,
+ { "Heartbeat Message", "ssl.heartbeat_message",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_ssl_heartbeat_message_type,
+ { "Type", "ssl.heartbeat_message.type",
+ FT_UINT8, BASE_DEC, VALS(tls_heartbeat_type), 0x0,
+ "Heartbeat message type", HFILL }
+ },
+ { &hf_ssl_heartbeat_message_payload_length,
+ { "Payload Length", "ssl.heartbeat_message.payload_length",
+ FT_UINT16, BASE_DEC, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_ssl_heartbeat_message_payload,
+ { "Payload Length", "ssl.heartbeat_message.payload",
+ FT_BYTES, BASE_NONE, NULL, 0x00, NULL, HFILL }
+ },
+ { &hf_ssl_heartbeat_message_padding,
+ { "Payload Length", "ssl.heartbeat_message.padding",
+ FT_BYTES, BASE_NONE, NULL, 0x00, NULL, HFILL }
+ },
{ &hf_ssl2_handshake_challenge,
{ "Challenge", "ssl.handshake.challenge",
FT_NONE, BASE_NONE, NULL, 0x0,
@@ -5246,6 +5389,7 @@ proto_register_ssl(void)
&ett_ssl_record,
&ett_ssl_alert,
&ett_ssl_handshake,
+ &ett_ssl_heartbeat,
&ett_ssl_cipher_suites,
&ett_ssl_comp_methods,
&ett_ssl_extension,