From dc86242e3e158adbc99371acf4c99d4e06e57a1a Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Thu, 26 Jan 2017 12:07:49 +0100 Subject: ssl-utils: recognize new TLS 1.3 keylog format Implemented by BoringSSL, an older description can be found at: https://github.com/google/boringssl/commit/e776cc29568e520aaabc83188cc7db7991f0b776 Implementation pending at OpenSSL: https://github.com/openssl/openssl/pull/2287 NSS bug (still open): https://bugzilla.mozilla.org/show_bug.cgi?id=1287711 Proposal for PicoTLS: https://github.com/h2o/picotls/issues/6 Change-Id: Ib597f48e296d286d8f6d30873ca03e7d6324a3c4 Ping-Bug: 12779 Reviewed-on: https://code.wireshark.org/review/19801 Reviewed-by: Alexis La Goutte Petri-Dish: Alexis La Goutte Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman --- epan/dissectors/packet-ssl-utils.c | 39 +++++++++++++++++++++++++++++++++++--- epan/dissectors/packet-ssl-utils.h | 6 ++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/epan/dissectors/packet-ssl-utils.c b/epan/dissectors/packet-ssl-utils.c index a0b1a75477..4e3a93e6ef 100644 --- a/epan/dissectors/packet-ssl-utils.c +++ b/epan/dissectors/packet-ssl-utils.c @@ -4561,6 +4561,10 @@ ssl_common_init(ssl_master_key_map_t *mk_map, mk_map->crandom = g_hash_table_new(ssl_hash, ssl_equal); mk_map->pre_master = g_hash_table_new(ssl_hash, ssl_equal); mk_map->pms = g_hash_table_new(ssl_hash, ssl_equal); + mk_map->tls13_client_handshake = g_hash_table_new(ssl_hash, ssl_equal); + mk_map->tls13_server_handshake = g_hash_table_new(ssl_hash, ssl_equal); + mk_map->tls13_client_appdata = g_hash_table_new(ssl_hash, ssl_equal); + mk_map->tls13_server_appdata = g_hash_table_new(ssl_hash, ssl_equal); ssl_data_alloc(decrypted_data, 32); ssl_data_alloc(compressed_data, 32); } @@ -4574,6 +4578,10 @@ ssl_common_cleanup(ssl_master_key_map_t *mk_map, FILE **ssl_keylog_file, g_hash_table_destroy(mk_map->crandom); g_hash_table_destroy(mk_map->pre_master); g_hash_table_destroy(mk_map->pms); + g_hash_table_destroy(mk_map->tls13_client_handshake); + g_hash_table_destroy(mk_map->tls13_server_handshake); + g_hash_table_destroy(mk_map->tls13_client_appdata); + g_hash_table_destroy(mk_map->tls13_server_appdata); g_free(decrypted_data->data); g_free(compressed_data->data); @@ -4823,7 +4831,14 @@ ssl_compile_keyfile_regex(void) /* Matches Client Hellos having this Client Random */ "|CLIENT_RANDOM (?" OCTET "{32}) " /* Master-Secret is given, its length is fixed */ - ")(?" OCTET "{" G_STRINGIFY(SSL_MASTER_SECRET_LENGTH) "})"; + ")(?" OCTET "{" G_STRINGIFY(SSL_MASTER_SECRET_LENGTH) "})" + "|(?" + /* TLS 1.3 Client Random to Derived Secrets mapping. */ + ":CLIENT_HANDSHAKE_TRAFFIC_SECRET (?" OCTET "{32})" + "|SERVER_HANDSHAKE_TRAFFIC_SECRET (?" OCTET "{32})" + "|CLIENT_TRAFFIC_SECRET_0 (?" OCTET "{32})" + "|SERVER_TRAFFIC_SECRET_0 (?" OCTET "{32})" + ") (?" OCTET "+)"; #undef OCTET static GRegex *regex = NULL; GError *gerr = NULL; @@ -4878,7 +4893,12 @@ ssl_load_keyfile(const gchar *ssl_keylog_filename, FILE **keylog_file, { "encrypted_pmk", mk_map->pre_master }, { "session_id", mk_map->session }, { "client_random", mk_map->crandom }, - { "client_random_pms", mk_map->pms}, + { "client_random_pms", mk_map->pms }, + /* TLS 1.3 map from Client Random to derived secret. */ + { "client_handshake", mk_map->tls13_client_handshake }, + { "server_handshake", mk_map->tls13_server_handshake }, + { "client_appdata", mk_map->tls13_client_appdata }, + { "server_appdata", mk_map->tls13_server_appdata }, }; /* no need to try if no key log file is configured. */ if (!ssl_keylog_filename || !*ssl_keylog_filename) { @@ -4912,6 +4932,15 @@ ssl_load_keyfile(const gchar *ssl_keylog_filename, FILE **keylog_file, * Where yyyy is the cleartext master secret (hex-encoded) * (This format allows non-RSA SSL connections to be decrypted, i.e. * ECDHE-RSA.) + * + * - "CLIENT_HANDSHAKE_TRAFFIC_SECRET xxxx yyyy" + * - "SERVER_HANDSHAKE_TRAFFIC_SECRET xxxx yyyy" + * - "CLIENT_TRAFFIC_SECRET_0 xxxx yyyy" + * - "SERVER_TRAFFIC_SECRET_0 xxxx yyyy" + * Where xxxx is the client_random from the ClientHello (hex-encoded) + * Where yyyy is the secret (hex-encoded) derived from the handshake or + * master secrets. (This format is introduced with TLS 1.3 and supported + * by BoringSSL, OpenSSL, etc. See bug 12779.) */ regex = ssl_compile_keyfile_regex(); if (!regex) @@ -4965,10 +4994,14 @@ ssl_load_keyfile(const gchar *ssl_keylog_filename, FILE **keylog_file, * otherwise we will use the Master Secret */ hex_pre_ms_or_ms = g_match_info_fetch_named(mi, "master_secret"); - if (hex_pre_ms_or_ms == NULL || strlen(hex_pre_ms_or_ms) == 0){ + if (hex_pre_ms_or_ms == NULL || !*hex_pre_ms_or_ms) { g_free(hex_pre_ms_or_ms); hex_pre_ms_or_ms = g_match_info_fetch_named(mi, "pms"); } + if (hex_pre_ms_or_ms == NULL || !*hex_pre_ms_or_ms) { + g_free(hex_pre_ms_or_ms); + hex_pre_ms_or_ms = g_match_info_fetch_named(mi, "derived_secret"); + } /* There is always a match, otherwise the regex is wrong. */ DISSECTOR_ASSERT(hex_pre_ms_or_ms && strlen(hex_pre_ms_or_ms)); diff --git a/epan/dissectors/packet-ssl-utils.h b/epan/dissectors/packet-ssl-utils.h index 43e408028a..b3094993f4 100644 --- a/epan/dissectors/packet-ssl-utils.h +++ b/epan/dissectors/packet-ssl-utils.h @@ -450,6 +450,12 @@ typedef struct { GHashTable *pre_master; /* First 8 bytes of encrypted pre-master secret to pre-master secret */ GHashTable *pms; /* Client Random to unencrypted pre-master secret */ + + /* For TLS 1.3: maps Client Random to derived secret. */ + GHashTable *tls13_client_handshake; + GHashTable *tls13_server_handshake; + GHashTable *tls13_client_appdata; + GHashTable *tls13_server_appdata; } ssl_master_key_map_t; gint ssl_get_keyex_alg(gint cipher); -- cgit v1.2.1