diff options
Diffstat (limited to 'epan/dissectors')
-rw-r--r-- | epan/dissectors/packet-dtls.c | 4 | ||||
-rw-r--r-- | epan/dissectors/packet-tls-utils.c | 61 | ||||
-rw-r--r-- | epan/dissectors/packet-tls-utils.h | 17 | ||||
-rw-r--r-- | epan/dissectors/packet-tls.c | 3 |
4 files changed, 25 insertions, 60 deletions
diff --git a/epan/dissectors/packet-dtls.c b/epan/dissectors/packet-dtls.c index e1cfaf4109..1252acd55f 100644 --- a/epan/dissectors/packet-dtls.c +++ b/epan/dissectors/packet-dtls.c @@ -46,6 +46,7 @@ #include <epan/exported_pdu.h> #include <epan/decode_as.h> #include <epan/proto_data.h> +#include <epan/secrets.h> /* for privkey_hash_table_new */ #include <wsutil/str_util.h> #include <wsutil/strtoi.h> #include <wsutil/utf8_entities.h> @@ -247,8 +248,7 @@ 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(tls_private_key_hash, - tls_private_key_equal, g_free, tls_private_key_free); + dtls_key_hash = privkey_hash_table_new(); ssl_set_debug(dtls_debug_file_name); diff --git a/epan/dissectors/packet-tls-utils.c b/epan/dissectors/packet-tls-utils.c index 7af38064a3..6e274ddda4 100644 --- a/epan/dissectors/packet-tls-utils.c +++ b/epan/dissectors/packet-tls-utils.c @@ -30,6 +30,7 @@ #include <epan/asn1.h> #include <epan/proto_data.h> #include <epan/oids.h> +#include <epan/secrets.h> #include <wsutil/filesystem.h> #include <wsutil/file_util.h> @@ -3033,7 +3034,7 @@ end: static int ssl_decrypt_pre_master_secret(SslDecryptSession *ssl_session, StringInfo *encrypted_pre_master, - gnutls_privkey_t pk); + GHashTable *key_hash); #endif /* HAVE_LIBGNUTLS */ static gboolean @@ -3163,12 +3164,8 @@ ssl_generate_pre_master_secret(SslDecryptSession *ssl_session, #ifdef HAVE_LIBGNUTLS /* Try to lookup an appropriate RSA private key to decrypt the Encrypted Pre-Master Secret. */ - gnutls_privkey_t pk = NULL; if (ssl_session->cert_key_id) { - pk = (gnutls_privkey_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)) + if (ssl_decrypt_pre_master_secret(ssl_session, &encrypted_pre_master, key_hash)) return TRUE; ssl_debug_printf("%s: can't decrypt pre-master secret\n", @@ -3599,8 +3596,10 @@ end: /* Decrypt RSA pre-master secret using RSA private key. {{{ */ static gboolean ssl_decrypt_pre_master_secret(SslDecryptSession *ssl_session, - StringInfo *encrypted_pre_master, gnutls_privkey_t pk) + StringInfo *encrypted_pre_master, GHashTable *key_hash) { + int ret; + if (!encrypted_pre_master) return FALSE; @@ -3618,12 +3617,18 @@ ssl_decrypt_pre_master_secret(SslDecryptSession *ssl_session, return FALSE; } + gnutls_privkey_t pk = (gnutls_privkey_t)g_hash_table_lookup(key_hash, ssl_session->cert_key_id); + ssl_print_string("pre master encrypted", encrypted_pre_master); ssl_debug_printf("%s: RSA_private_decrypt\n", G_STRFUNC); const gnutls_datum_t epms = { encrypted_pre_master->data, encrypted_pre_master->data_len }; gnutls_datum_t pms = { 0 }; - // uses mechanism CKM_RSA_PKCS (corresponds to RSAES-PKCS1-v1_5) - int ret = gnutls_privkey_decrypt_data(pk, 0, &epms, &pms); + if (pk) { + // Try to decrypt using the RSA keys table from (D)TLS preferences. + ret = gnutls_privkey_decrypt_data(pk, 0, &epms, &pms); + } else { + ret = GNUTLS_E_NO_CERTIFICATE_FOUND; + } if (ret < 0) { ssl_debug_printf("%s: decryption failed: %d (%s)\n", G_STRFUNC, ret, gnutls_strerror(ret)); return FALSE; @@ -4267,7 +4272,7 @@ ssl_find_private_key_by_pubkey(SslDecryptSession *ssl, gnutls_datum_t *subjectPublicKeyInfo) { gnutls_pubkey_t pubkey = NULL; - guchar key_id[20]; + cert_key_id_t key_id; size_t key_id_len = sizeof(key_id); int r; @@ -4296,7 +4301,7 @@ ssl_find_private_key_by_pubkey(SslDecryptSession *ssl, } /* Generate a 20-byte SHA-1 hash. */ - r = gnutls_pubkey_get_key_id(pubkey, 0, key_id, &key_id_len); + r = gnutls_pubkey_get_key_id(pubkey, 0, key_id.key_id, &key_id_len); if (r < 0) { ssl_debug_printf("%s: failed to extract key id from pubkey: %s\n", G_STRFUNC, gnutls_strerror(r)); @@ -4309,8 +4314,9 @@ ssl_find_private_key_by_pubkey(SslDecryptSession *ssl, 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); + ssl_print_data("Certificate.KeyID", key_id.key_id, key_id_len); + ssl->cert_key_id = wmem_new(wmem_file_scope(), cert_key_id_t); + *ssl->cert_key_id = key_id; end: gnutls_pubkey_deinit(pubkey); @@ -4510,35 +4516,6 @@ ssl_hash (gconstpointer v) return hash; } - -#ifdef HAVE_LIBGNUTLS -gboolean -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 -tls_private_key_hash (gconstpointer v) -{ - guint l, hash = 0; - const guint8 *cur = (const guint8 *)v; - - /* The public key' SHA-1 hash (which maps to a private key) has a uniform - * distribution, hence simply xor'ing them should be sufficient. */ - for (l = 0; l < 20; l += 4, cur += 4) - hash ^= pntoh32(cur); - - return hash; -} -void -tls_private_key_free(gpointer data) -{ - gnutls_privkey_t pkey = (gnutls_privkey_t)data; - gnutls_privkey_deinit(pkey); -} -#endif /* Functions for TLS/DTLS sessions and RSA private keys hashtables. }}} */ /* Handling of association between tls/dtls ports and clear text protocol. {{{ */ diff --git a/epan/dissectors/packet-tls-utils.h b/epan/dissectors/packet-tls-utils.h index 8697d494be..0bf7a76dc7 100644 --- a/epan/dissectors/packet-tls-utils.h +++ b/epan/dissectors/packet-tls-utils.h @@ -408,6 +408,8 @@ typedef struct _SslSession { /* RFC 5246, section 8.1 says that the master secret is always 48 bytes */ #define SSL_MASTER_SECRET_LENGTH 48 +struct cert_key_id; /* defined in epan/secrets.h */ + /* This holds state information for a SSL conversation */ typedef struct _SslDecryptSession { guchar _master_secret[SSL_MASTER_SECRET_LENGTH]; @@ -434,7 +436,7 @@ typedef struct _SslDecryptSession { SslDecoder *server_new; SslDecoder *client_new; #if defined(HAVE_LIBGNUTLS) - guint8 *cert_key_id; /**< SHA-1 Key ID of public key in certificate. */ + struct cert_key_id *cert_key_id; /**< SHA-1 Key ID of public key in certificate. */ #endif StringInfo psk; StringInfo app_data_segment; @@ -611,19 +613,6 @@ tls13_cipher_create(const char *label_prefix, int cipher_algo, int cipher_mode, /* Common part between TLS and DTLS dissectors */ -/* Hash Functions for RSA private keys table */ - -#ifdef HAVE_LIBGNUTLS -extern gboolean -tls_private_key_equal (gconstpointer v, gconstpointer v2); - -extern guint -tls_private_key_hash (gconstpointer v); - -extern void -tls_private_key_free(gpointer key); -#endif /* HAVE_LIBGNUTLS */ - /* handling of association between tls/dtls ports and clear text protocol */ extern void diff --git a/epan/dissectors/packet-tls.c b/epan/dissectors/packet-tls.c index 32e5f77206..28632dcbd8 100644 --- a/epan/dissectors/packet-tls.c +++ b/epan/dissectors/packet-tls.c @@ -336,8 +336,7 @@ 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(tls_private_key_hash, - tls_private_key_equal, g_free, tls_private_key_free); + ssl_key_hash = privkey_hash_table_new(); if (ntlsdecrypt > 0) { |