aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-dtls.c42
-rw-r--r--epan/dissectors/packet-tls-utils.c62
-rw-r--r--epan/dissectors/packet-tls-utils.h23
-rw-r--r--epan/dissectors/packet-tls.c44
4 files changed, 104 insertions, 67 deletions
diff --git a/epan/dissectors/packet-dtls.c b/epan/dissectors/packet-dtls.c
index 3741483b7c..e1cfaf4109 100644
--- a/epan/dissectors/packet-dtls.c
+++ b/epan/dissectors/packet-dtls.c
@@ -55,9 +55,11 @@
void proto_register_dtls(void);
+#ifdef HAVE_LIBGNUTLS
/* DTLS User Access Table */
static ssldecrypt_assoc_t *dtlskeylist_uats = NULL;
static guint ndtlsdecrypt = 0;
+#endif
/* we need to remember the top tree so that subdissectors we call are created
* at the root and not deep down inside the DTLS decode
@@ -145,8 +147,12 @@ static expert_field ei_dtls_msg_len_diff_fragment = EI_INIT;
static expert_field ei_dtls_heartbeat_payload_length = EI_INIT;
static ssl_master_key_map_t dtls_master_key_map;
-static GHashTable *dtls_key_hash = NULL;
-static wmem_stack_t *key_list_stack = NULL;
+#ifdef HAVE_LIBGNUTLS
+static GHashTable *dtls_key_hash = NULL;
+static wmem_stack_t *key_list_stack = NULL;
+static uat_t *dtlsdecrypt_uat = NULL;
+static const gchar *dtls_keys_list = NULL;
+#endif
static reassembly_table dtls_reassembly_table;
static dissector_table_t dtls_associations = NULL;
static dissector_handle_t dtls_handle = NULL;
@@ -155,8 +161,6 @@ static StringInfo dtls_decrypted_data = {NULL, 0};
static gint dtls_decrypted_data_avail = 0;
static FILE *dtls_keylog_file = NULL;
-static uat_t *dtlsdecrypt_uat = NULL;
-static const gchar *dtls_keys_list = NULL;
static ssl_common_options_t dtls_options = { NULL, NULL};
static const gchar *dtls_debug_file_name = NULL;
@@ -209,14 +213,17 @@ dtls_init(void)
static void
dtls_cleanup(void)
{
+#ifdef HAVE_LIBGNUTLS
if (key_list_stack != NULL) {
wmem_destroy_stack(key_list_stack);
key_list_stack = NULL;
}
+#endif
ssl_common_cleanup(&dtls_master_key_map, &dtls_keylog_file,
&dtls_decrypted_data, &dtls_compressed_data);
}
+#ifdef HAVE_LIBGNUTLS
/* parse dtls related preferences (private keys and ports association strings) */
static void
dtls_parse_uat(void)
@@ -240,8 +247,8 @@ dtls_parse_uat(void)
}
/* parse private keys string, load available keys and put them in key hash*/
- dtls_key_hash = g_hash_table_new_full(ssl_private_key_hash,
- ssl_private_key_equal, g_free, rsa_private_key_free);
+ dtls_key_hash = g_hash_table_new_full(tls_private_key_hash,
+ tls_private_key_equal, g_free, tls_private_key_free);
ssl_set_debug(dtls_debug_file_name);
@@ -263,14 +270,12 @@ dtls_parse_uat(void)
dissector_add_for_decode_as("udp.port", dtls_handle);
}
-#if defined(HAVE_LIBGNUTLS)
static void
dtls_reset_uat(void)
{
g_hash_table_destroy(dtls_key_hash);
dtls_key_hash = NULL;
}
-#endif
static void
dtls_parse_old_keys(void)
@@ -301,6 +306,7 @@ dtls_parse_old_keys(void)
g_strfreev(old_keys);
}
}
+#endif /* HAVE_LIBGNUTLS */
/*
* DTLS Dissection Routines
@@ -1305,7 +1311,7 @@ dissect_dtls_handshake(tvbuff_t *tvb, packet_info *pinfo,
case SSL_HND_CERTIFICATE:
ssl_dissect_hnd_cert(&dissect_dtls_hf, sub_tvb, ssl_hand_tree, 0, length,
- pinfo, session, ssl, dtls_key_hash, is_from_server, TRUE);
+ pinfo, session, ssl, is_from_server, TRUE);
break;
case SSL_HND_SERVER_KEY_EXCHG:
@@ -1335,6 +1341,9 @@ dissect_dtls_handshake(tvbuff_t *tvb, packet_info *pinfo,
/* try to find master key from pre-master key */
if (!ssl_generate_pre_master_secret(ssl, length, sub_tvb, 0,
dtls_options.psk,
+#ifdef HAVE_LIBGNUTLS
+ dtls_key_hash,
+#endif
&dtls_master_key_map)) {
ssl_debug_printf("dissect_dtls_handshake can't generate pre master secret\n");
}
@@ -1980,17 +1989,17 @@ proto_register_dtls(void)
"RSA keys list",
"A table of RSA keys for DTLS decryption",
dtlsdecrypt_uat);
-#endif /* HAVE_LIBGNUTLS */
-
- prefs_register_filename_preference(dtls_module, "debug_file", "DTLS debug file",
- "redirect dtls debug to file name; leave empty to disable debug, "
- "use \"" SSL_DEBUG_USE_STDERR "\" to redirect output to stderr\n",
- &dtls_debug_file_name, TRUE);
prefs_register_string_preference(dtls_module, "keys_list", "RSA keys list (deprecated)",
"Semicolon-separated list of private RSA keys used for DTLS decryption. "
"Used by versions of Wireshark prior to 1.6",
&dtls_keys_list);
+#endif /* HAVE_LIBGNUTLS */
+
+ prefs_register_filename_preference(dtls_module, "debug_file", "DTLS debug file",
+ "redirect dtls debug to file name; leave empty to disable debug, "
+ "use \"" SSL_DEBUG_USE_STDERR "\" to redirect output to stderr\n",
+ &dtls_debug_file_name, TRUE);
ssl_common_register_options(dtls_module, &dtls_options);
}
@@ -2018,9 +2027,10 @@ proto_reg_handoff_dtls(void)
{
static gboolean initialized = FALSE;
- /* add now dissector to default ports.*/
+#ifdef HAVE_LIBGNUTLS
dtls_parse_uat();
dtls_parse_old_keys();
+#endif
exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_7);
if (initialized == FALSE) {
diff --git a/epan/dissectors/packet-tls-utils.c b/epan/dissectors/packet-tls-utils.c
index 447a1a1797..f3c764fbbe 100644
--- a/epan/dissectors/packet-tls-utils.c
+++ b/epan/dissectors/packet-tls-utils.c
@@ -3044,6 +3044,9 @@ gboolean
ssl_generate_pre_master_secret(SslDecryptSession *ssl_session,
guint32 length, tvbuff_t *tvb, guint32 offset,
const gchar *ssl_psk,
+#ifdef HAVE_LIBGNUTLS
+ GHashTable *key_hash,
+#endif
const ssl_master_key_map_t *mk_map)
{
/* check for required session data */
@@ -3159,10 +3162,13 @@ ssl_generate_pre_master_secret(SslDecryptSession *ssl_session,
tvb_memcpy(tvb, encrypted_pre_master.data, offset+skip, encrlen);
#ifdef HAVE_LIBGNUTLS
- if (ssl_session->private_key) {
- /* try to decrypt encrypted pre-master with RSA key */
- if (ssl_decrypt_pre_master_secret(ssl_session,
- &encrypted_pre_master, ssl_session->private_key))
+ /* Try to lookup an appropriate RSA private key to decrypt the Encrypted Pre-Master Secret. */
+ gcry_sexp_t pk = NULL;
+ if (ssl_session->cert_key_id) {
+ pk = (gcry_sexp_t)g_hash_table_lookup(key_hash, ssl_session->cert_key_id);
+ }
+ if (pk) {
+ if (ssl_decrypt_pre_master_secret(ssl_session, &encrypted_pre_master, pk))
return TRUE;
ssl_debug_printf("%s: can't decrypt pre-master secret\n",
@@ -3592,8 +3598,8 @@ end:
#ifdef HAVE_LIBGNUTLS
/* Decrypt RSA pre-master secret using RSA private key. {{{ */
static gboolean
-ssl_decrypt_pre_master_secret(SslDecryptSession*ssl_session,
- StringInfo* encrypted_pre_master, gcry_sexp_t pk)
+ssl_decrypt_pre_master_secret(SslDecryptSession *ssl_session,
+ StringInfo *encrypted_pre_master, gcry_sexp_t pk)
{
size_t i;
char *err;
@@ -4254,11 +4260,11 @@ skip_mac:
-#if defined(HAVE_LIBGNUTLS)
+#ifdef HAVE_LIBGNUTLS
/* RSA private key file processing {{{ */
static void
-ssl_find_private_key_by_pubkey(SslDecryptSession *ssl, GHashTable *key_hash,
+ssl_find_private_key_by_pubkey(SslDecryptSession *ssl,
gnutls_datum_t *subjectPublicKeyInfo)
{
gnutls_pubkey_t pubkey = NULL;
@@ -4293,16 +4299,21 @@ ssl_find_private_key_by_pubkey(SslDecryptSession *ssl, GHashTable *key_hash,
goto end;
}
- ssl_print_data("lookup(KeyID)", key_id, key_id_len);
- ssl->private_key = (gcry_sexp_t)g_hash_table_lookup(key_hash, key_id);
- ssl_debug_printf("%s: lookup result: %p\n", G_STRFUNC, (void *) ssl->private_key);
+ if (key_id_len != sizeof(key_id)) {
+ ssl_debug_printf("%s: expected Key ID size %zu, got %zu\n",
+ G_STRFUNC, sizeof(key_id), key_id_len);
+ goto end;
+ }
+
+ ssl_print_data("Certificate.KeyID", key_id, key_id_len);
+ ssl->cert_key_id = (guint8 *)wmem_memdup(wmem_file_scope(), key_id, key_id_len);
end:
gnutls_pubkey_deinit(pubkey);
}
/* RSA private key file processing }}} */
-#endif /* ! defined(HAVE_LIBGNUTLS) */
+#endif /* HAVE_LIBGNUTLS */
/*--- Start of dissector-related code below ---*/
@@ -4371,8 +4382,8 @@ static void ssl_reset_session(SslSession *session, SslDecryptSession *ssl, gbool
clear_flags |= SSL_SERVER_EXTENDED_MASTER_SECRET | SSL_NEW_SESSION_TICKET;
ssl->server_random.data_len = 0;
ssl->pre_master_secret.data_len = 0;
-#if defined(HAVE_LIBGNUTLS)
- ssl->private_key = NULL;
+#ifdef HAVE_LIBGNUTLS
+ ssl->cert_key_id = NULL;
#endif
ssl->psk.data_len = 0;
}
@@ -4496,15 +4507,16 @@ ssl_hash (gconstpointer v)
return hash;
}
+#ifdef HAVE_LIBGNUTLS
gboolean
-ssl_private_key_equal (gconstpointer v, gconstpointer v2)
+tls_private_key_equal (gconstpointer v, gconstpointer v2)
{
/* key ID length (SHA-1 hash, per GNUTLS_KEYID_USE_SHA1) */
return !memcmp(v, v2, 20);
}
guint
-ssl_private_key_hash (gconstpointer v)
+tls_private_key_hash (gconstpointer v)
{
guint l, hash = 0;
const guint8 *cur = (const guint8 *)v;
@@ -4516,6 +4528,12 @@ ssl_private_key_hash (gconstpointer v)
return hash;
}
+void
+tls_private_key_free(gpointer data)
+{
+ rsa_private_key_free(data);
+}
+#endif
/* Functions for TLS/DTLS sessions and RSA private keys hashtables. }}} */
/* Handling of association between tls/dtls ports and clear text protocol. {{{ */
@@ -4809,12 +4827,6 @@ end:
g_free(key_id);
}
/* }}} */
-#else
-void
-ssl_parse_key_list(const ssldecrypt_assoc_t *uats _U_, GHashTable *key_hash _U_, const char* dissector_table_name _U_, dissector_handle_t main_handle _U_, gboolean tcp _U_)
-{
- report_failure("Can't load private key files, support is not compiled in.");
-}
#endif
@@ -7862,7 +7874,7 @@ void
ssl_dissect_hnd_cert(ssl_common_dissect_t *hf, tvbuff_t *tvb, proto_tree *tree,
guint32 offset, guint32 offset_end, packet_info *pinfo,
SslSession *session, SslDecryptSession *ssl _U_,
- GHashTable *key_hash _U_, gboolean is_from_server, gboolean is_dtls)
+ gboolean is_from_server, gboolean is_dtls)
{
/* opaque ASN.1Cert<1..2^24-1>;
*
@@ -7990,7 +8002,7 @@ ssl_dissect_hnd_cert(ssl_common_dissect_t *hf, tvbuff_t *tvb, proto_tree *tree,
dissect_x509af_Certificate(FALSE, tvb, offset, &asn1_ctx, subtree, hf->hf.hs_certificate);
#if defined(HAVE_LIBGNUTLS)
if (is_from_server && ssl && certificate_index == 0) {
- ssl_find_private_key_by_pubkey(ssl, key_hash, &subjectPublicKeyInfo);
+ ssl_find_private_key_by_pubkey(ssl, &subjectPublicKeyInfo);
/* Only attempt to get the RSA modulus for the first cert. */
asn1_ctx.private_data = NULL;
}
@@ -8265,7 +8277,7 @@ void
ssl_dissect_hnd_compress_certificate(ssl_common_dissect_t *hf, tvbuff_t *tvb, proto_tree *tree,
guint32 offset, guint32 offset_end, packet_info *pinfo,
SslSession *session _U_, SslDecryptSession *ssl _U_,
- GHashTable *key_hash _U_, gboolean is_from_server _U_, gboolean is_dtls _U_)
+ gboolean is_from_server _U_, gboolean is_dtls _U_)
{
guint32 compressed_certificate_message_length;
/*
diff --git a/epan/dissectors/packet-tls-utils.h b/epan/dissectors/packet-tls-utils.h
index 1ad18c063b..8697d494be 100644
--- a/epan/dissectors/packet-tls-utils.h
+++ b/epan/dissectors/packet-tls-utils.h
@@ -434,7 +434,7 @@ typedef struct _SslDecryptSession {
SslDecoder *server_new;
SslDecoder *client_new;
#if defined(HAVE_LIBGNUTLS)
- gcry_sexp_t private_key;
+ guint8 *cert_key_id; /**< SHA-1 Key ID of public key in certificate. */
#endif
StringInfo psk;
StringInfo app_data_segment;
@@ -569,6 +569,9 @@ gboolean
ssl_generate_pre_master_secret(SslDecryptSession *ssl_session,
guint32 length, tvbuff_t *tvb, guint32 offset,
const gchar *ssl_psk,
+#ifdef HAVE_LIBGNUTLS
+ GHashTable *key_hash,
+#endif
const ssl_master_key_map_t *mk_map);
/** Expand the pre_master_secret to generate all the session information
@@ -607,19 +610,19 @@ tls13_cipher *
tls13_cipher_create(const char *label_prefix, int cipher_algo, int cipher_mode, int hash_algo, const StringInfo *secret, const gchar **error);
-/* Common part bitween SSL and DTLS dissectors */
+/* Common part between TLS and DTLS dissectors */
/* Hash Functions for RSA private keys table */
+#ifdef HAVE_LIBGNUTLS
extern gboolean
-ssl_private_key_equal (gconstpointer v, gconstpointer v2);
+tls_private_key_equal (gconstpointer v, gconstpointer v2);
extern guint
-ssl_private_key_hash (gconstpointer v);
+tls_private_key_hash (gconstpointer v);
-/* private key table entries have a scope 'larger' then packet capture,
- * so we can't rely on wmem_file_scope function */
extern void
-ssl_private_key_free(gpointer key);
+tls_private_key_free(gpointer key);
+#endif /* HAVE_LIBGNUTLS */
/* handling of association between tls/dtls ports and clear text protocol */
@@ -657,9 +660,11 @@ extern void
ssl_load_keyfile(const gchar *ssl_keylog_filename, FILE **keylog_file,
const ssl_master_key_map_t *mk_map);
+#ifdef HAVE_LIBGNUTLS
/* parse ssl related preferences (private keys and ports association strings) */
extern void
ssl_parse_key_list(const ssldecrypt_assoc_t * uats, GHashTable *key_hash, const char* dissector_table_name, dissector_handle_t main_handle, gboolean tcp);
+#endif
/* store master secret into session data cache */
extern void
@@ -1043,7 +1048,7 @@ extern void
ssl_dissect_hnd_cert(ssl_common_dissect_t *hf, tvbuff_t *tvb, proto_tree *tree,
guint32 offset, guint32 offset_end, packet_info *pinfo,
SslSession *session, SslDecryptSession *ssl,
- GHashTable *key_hash, gboolean is_from_server, gboolean is_dtls);
+ gboolean is_from_server, gboolean is_dtls);
extern void
ssl_dissect_hnd_cert_req(ssl_common_dissect_t *hf, tvbuff_t *tvb, packet_info *pinfo,
@@ -1099,7 +1104,7 @@ extern void
ssl_dissect_hnd_compress_certificate(ssl_common_dissect_t *hf, tvbuff_t *tvb, proto_tree *tree,
guint32 offset, guint32 offset_end, packet_info *pinfo,
SslSession *session _U_, SslDecryptSession *ssl _U_,
- GHashTable *key_hash _U_, gboolean is_from_server _U_, gboolean is_dtls _U_);
+ gboolean is_from_server _U_, gboolean is_dtls _U_);
/* {{{ */
#define SSL_COMMON_LIST_T(name) \
ssl_common_dissect_t name = { \
diff --git a/epan/dissectors/packet-tls.c b/epan/dissectors/packet-tls.c
index 095bda7067..32e5f77206 100644
--- a/epan/dissectors/packet-tls.c
+++ b/epan/dissectors/packet-tls.c
@@ -98,8 +98,10 @@
void proto_register_tls(void);
+#ifdef HAVE_LIBGNUTLS
static ssldecrypt_assoc_t *tlskeylist_uats = NULL;
static guint ntlsdecrypt = 0;
+#endif
static gboolean tls_desegment = TRUE;
static gboolean tls_desegment_app_data = TRUE;
@@ -239,17 +241,18 @@ static ssl_master_key_map_t ssl_master_key_map;
GHashTable *ssl_session_hash;
GHashTable *ssl_crandom_hash;
+#ifdef HAVE_LIBGNUTLS
static GHashTable *ssl_key_hash = NULL;
static wmem_stack_t *key_list_stack = NULL;
+static uat_t *ssldecrypt_uat = NULL;
+static const gchar *ssl_keys_list = NULL;
+#endif
static dissector_table_t ssl_associations = NULL;
static dissector_handle_t tls_handle = NULL;
static StringInfo ssl_compressed_data = {NULL, 0};
static StringInfo ssl_decrypted_data = {NULL, 0};
static gint ssl_decrypted_data_avail = 0;
static FILE *ssl_keylog_file = NULL;
-
-static uat_t *ssldecrypt_uat = NULL;
-static const gchar *ssl_keys_list = NULL;
static ssl_common_options_t ssl_options = { NULL, NULL};
/* List of dissectors to call for TLS data */
@@ -292,10 +295,12 @@ ssl_init(void)
static void
ssl_cleanup(void)
{
+#ifdef HAVE_LIBGNUTLS
if (key_list_stack != NULL) {
wmem_destroy_stack(key_list_stack);
key_list_stack = NULL;
}
+#endif
ssl_common_cleanup(&ssl_master_key_map, &ssl_keylog_file,
&ssl_decrypted_data, &ssl_compressed_data);
@@ -305,6 +310,7 @@ ssl_cleanup(void)
ssl_crandom_hash = NULL;
}
+#ifdef HAVE_LIBGNUTLS
/* parse ssl related preferences (private keys and ports association strings) */
static void
ssl_parse_uat(void)
@@ -330,8 +336,8 @@ ssl_parse_uat(void)
}
}
/* parse private keys string, load available keys and put them in key hash*/
- ssl_key_hash = g_hash_table_new_full(ssl_private_key_hash,
- ssl_private_key_equal, g_free, rsa_private_key_free);
+ ssl_key_hash = g_hash_table_new_full(tls_private_key_hash,
+ tls_private_key_equal, g_free, tls_private_key_free);
if (ntlsdecrypt > 0) {
@@ -348,14 +354,12 @@ ssl_parse_uat(void)
ssl_debug_flush();
}
-#if defined(HAVE_LIBGNUTLS)
static void
ssl_reset_uat(void)
{
g_hash_table_destroy(ssl_key_hash);
ssl_key_hash = NULL;
}
-#endif
static void
ssl_parse_old_keys(void)
@@ -387,6 +391,7 @@ ssl_parse_old_keys(void)
g_strfreev(old_keys);
}
}
+#endif /* HAVE_LIBGNUTLS */
static gboolean
@@ -2327,7 +2332,7 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo,
case SSL_HND_CERTIFICATE:
ssl_dissect_hnd_cert(&dissect_ssl3_hf, tvb, ssl_hand_tree,
- offset, offset + length, pinfo, session, ssl, ssl_key_hash, is_from_server, FALSE);
+ offset, offset + length, pinfo, session, ssl, is_from_server, FALSE);
break;
case SSL_HND_SERVER_KEY_EXCHG:
@@ -2358,6 +2363,9 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo,
/* try to find master key from pre-master key */
if (!ssl_generate_pre_master_secret(ssl, length, tvb, offset,
ssl_options.psk,
+#ifdef HAVE_LIBGNUTLS
+ ssl_key_hash,
+#endif
&ssl_master_key_map)) {
ssl_debug_printf("dissect_ssl3_handshake can't generate pre master secret\n");
}
@@ -2394,7 +2402,7 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo,
case SSL_HND_COMPRESSED_CERTIFICATE:
ssl_dissect_hnd_compress_certificate(&dissect_ssl3_hf, tvb, ssl_hand_tree,
offset, offset + length, pinfo, session,
- ssl, ssl_key_hash, is_from_server, FALSE);
+ ssl, is_from_server, FALSE);
break;
case SSL_HND_ENCRYPTED_EXTS:
@@ -3628,7 +3636,7 @@ tls13_exporter(packet_info *pinfo, gboolean is_early,
/* UAT */
-#if defined(HAVE_LIBGNUTLS)
+#ifdef HAVE_LIBGNUTLS
static void
ssldecrypt_free_cb(void *r)
{
@@ -3687,7 +3695,7 @@ ssldecrypt_uat_fld_protocol_chk_cb(void* r _U_, const char* p, guint len _U_, co
*err = NULL;
return TRUE;
}
-#endif
+#endif /* HAVE_LIBGNUTLS */
static void
ssl_src_prompt(packet_info *pinfo, gchar *result)
@@ -4125,17 +4133,17 @@ proto_register_tls(void)
"RSA keys list",
"A table of RSA keys for TLS decryption",
ssldecrypt_uat);
-#endif /* HAVE_LIBGNUTLS */
-
- prefs_register_filename_preference(ssl_module, "debug_file", "TLS debug file",
- "Redirect TLS debug to the file specified. Leave empty to disable debugging "
- "or use \"" SSL_DEBUG_USE_STDERR "\" to redirect output to stderr.",
- &ssl_debug_file_name, TRUE);
prefs_register_string_preference(ssl_module, "keys_list", "RSA keys list (deprecated)",
"Semicolon-separated list of private RSA keys used for TLS decryption. "
"Used by versions of Wireshark prior to 1.6",
&ssl_keys_list);
+#endif /* HAVE_LIBGNUTLS */
+
+ prefs_register_filename_preference(ssl_module, "debug_file", "TLS debug file",
+ "Redirect TLS debug to the file specified. Leave empty to disable debugging "
+ "or use \"" SSL_DEBUG_USE_STDERR "\" to redirect output to stderr.",
+ &ssl_debug_file_name, TRUE);
prefs_register_bool_preference(ssl_module,
"desegment_ssl_records",
@@ -4203,9 +4211,11 @@ void
proto_reg_handoff_ssl(void)
{
+#ifdef HAVE_LIBGNUTLS
/* parse key list */
ssl_parse_uat();
ssl_parse_old_keys();
+#endif
/*
* XXX the port preferences should probably be removed in favor of Decode