diff options
-rw-r--r-- | epan/dissectors/packet-dtls.c | 42 | ||||
-rw-r--r-- | epan/dissectors/packet-tls-utils.c | 62 | ||||
-rw-r--r-- | epan/dissectors/packet-tls-utils.h | 23 | ||||
-rw-r--r-- | epan/dissectors/packet-tls.c | 44 |
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 |