update epan/dissectors/pidl/drsuapi/drsuapi.idl from samba
[wireshark-sm.git] / ui / ssl_key_export.c
blobaa16903d4e5708d9b0ae22d86c39b33fd54b835f
1 /* export_sslkeys.c
3 * Export SSL Session Keys dialog
4 * by Sake Blok <sake@euronet.nl> (20110526)
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "config.h"
15 #include <glib.h>
17 #include <epan/address.h>
18 #include <epan/dissectors/packet-tls-utils.h>
20 #include <wiretap/secrets-types.h>
22 #include "ui/ssl_key_export.h"
24 int
25 ssl_session_key_count(void)
27 int count = 0;
28 ssl_master_key_map_t *mk_map = tls_get_master_key_map(false);
29 if (!mk_map || !mk_map->used_crandom)
30 return count;
32 GHashTableIter iter;
33 void *key;
35 g_hash_table_iter_init(&iter, mk_map->used_crandom);
36 while (g_hash_table_iter_next(&iter, &key, NULL)) {
37 if (g_hash_table_contains(mk_map->crandom, key)) {
38 count++;
40 if (g_hash_table_contains(mk_map->tls13_client_early, key)) {
41 count++;
43 if (g_hash_table_contains(mk_map->tls13_client_handshake, key)) {
44 count++;
46 if (g_hash_table_contains(mk_map->tls13_server_handshake, key)) {
47 count++;
49 if (g_hash_table_contains(mk_map->tls13_client_appdata, key)) {
50 count++;
52 if (g_hash_table_contains(mk_map->tls13_server_appdata, key)) {
53 count++;
56 return count;
59 static void
60 tls_export_client_randoms_func(void *key, void *value, void *user_data, const char* label)
62 unsigned i;
63 StringInfo *client_random = (StringInfo *)key;
64 StringInfo *master_secret = (StringInfo *)value;
65 GString *keylist = (GString *)user_data;
67 g_string_append(keylist, label);
69 for (i = 0; i < client_random->data_len; i++) {
70 g_string_append_printf(keylist, "%.2x", client_random->data[i]);
73 g_string_append_c(keylist, ' ');
75 for (i = 0; i < master_secret->data_len; i++) {
76 g_string_append_printf(keylist, "%.2x", master_secret->data[i]);
79 g_string_append_c(keylist, '\n');
82 char*
83 ssl_export_sessions(size_t *length)
85 /* Output format is:
86 * "CLIENT_RANDOM zzzz yyyy\n"
87 * Where zzzz is the client random (always 64 chars)
88 * Where yyyy is same as above
89 * So length will always be 13+1+64+1+96+2 = 177 chars
91 * Wireshark can read CLIENT_RANDOM since v1.8.0.
92 * Both values are exported in case you use the Session-ID for resuming a
93 * session in a different capture.
95 * TLS 1.3 derived secrets are similar to the CLIENT_RANDOM master secret
96 * export, but with a (longer) label indicating the type of derived secret
97 * to which the client random maps, e.g.
98 * "CLIENT_HANDSHAKE_TRAFFIC_SECRET zzzz yyyy\n"
100 * The TLS 1.3 values are obtained from an existing key log, but exporting
101 * them is useful in order to filter actually used secrets or add a DSB.
103 ssl_master_key_map_t *mk_map = tls_get_master_key_map(false);
105 if (!mk_map) {
106 *length = 0;
107 return g_strdup("");
110 size_t len = 177 * (size_t)ssl_session_key_count();
111 GString *keylist = g_string_sized_new(len);
113 GHashTableIter iter;
114 void *key, *value;
116 g_hash_table_iter_init(&iter, mk_map->used_crandom);
117 while (g_hash_table_iter_next(&iter, &key, NULL)) {
118 if ((value = g_hash_table_lookup(mk_map->crandom, key))) {
119 tls_export_client_randoms_func(key, value, (void *)keylist, "CLIENT_RANDOM ");
121 if ((value = g_hash_table_lookup(mk_map->tls13_client_early, key))) {
122 tls_export_client_randoms_func(key, value, (void *)keylist, "CLIENT_EARLY_TRAFFIC_SECRET ");
124 if ((value = g_hash_table_lookup(mk_map->tls13_client_handshake, key))) {
125 tls_export_client_randoms_func(key, value, (void *)keylist, "CLIENT_HANDSHAKE_TRAFFIC_SECRET ");
127 if ((value = g_hash_table_lookup(mk_map->tls13_server_handshake, key))) {
128 tls_export_client_randoms_func(key, value, (void *)keylist, "SERVER_HANDSHAKE_TRAFFIC_SECRET ");
130 if ((value = g_hash_table_lookup(mk_map->tls13_server_appdata, key))) {
131 tls_export_client_randoms_func(key, value, (void *)keylist, "SERVER_TRAFFIC_SECRET_0 ");
133 if ((value = g_hash_table_lookup(mk_map->tls13_client_appdata, key))) {
134 tls_export_client_randoms_func(key, value, (void *)keylist, "CLIENT_TRAFFIC_SECRET_0 ");
136 if ((value = g_hash_table_lookup(mk_map->tls13_early_exporter, key))) {
137 tls_export_client_randoms_func(key, value, (void *)keylist, "EARLY_EXPORTER_SECRET ");
139 if ((value = g_hash_table_lookup(mk_map->tls13_exporter, key))) {
140 tls_export_client_randoms_func(key, value, (void *)keylist, "EXPORTER_SECRET ");
144 *length = keylist->len;
145 return g_string_free(keylist, FALSE);
148 void
149 tls_export_dsb(capture_file *cf)
151 wtap_block_t block;
152 wtapng_dsb_mandatory_t *dsb;
153 size_t secrets_len;
154 char* secrets = ssl_export_sessions(&secrets_len);
156 block = wtap_block_create(WTAP_BLOCK_DECRYPTION_SECRETS);
157 dsb = (wtapng_dsb_mandatory_t *)wtap_block_get_mandatory_data(block);
159 dsb->secrets_type = SECRETS_TYPE_TLS;
160 dsb->secrets_data = g_memdup2(secrets, secrets_len);
161 dsb->secrets_len = (unsigned)secrets_len;
163 /* XXX - support replacing the DSB of the same type instead of adding? */
164 wtap_file_add_decryption_secrets(cf->provider.wth, block);
165 /* Mark the file as having unsaved changes */
166 cf->unsaved_changes = true;
168 return;