From d82df1273c7bca0b7b80528378269104ce8d34f4 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Wed, 10 Apr 2024 16:50:24 +0200 Subject: [PATCH] Add support for `SSLKEYLOGFILE` with OpenSSL GnuTLS has support already built-in. Signed-off-by: Steffen Jaeckel --- src/tls_openssl.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/tls_openssl.c b/src/tls_openssl.c index d9e86c07..7f8c27b7 100644 --- a/src/tls_openssl.c +++ b/src/tls_openssl.c @@ -109,6 +109,7 @@ struct _tls { X509 *client_cert; void *channel_binding_data; size_t channel_binding_size; + FILE *keylogfile; int lasterror; }; @@ -556,6 +557,36 @@ static int _tls_password_callback(char *buf, int size, int rwflag, void *u) return tls_caching_password_callback(buf, size, u); } +#if OPENSSL_VERSION_NUMBER >= 0x10101000L +static void _keylog_cb(const SSL *ssl, const char *line) +{ + xmpp_conn_t *conn = SSL_get_app_data(ssl); + fwrite(line, strlen(line), 1, conn->tls->keylogfile); + fputc('\n', conn->tls->keylogfile); + fflush(conn->tls->keylogfile); +} +#endif + +static void _try_open_keylogfile(tls_t *tls) +{ +#if OPENSSL_VERSION_NUMBER >= 0x10101000L + const char *first_line = "# SSL Key logfile generated by libstrophe\n"; + const char *SSLKEYLOGFILE = getenv("SSLKEYLOGFILE"); + if (!SSLKEYLOGFILE || *SSLKEYLOGFILE == '\0') + return; + tls->keylogfile = fopen(SSLKEYLOGFILE, "abe"); + if (!tls->keylogfile) { + strophe_warn(tls->ctx, "tls", "Could not open SSL keylog file %s", + SSLKEYLOGFILE); + return; + } + fwrite(first_line, strlen(first_line), 1, tls->keylogfile); + SSL_CTX_set_keylog_callback(tls->ssl_ctx, _keylog_cb); +#else + UNUSED(tls); +#endif +} + tls_t *tls_new(xmpp_conn_t *conn) { tls_t *tls = strophe_alloc(conn->ctx, sizeof(*tls)); @@ -699,6 +730,8 @@ tls_t *tls_new(xmpp_conn_t *conn) ret = SSL_set_fd(tls->ssl, conn->sock); if (ret <= 0) goto err_free_ssl; + + _try_open_keylogfile(tls); } return tls; @@ -717,6 +750,8 @@ tls_t *tls_new(xmpp_conn_t *conn) void tls_free(tls_t *tls) { + if (tls->keylogfile) + fclose(tls->keylogfile); strophe_free(tls->ctx, tls->channel_binding_data); SSL_free(tls->ssl); X509_free(tls->client_cert);