diff options
author | Peter Wu <peter@lekensteyn.nl> | 2017-01-30 05:25:11 +0100 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2017-01-31 14:54:22 +0000 |
commit | 69ee6ec3d8e33c860d0c9e16bcfa4401ce506d8e (patch) | |
tree | a29d8c0d1362f14f54a1f57f621d57daf1968a9a | |
parent | aaa655106af794258215b97292abd4452d21b6fa (diff) | |
download | wireshark-69ee6ec3d8e33c860d0c9e16bcfa4401ce506d8e.tar.gz |
TLS13: handle content type from decrypted record
Extract the content type and handle padding per
https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-5.2
When TLS 1.3 is detected, rename the "Content Type" field to "Opaque
[Content] Type" and add a new generated field for the content type that
was extracted from the decrypted contents.
Change-Id: I149a5d7e2493dded6e2c0190e170fa350f76466e
Ping-Bug: 12779
Reviewed-on: https://code.wireshark.org/review/19859
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
-rw-r--r-- | epan/dissectors/packet-ssl.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/epan/dissectors/packet-ssl.c b/epan/dissectors/packet-ssl.c index b146f2ed8e..7e9bd5376f 100644 --- a/epan/dissectors/packet-ssl.c +++ b/epan/dissectors/packet-ssl.c @@ -126,6 +126,7 @@ static gint exported_pdu_tap = -1; static gint proto_ssl = -1; static gint hf_ssl_record = -1; static gint hf_ssl_record_content_type = -1; +static gint hf_ssl_record_opaque_type = -1; static gint hf_ssl_record_version = -1; static gint hf_ssl_record_length = -1; static gint hf_ssl_record_appdata = -1; @@ -934,7 +935,25 @@ decrypt_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, guint32 offset, SslDecryp const guchar *data = ssl_decrypted_data.data; guint datalen = ssl_decrypted_data_avail; - // XXX extract content type, check padding + if (ssl->session.version == TLSV1DOT3_VERSION) { + /* + * The actual data is followed by the content type and then zero or + * more padding. Scan backwards for content type, skipping padding. + */ + while (datalen > 0 && data[datalen - 1] == 0) { + datalen--; + } + ssl_debug_printf("%s found %d padding bytes\n", G_STRFUNC, ssl_decrypted_data_avail - datalen); + if (datalen == 0) { + ssl_debug_printf("%s there is no room for content type!\n", G_STRFUNC); + return FALSE; + } + content_type = data[--datalen]; + if (datalen == 0) { + /* XXX should we remember that the decrypted contents was zero-length? */ + return FALSE; + } + } /* In TLS 1.3 only Handshake and Application Data can be fragmented. * Alert messages MUST NOT be fragmented across records, so do not @@ -1529,6 +1548,7 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ti; proto_tree *ssl_record_tree; proto_item *pi, *ct_pi; + guint content_type_offset; guint32 available_bytes; tvbuff_t *decrypted; SslRecordInfo *record = NULL; @@ -1644,8 +1664,14 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, ssl_record_tree = proto_item_add_subtree(ti, ett_ssl_record); /* show the one-byte content type */ - ct_pi = proto_tree_add_item(ssl_record_tree, hf_ssl_record_content_type, - tvb, offset, 1, ENC_BIG_ENDIAN); + if (session->version == TLSV1DOT3_VERSION && content_type == SSL_ID_APP_DATA) { + ct_pi = proto_tree_add_item(ssl_record_tree, hf_ssl_record_opaque_type, + tvb, offset, 1, ENC_BIG_ENDIAN); + } else { + ct_pi = proto_tree_add_item(ssl_record_tree, hf_ssl_record_content_type, + tvb, offset, 1, ENC_BIG_ENDIAN); + } + content_type_offset = offset; offset++; /* add the version */ @@ -1694,8 +1720,10 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, /* try to decrypt record on the first pass, if possible. Store decrypted * record for later usage (without having to decrypt again). The offset is * used as 'key' to identify this record in the packet (we can have multiple - * handshake records in the same frame). */ - if (ssl) { + * handshake records in the same frame). + * In TLS 1.3, only "Application Data" records are encrypted. + */ + if (ssl && (session->version != TLSV1DOT3_VERSION || content_type == SSL_ID_APP_DATA)) { decrypt_ssl3_record(tvb, pinfo, offset, ssl, content_type, record_version, record_length, content_type == SSL_ID_APP_DATA || @@ -1705,6 +1733,12 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, decrypted = ssl_get_record_info(tvb, proto_ssl, pinfo, tvb_raw_offset(tvb)+offset, &record); if (decrypted) { add_new_data_source(pinfo, decrypted, "Decrypted SSL"); + if (session->version == TLSV1DOT3_VERSION) { + content_type = record->type; + ti = proto_tree_add_uint(ssl_record_tree, hf_ssl_record_content_type, + tvb, content_type_offset, 1, record->type); + PROTO_ITEM_SET_GENERATED(ti); + } } switch ((ContentType) content_type) { @@ -3742,6 +3776,11 @@ proto_register_ssl(void) FT_UINT8, BASE_DEC, VALS(ssl_31_content_type), 0x0, NULL, HFILL} }, + { &hf_ssl_record_opaque_type, + { "Opaque Type", "ssl.record.opaque_type", + FT_UINT8, BASE_DEC, VALS(ssl_31_content_type), 0x0, + "Always set to value 23, actual content type is known after decryption", HFILL} + }, { &hf_ssl2_msg_type, { "Handshake Message Type", "ssl.handshake.type", FT_UINT8, BASE_DEC, VALS(ssl_20_msg_types), 0x0, |