summaryrefslogtreecommitdiff
path: root/epan/dissectors/packet-ssl-utils.c
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2017-02-11 12:02:40 +0100
committerPeter Wu <peter@lekensteyn.nl>2017-02-11 13:22:56 +0000
commit6cc7a7031d039facf4e3d39a322589ec39807424 (patch)
tree468358df87a3710fcc989893b87766d76aa007e6 /epan/dissectors/packet-ssl-utils.c
parenteb1a63f3bcd30e8e844f2a72ac9c3e7a82871638 (diff)
downloadwireshark-6cc7a7031d039facf4e3d39a322589ec39807424.tar.gz
TLS13: handle Key Update for decryption
Generate new key upon receipt of Key Update message. Untested. Note that the "traffic_secret" field in SslDecryptSession was unused and since the client and server have two different encryption states, store the application traffic secret in SslDecoder. Change-Id: Iefca3f6cb75745a996fecb0fe7769c876dc9c4ee Ping-Bug: 12779 Reviewed-on: https://code.wireshark.org/review/20013 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Diffstat (limited to 'epan/dissectors/packet-ssl-utils.c')
-rw-r--r--epan/dissectors/packet-ssl-utils.c63
1 files changed, 59 insertions, 4 deletions
diff --git a/epan/dissectors/packet-ssl-utils.c b/epan/dissectors/packet-ssl-utils.c
index 1bcd0b2113..1f2aeef216 100644
--- a/epan/dissectors/packet-ssl-utils.c
+++ b/epan/dissectors/packet-ssl-utils.c
@@ -5176,13 +5176,68 @@ tls13_change_key(SslDecryptSession *ssl, ssl_master_key_map_t *mk_map,
}
/* TLS 1.3 secret found, set new keys. */
- ssl->traffic_secret.data = (guchar *) wmem_realloc(wmem_file_scope(),
- ssl->traffic_secret.data, secret->data_len);
- ssl_data_set(&ssl->traffic_secret, secret->data, secret->data_len);
ssl_debug_printf("%s Retrieved TLS 1.3 traffic secret.\n", G_STRFUNC);
ssl_print_string("Client Random", &ssl->client_random);
ssl_print_string(label, secret);
- tls13_generate_keys(ssl, secret, is_from_server);
+ if (tls13_generate_keys(ssl, secret, is_from_server)) {
+ /*
+ * Remember the application traffic secret to support Key Update. The
+ * other secrets cannot be used for this purpose, so free them.
+ */
+ SslDecoder *decoder = is_from_server ? ssl->server : ssl->client;
+ StringInfo *app_secret = &decoder->app_traffic_secret;
+ if (type == TLS_SECRET_APP) {
+ app_secret->data = (guchar *) wmem_realloc(wmem_file_scope(),
+ app_secret->data,
+ secret->data_len);
+ ssl_data_set(app_secret, secret->data, secret->data_len);
+ } else {
+ wmem_free(wmem_file_scope(), app_secret->data);
+ app_secret->data = NULL;
+ app_secret->data_len = 0;
+ }
+ }
+}
+
+/**
+ * Update to next application data traffic secret for TLS 1.3. The previous
+ * secret should have been set by tls13_change_key.
+ */
+void
+tls13_key_update(SslDecryptSession *ssl, gboolean is_from_server)
+{
+ /* https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-7.2
+ * traffic_secret_N+1 = HKDF-Expand-Label(
+ * traffic_secret_N,
+ * "application traffic secret", "", Hash.length)
+ *
+ * Note that traffic_secret_N is of the same length (Hash.length).
+ */
+ const SslCipherSuite *cipher_suite = ssl->cipher_suite;
+ SslDecoder *decoder = is_from_server ? ssl->server : ssl->client;
+ StringInfo *app_secret = decoder ? &decoder->app_traffic_secret : NULL;
+
+ if (!cipher_suite || !app_secret || app_secret->data_len == 0) {
+ ssl_debug_printf("%s Cannot perform Key Update due to missing info\n", G_STRFUNC);
+ return;
+ }
+
+ /*
+ * Previous traffic secret is available, so find the hash function,
+ * expand the new traffic secret and generate new keys.
+ */
+ const char *hash_name = ssl_cipher_suite_dig(cipher_suite)->name;
+ int hash_algo = ssl_get_digest_by_name(hash_name);
+ const guint hash_len = app_secret->data_len;
+ guchar *new_secret;
+ if (!tls13_hkdf_expand_label(hash_algo, app_secret, "application traffic secret", "",
+ hash_len, &new_secret)) {
+ ssl_debug_printf("%s traffic_secret_N+1 expansion failed\n", G_STRFUNC);
+ return;
+ }
+ ssl_data_set(app_secret, new_secret, hash_len);
+ wmem_free(NULL, new_secret);
+ tls13_generate_keys(ssl, app_secret, is_from_server);
}
#endif /* HAVE_LIBGCRYPT */