diff options
-rw-r--r-- | lib/global.c | 2 | ||||
-rw-r--r-- | lib/global.h | 1 | ||||
-rw-r--r-- | lib/kx.c | 56 | ||||
-rw-r--r-- | lib/kx.h | 3 |
4 files changed, 42 insertions, 20 deletions
diff --git a/lib/global.c b/lib/global.c index eaac0a5872..1f92965b80 100644 --- a/lib/global.c +++ b/lib/global.c @@ -436,6 +436,8 @@ static void _gnutls_global_deinit(unsigned destructor) _gnutls_tpm_global_deinit(); #endif + _gnutls_nss_keylog_deinit(); + gnutls_mutex_deinit(&_gnutls_file_mutex); gnutls_mutex_deinit(&_gnutls_pkcs11_mutex); } else { diff --git a/lib/global.h b/lib/global.h index 45d8dcaff8..c1aa7863b5 100644 --- a/lib/global.h +++ b/lib/global.h @@ -44,6 +44,7 @@ extern int _gnutls_log_level; extern int gnutls_crypto_init(void); extern void gnutls_crypto_deinit(void); extern void _gnutls_tpm_global_deinit(void); +extern void _gnutls_nss_keylog_deinit(void); extern void _gnutls_load_system_priorities(void); extern void _gnutls_unload_system_priorities(void); @@ -31,6 +31,7 @@ #include "errors.h" #include "algorithms.h" #include "debug.h" +#include "locks.h" #include "mpi.h" #include <state.h> #include <datum.h> @@ -45,6 +46,9 @@ #define EXT_MASTER_SECRET "extended master secret" #define EXT_MASTER_SECRET_SIZE (sizeof(EXT_MASTER_SECRET)-1) +GNUTLS_STATIC_MUTEX(keylog_mutex); +static FILE *keylog; + static int generate_normal_master(gnutls_session_t session, gnutls_datum_t *, int); @@ -66,34 +70,44 @@ int _gnutls_generate_master(gnutls_session_t session, int keep_premaster) return 0; } -static void write_nss_key_log(gnutls_session_t session, const gnutls_datum_t *premaster) +void _gnutls_nss_keylog_write(gnutls_session_t session, + const char *label, + const uint8_t *secret, size_t secret_size) { - char buf[512]; - char buf2[512]; - FILE *fp; static const char *keylogfile = NULL; static unsigned checked_env = 0; if (!checked_env) { checked_env = 1; keylogfile = secure_getenv("SSLKEYLOGFILE"); + if (keylogfile != NULL) + keylog = fopen(keylogfile, "a"); } - if (keylogfile == NULL) - return; - - fp = fopen(keylogfile, "a"); - if (fp == NULL) - return; - - fprintf(fp, "CLIENT_RANDOM %s %s\n", - _gnutls_bin2hex(session->security_parameters. - client_random, 32, buf, - sizeof(buf), NULL), - _gnutls_bin2hex(session->security_parameters. - master_secret, GNUTLS_MASTER_SIZE, - buf2, sizeof(buf2), NULL)); - fclose(fp); + if (keylog) { + char client_random_hex[2*GNUTLS_RANDOM_SIZE+1]; + char secret_hex[2*MAX_HASH_SIZE+1]; + + GNUTLS_STATIC_MUTEX_LOCK(keylog_mutex); + fprintf(keylog, "%s %s %s\n", + label, + _gnutls_bin2hex(session->security_parameters. + client_random, GNUTLS_RANDOM_SIZE, + client_random_hex, + sizeof(client_random_hex), NULL), + _gnutls_bin2hex(secret, secret_size, + secret_hex, sizeof(secret_hex), NULL)); + fflush(keylog); + GNUTLS_STATIC_MUTEX_UNLOCK(keylog_mutex); + } +} + +void _gnutls_nss_keylog_deinit(void) +{ + if (keylog) { + fclose(keylog); + keylog = NULL; + } } /* here we generate the TLS Master secret. @@ -168,7 +182,9 @@ generate_normal_master(gnutls_session_t session, gnutls_free(shash.data); } - write_nss_key_log(session, premaster); + _gnutls_nss_keylog_write(session, "CLIENT_RANDOM", + session->security_parameters.master_secret, + GNUTLS_MASTER_SIZE); if (!keep_premaster) _gnutls_free_temp_key_datum(premaster); @@ -35,3 +35,6 @@ int _gnutls_recv_server_crt_request(gnutls_session_t session); int _gnutls_send_server_crt_request(gnutls_session_t session, int again); int _gnutls_recv_client_certificate_verify_message(gnutls_session_t session); +void _gnutls_nss_keylog_write(gnutls_session_t session, + const char *label, + const uint8_t *secret, size_t secret_size); |