summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-dtls.c43
-rw-r--r--epan/dissectors/packet-ssl-utils.c49
-rw-r--r--epan/dissectors/packet-ssl-utils.h24
-rw-r--r--epan/dissectors/packet-ssl.c44
4 files changed, 81 insertions, 79 deletions
diff --git a/epan/dissectors/packet-dtls.c b/epan/dissectors/packet-dtls.c
index f90e9cab4c..900aed3b09 100644
--- a/epan/dissectors/packet-dtls.c
+++ b/epan/dissectors/packet-dtls.c
@@ -87,7 +87,6 @@ static gint hf_dtls_record_epoch = -1;
static gint hf_dtls_record_sequence_number = -1;
static gint hf_dtls_record_length = -1;
static gint hf_dtls_record_appdata = -1;
-static gint hf_dtls_change_cipher_spec = -1;
static gint hf_dtls_alert_message = -1;
static gint hf_dtls_alert_message_level = -1;
static gint hf_dtls_alert_message_description = -1;
@@ -287,12 +286,6 @@ static gint dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo,
SslSession *session, gint is_from_server,
SslDecryptSession *conv_data);
-/* change cipher spec dissector */
-static void dissect_dtls_change_cipher_spec(tvbuff_t *tvb,
- proto_tree *tree,
- guint32 offset,
- const SslSession *session, guint8 content_type);
-
/* alert message dissector */
static void dissect_dtls_alert(tvbuff_t *tvb, packet_info *pinfo,
proto_tree *tree, guint32 offset,
@@ -802,8 +795,9 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo,
switch ((ContentType) content_type) {
case SSL_ID_CHG_CIPHER_SPEC:
col_append_str(pinfo->cinfo, COL_INFO, "Change Cipher Spec");
- dissect_dtls_change_cipher_spec(tvb, dtls_record_tree,
- offset, session, content_type);
+ ssl_dissect_change_cipher_spec(&dissect_dtls_hf, tvb, pinfo,
+ dtls_record_tree, offset, session,
+ is_from_server, ssl);
if (ssl) {
ssl_load_keyfile(dtls_options.keylog_filename, &dtls_keylog_file,
&dtls_master_key_map);
@@ -971,29 +965,6 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo,
return offset;
}
-/* dissects the change cipher spec protocol, filling in the tree */
-static void
-dissect_dtls_change_cipher_spec(tvbuff_t *tvb,
- proto_tree *tree, guint32 offset,
- const SslSession *session, guint8 content_type)
-{
- /*
- * struct {
- * enum { change_cipher_spec(1), (255) } type;
- * } ChangeCipherSpec;
- *
- */
- if (tree)
- {
- proto_item_set_text(tree,
- "%s Record Layer: %s Protocol: Change Cipher Spec",
- val_to_str_const(session->version, ssl_version_short_names, "SSL"),
- val_to_str_const(content_type, ssl_31_content_type, "unknown"));
- proto_tree_add_item(tree, hf_dtls_change_cipher_spec, tvb,
- offset, 1, ENC_NA);
- }
-}
-
/* dissects the alert message, filling in the tree */
static void
dissect_dtls_alert(tvbuff_t *tvb, packet_info *pinfo,
@@ -1366,7 +1337,8 @@ dissect_dtls_handshake(tvbuff_t *tvb, packet_info *pinfo,
break;
case SSL_HND_SVR_HELLO_DONE:
- /* server_hello_done has no fields, so nothing to do! */
+ if (ssl)
+ ssl->state |= SSL_SERVER_HELLO_DONE;
break;
case SSL_HND_CERT_VERIFY:
@@ -1700,11 +1672,6 @@ proto_register_dtls(void)
FT_BYTES, BASE_NONE, NULL, 0x0,
"Payload is encrypted application data", HFILL }
},
- { &hf_dtls_change_cipher_spec,
- { "Change Cipher Spec Message", "dtls.change_cipher_spec",
- FT_NONE, BASE_NONE, NULL, 0x0,
- "Signals a change in cipher specifications", HFILL }
- },
{ & hf_dtls_alert_message,
{ "Alert Message", "dtls.alert_message",
FT_NONE, BASE_NONE, NULL, 0x0,
diff --git a/epan/dissectors/packet-ssl-utils.c b/epan/dissectors/packet-ssl-utils.c
index bc81fb49b2..41a021edb7 100644
--- a/epan/dissectors/packet-ssl-utils.c
+++ b/epan/dissectors/packet-ssl-utils.c
@@ -4976,6 +4976,55 @@ ssldecrypt_uat_fld_password_chk_cb(void *r _U_, const char *p _U_, guint len _U_
/** Begin of code related to dissection of wire data. */
+/* change_cipher_spec(20) dissection */
+void
+ssl_dissect_change_cipher_spec(ssl_common_dissect_t *hf, tvbuff_t *tvb,
+ packet_info *pinfo, proto_tree *tree,
+ guint32 offset, SslSession *session,
+ gboolean is_from_server,
+ const SslDecryptSession *ssl)
+{
+ /*
+ * struct {
+ * enum { change_cipher_spec(1), (255) } type;
+ * } ChangeCipherSpec;
+ */
+ proto_item *ti;
+ proto_item_set_text(tree,
+ "%s Record Layer: %s Protocol: Change Cipher Spec",
+ val_to_str_const(session->version, ssl_version_short_names, "SSL"),
+ val_to_str_const(SSL_ID_CHG_CIPHER_SPEC, ssl_31_content_type, "unknown"));
+ ti = proto_tree_add_item(tree, hf->hf.change_cipher_spec, tvb, offset, 1, ENC_NA);
+
+ /* Use heuristics to detect an abbreviated handshake, assume that missing
+ * ServerHelloDone implies reusing previously negotiating keys. Then when
+ * a Session ID or ticket is present, it must be a resumed session.
+ * Normally this should be done at the Finished message, but that may be
+ * encrypted so we do it here, at the last cleartext message. */
+ if (is_from_server && ssl) {
+ if (!(ssl->state & SSL_SERVER_HELLO_DONE)) {
+ const char *resumed = NULL;
+ if (ssl->session_ticket.data_len) {
+ resumed = "Session Ticket";
+ } else if (ssl->session_id.data_len) {
+ resumed = "Session ID";
+ }
+ if (resumed) {
+ ssl_debug_printf("%s Session resumption using %s\n", G_STRFUNC, resumed);
+ session->is_session_resumed = TRUE;
+ } else {
+ /* Can happen if the capture somehow starts in the middle */
+ ssl_debug_printf("%s No Session resumption, missing packets?\n", G_STRFUNC);
+ }
+ } else {
+ ssl_debug_printf("%s Not using Session resumption\n", G_STRFUNC);
+ }
+ }
+ if (is_from_server && session->is_session_resumed)
+ expert_add_info(pinfo, ti, &hf->ei.resumed);
+}
+
+/** Begin of handshake(22) record dissections */
/* 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. {{{ */
diff --git a/epan/dissectors/packet-ssl-utils.h b/epan/dissectors/packet-ssl-utils.h
index 4e3be07eea..f7a2496759 100644
--- a/epan/dissectors/packet-ssl-utils.h
+++ b/epan/dissectors/packet-ssl-utils.h
@@ -236,6 +236,7 @@ typedef struct _StringInfo {
#define SSL_PRE_MASTER_SECRET (1<<6)
#define SSL_CLIENT_EXTENDED_MASTER_SECRET (1<<7)
#define SSL_SERVER_EXTENDED_MASTER_SECRET (1<<8)
+#define SSL_SERVER_HELLO_DONE (1<<9)
#define SSL_EXTENDED_MASTER_SECRET_MASK (SSL_CLIENT_EXTENDED_MASTER_SECRET|SSL_SERVER_EXTENDED_MASTER_SECRET)
@@ -368,6 +369,7 @@ typedef struct _SslSession {
/* The Application layer protocol if known (for STARTTLS support) */
dissector_handle_t app_handle;
guint32 last_nontls_frame;
+ gboolean is_session_resumed;
} SslSession;
/* RFC 5246, section 8.1 says that the master secret is always 48 bytes */
@@ -613,6 +615,7 @@ ssl_calculate_handshake_hash(SslDecryptSession *ssl_session, tvbuff_t *tvb, guin
/* common header fields, subtrees and expert info for SSL and DTLS dissectors */
typedef struct ssl_common_dissect {
struct {
+ gint change_cipher_spec;
gint hs_exts_len;
gint hs_ext_alpn_len;
gint hs_ext_alpn_list;
@@ -744,6 +747,7 @@ typedef struct ssl_common_dissect {
expert_field hs_sig_hash_alg_len_bad;
expert_field hs_cipher_suites_len_bad;
expert_field hs_sig_hash_algs_bad;
+ expert_field resumed;
/* do not forget to update SSL_COMMON_LIST_T and SSL_COMMON_EI_LIST! */
} ei;
@@ -765,6 +769,13 @@ typedef struct {
/* Do not forget to initialize ssl_hfs to -1 in packet-ssl.c! */
} ssl_hfs_t;
+void
+ssl_dissect_change_cipher_spec(ssl_common_dissect_t *hf, tvbuff_t *tvb,
+ packet_info *pinfo, proto_tree *tree,
+ guint32 offset, SslSession *session,
+ gboolean is_from_server,
+ const SslDecryptSession *ssl);
+
extern void
ssl_dissect_hnd_cli_hello(ssl_common_dissect_t *hf, tvbuff_t *tvb,
packet_info *pinfo, proto_tree *tree, guint32 offset,
@@ -827,20 +838,25 @@ ssl_common_dissect_t name = { \
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \
- -1, -1, -1 \
+ -1, -1, -1, -1, \
}, \
/* ett */ { \
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, \
-1, -1, -1, -1, \
}, \
/* ei */ { \
- EI_INIT, EI_INIT, EI_INIT, EI_INIT, \
+ EI_INIT, EI_INIT, EI_INIT, EI_INIT, EI_INIT, \
}, \
}
/* }}} */
/* {{{ */
#define SSL_COMMON_HF_LIST(name, prefix) \
+ { & name .hf.change_cipher_spec, \
+ { "Change Cipher Spec Message", prefix ".change_cipher_spec", \
+ FT_NONE, BASE_NONE, NULL, 0x0, \
+ "Signals a change in cipher specifications", HFILL } \
+ }, \
{ & name .hf.hs_exts_len, \
{ "Extensions Length", prefix ".handshake.extensions_length", \
FT_UINT16, BASE_DEC, NULL, 0x0, \
@@ -1380,6 +1396,10 @@ ssl_common_dissect_t name = { \
{ & name .ei.hs_sig_hash_algs_bad, \
{ prefix ".handshake.sig_hash_algs.mult2", PI_MALFORMED, PI_ERROR, \
"Hash Algorithm length must be a multiple of 2", EXPFILL } \
+ }, \
+ { & name .ei.resumed, \
+ { prefix ".resumed", PI_SEQUENCE, PI_NOTE, \
+ "This session reuses previously negotiated keys (Session resumption)", EXPFILL } \
}
/* }}} */
diff --git a/epan/dissectors/packet-ssl.c b/epan/dissectors/packet-ssl.c
index 1e5b95c23c..ae9daf8956 100644
--- a/epan/dissectors/packet-ssl.c
+++ b/epan/dissectors/packet-ssl.c
@@ -127,7 +127,6 @@ static gint hf_ssl2_record_is_escape = -1;
static gint hf_ssl2_record_padding_length = -1;
static gint hf_ssl2_msg_type = -1;
static gint hf_pct_msg_type = -1;
-static gint hf_ssl_change_cipher_spec = -1;
static gint hf_ssl_alert_message = -1;
static gint hf_ssl_alert_message_level = -1;
static gint hf_ssl_alert_message_description = -1;
@@ -493,12 +492,6 @@ static gint dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo,
SslDecryptSession *conv_data,
const gboolean first_record_in_frame);
-/* change cipher spec dissector */
-static void dissect_ssl3_change_cipher_spec(tvbuff_t *tvb,
- proto_tree *tree,
- guint32 offset,
- const SslSession *session, const guint8 content_type);
-
/* alert message dissector */
static void dissect_ssl3_alert(tvbuff_t *tvb, packet_info *pinfo,
proto_tree *tree, guint32 offset,
@@ -1638,10 +1631,10 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo,
switch ((ContentType) content_type) {
case SSL_ID_CHG_CIPHER_SPEC:
- ssl_debug_printf("dissect_ssl3_change_cipher_spec\n");
col_append_str(pinfo->cinfo, COL_INFO, "Change Cipher Spec");
- dissect_ssl3_change_cipher_spec(tvb, ssl_record_tree,
- offset, session, content_type);
+ ssl_dissect_change_cipher_spec(&dissect_ssl3_hf, tvb, pinfo,
+ ssl_record_tree, offset, session,
+ is_from_server, ssl);
if (ssl) {
ssl_load_keyfile(ssl_options.keylog_filename, &ssl_keylog_file,
&ssl_master_key_map);
@@ -1771,29 +1764,6 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo,
return offset;
}
-/* dissects the change cipher spec procotol, filling in the tree */
-static void
-dissect_ssl3_change_cipher_spec(tvbuff_t *tvb,
- proto_tree *tree, guint32 offset,
- const SslSession *session, const guint8 content_type)
-{
- /*
- * struct {
- * enum { change_cipher_spec(1), (255) } type;
- * } ChangeCipherSpec;
- *
- */
- if (tree)
- {
- proto_item_set_text(tree,
- "%s Record Layer: %s Protocol: Change Cipher Spec",
- val_to_str_const(session->version, ssl_version_short_names, "SSL"),
- val_to_str_const(content_type, ssl_31_content_type, "unknown"));
- proto_tree_add_item(tree, hf_ssl_change_cipher_spec, tvb,
- offset++, 1, ENC_NA);
- }
-}
-
/* dissects the alert message, filling in the tree */
static void
dissect_ssl3_alert(tvbuff_t *tvb, packet_info *pinfo,
@@ -2040,7 +2010,8 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo,
break;
case SSL_HND_SVR_HELLO_DONE:
- /* server_hello_done has no fields, so nothing to do! */
+ if (ssl)
+ ssl->state |= SSL_SERVER_HELLO_DONE;
break;
case SSL_HND_CERT_VERIFY:
@@ -3744,11 +3715,6 @@ proto_register_ssl(void)
FT_UINT8, BASE_DEC, NULL, 0x0,
"Length of padding at end of record", HFILL }
},
- { &hf_ssl_change_cipher_spec,
- { "Change Cipher Spec Message", "ssl.change_cipher_spec",
- FT_NONE, BASE_NONE, NULL, 0x0,
- "Signals a change in cipher specifications", HFILL }
- },
{ &hf_ssl_alert_message,
{ "Alert Message", "ssl.alert_message",
FT_NONE, BASE_NONE, NULL, 0x0,