[PATCH] add SSLKEYLOGFILE capability to allow Wireshark TLS decoding of payloads

Alexander Clouter alex+hostapd at coremem.com
Thu Apr 28 15:07:35 PDT 2022


A port of the trivial patch I wrote for FreeRADIUS to allow TLS decoding in Wireshark for hostapd/wpa_supplicant:

https://github.com/FreeRADIUS/freeradius-server/commit/df0eb0a8849611cb44e0baeadfd3e6fcd20bc7b9

Signed-off-by: Alexander Clouter <alex at coremem.com>
---
 src/crypto/tls_openssl.c | 52 ++++++++++++++++++++++++++++++++++++++++
 src/utils/includes.h     |  1 +
 2 files changed, 53 insertions(+)

diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index 6fe816950..ae9eb5d1f 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -1523,6 +1523,53 @@ static void tls_msg_cb(int write_p, int version, int content_type,
 #endif /* CONFIG_SUITEB */
 }
 
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
+/*
+ * By setting the environment variable SSLKEYLOGFILE to a filename keying
+ * material will be exported that you may use with Wireshark to decode any
+ * TLS flows. Please see the following for more details:
+ *
+ *	https://gitlab.com/wireshark/wireshark/-/wikis/TLS#tls-decryption
+ *
+ * Example logging sessions are (you should delete the file on each run):
+ *
+ *	rm -f /tmp/sslkey.log
+ *	env SSLKEYLOGFILE=/tmp/sslkey.log hostapd ...
+ *
+ *	rm -f /tmp/sslkey.log
+ *	env SSLKEYLOGFILE=/tmp/sslkey.log wpa_supplicant ...
+ *
+ *	rm -f /tmp/sslkey.log
+ *	env SSLKEYLOGFILE=/tmp/sslkey.log eapol_test ...
+ */
+static void tls_keylog_cb(const SSL *ssl, const char *line)
+{
+	int fd;
+	const char *filename;
+	struct iovec iov[2];
+
+	filename = getenv("SSLKEYLOGFILE");
+	if (!filename) return;
+
+	fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
+	if (fd < 0) {
+		wpa_printf(MSG_ERROR, "Failed to open file %s: %s", filename, strerror(errno));
+		return;
+	}
+
+	// assume less than _POSIX_PIPE_BUF (512) where writes are guaranteed to be atomic for O_APPEND
+	iov[0].iov_base = (void *)line;
+	iov[0].iov_len = strlen(line);
+	iov[1].iov_base = "\n";
+	iov[1].iov_len = 1;
+
+	if (writev(fd, iov, ARRAY_SIZE(iov)) == -1) {
+		wpa_printf(MSG_DEBUG, "Failed to write to file %s: %s", filename, strerror(errno));
+	}
+
+	close(fd);
+}
+#endif
 
 struct tls_connection * tls_connection_init(void *ssl_ctx)
 {
@@ -1581,6 +1628,11 @@ struct tls_connection * tls_connection_init(void *ssl_ctx)
 	SSL_clear_options(conn->ssl, SSL_OP_ENABLE_MIDDLEBOX_COMPAT);
 #endif
 
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
+	/* Set the keylog file if the admin requested it. */
+	if (getenv("SSLKEYLOGFILE") != NULL) SSL_CTX_set_keylog_callback(conn->ssl_ctx, tls_keylog_cb);
+#endif
+
 	conn->ssl_in = BIO_new(BIO_s_mem());
 	if (!conn->ssl_in) {
 		tls_show_errors(MSG_INFO, __func__,
diff --git a/src/utils/includes.h b/src/utils/includes.h
index 741fc9c14..3922298da 100644
--- a/src/utils/includes.h
+++ b/src/utils/includes.h
@@ -28,6 +28,7 @@
 #include <errno.h>
 #endif /* _WIN32_WCE */
 #include <ctype.h>
+#include <fcntl.h>
 
 #ifndef _MSC_VER
 #include <unistd.h>
-- 
2.30.2



More information about the Hostap mailing list