1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

openssl: support SSLKEYLOGFILE client secret logging

This patch checks for the env var SSLKEYLOGFILE=path, if present, then
client connection tls secrets are appended into path.vhostname.

This allows decryption of captured encrypted data for debugging purposes.

SSKEYLOGFILE=path env var method is the same as provided by Firefox and
Chrome for this purpose.
This commit is contained in:
Andy Green 2021-12-07 08:31:17 +00:00
parent e88a1b1b32
commit b8c4820be4
6 changed files with 88 additions and 0 deletions

View file

@ -93,6 +93,7 @@
#cmakedefine LWS_HAVE_SSL_CTX_load_verify_dir
#cmakedefine LWS_HAVE_SSL_CTX_set1_param
#cmakedefine LWS_HAVE_SSL_CTX_set_ciphersuites
#cmakedefine LWS_HAVE_SSL_CTX_set_keylog_callback
#cmakedefine LWS_HAVE_SSL_EXTRA_CHAIN_CERTS
#cmakedefine LWS_HAVE_SSL_get0_alpn_selected
#cmakedefine LWS_HAVE_SSL_CTX_EVP_PKEY_new_raw_private_key

View file

@ -426,6 +426,10 @@ struct lws_context {
#if defined(LWS_WITH_SERVER)
char canonical_hostname[96];
#endif
#if defined(LWS_HAVE_SSL_CTX_set_keylog_callback) && \
defined(LWS_WITH_TLS) && defined(LWS_WITH_CLIENT)
char keylog_file[96];
#endif
#if defined(LWS_WITH_FILE_OPS)
struct lws_plat_file_ops fops_platform;

View file

@ -178,6 +178,17 @@ lws_plat_init(struct lws_context *context,
return 1;
}
#if defined(LWS_HAVE_SSL_CTX_set_keylog_callback) && \
defined(LWS_WITH_TLS) && defined(LWS_WITH_CLIENT)
{
char *klf_env = getenv("SSLKEYLOGFILE");
if (klf_env)
lws_strncpy(context->keylog_file, klf_env,
sizeof(context->keylog_file));
}
#endif
#if defined(LWS_WITH_PLUGINS) && !defined(LWS_WITH_PLUGINS_BUILTIN)
{
char *ld_env = getenv("LD_LIBRARY_PATH");

View file

@ -104,6 +104,17 @@ lws_plat_init(struct lws_context *context,
}
#endif
#if defined(LWS_HAVE_SSL_CTX_set_keylog_callback) && \
defined(LWS_WITH_TLS) && defined(LWS_WITH_CLIENT)
{
char *klf_env = getenv("SSLKEYLOGFILE");
if (klf_env)
lws_strncpy(context->keylog_file, klf_env,
sizeof(context->keylog_file));
}
#endif
for (i = 0; i < FD_HASHTABLE_MODULUS; i++) {
context->fd_hashtable[i].wsi =
lws_zalloc(sizeof(struct lws*) * context->max_fds,

View file

@ -344,6 +344,7 @@ CHECK_SYMBOL_EXISTS(${VARIA}SSL_CTX_set_ciphersuites LWS_HAVE_SSL_CTX_set_cipher
CHECK_FUNCTION_EXISTS(${VARIA}EVP_PKEY_new_raw_private_key LWS_HAVE_EVP_PKEY_new_raw_private_key PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}SSL_SESSION_set_time LWS_HAVE_SSL_SESSION_set_time PARENT_SCOPE)
CHECK_SYMBOL_EXISTS(${VARIA}SSL_SESSION_up_ref LWS_HAVE_SSL_SESSION_up_ref PARENT_SCOPE)
CHECK_FUNCTION_EXISTS(${VARIA}SSL_CTX_set_keylog_callback LWS_HAVE_SSL_CTX_set_keylog_callback PARENT_SCOPE)
# deprecated in openssl v3

View file

@ -705,6 +705,60 @@ lws_tls_client_vhost_extra_cert_mem(struct lws_vhost *vh,
return n != 1;
}
#if defined(LWS_HAVE_SSL_CTX_set_keylog_callback) && \
defined(LWS_WITH_TLS) && defined(LWS_WITH_CLIENT)
static void
lws_klog_dump(const SSL *ssl, const char *line)
{
struct lws *wsi = SSL_get_ex_data(ssl,
openssl_websocket_private_data_index);
char path[128], hdr[128], ts[64];
size_t w = 0, wx = 0;
int fd, t;
if (!wsi || !wsi->a.context->keylog_file[0] || !wsi->a.vhost)
return;
lws_snprintf(path, sizeof(path), "%s.%s", wsi->a.context->keylog_file,
wsi->a.vhost->name);
fd = open(path, O_CREAT | O_RDWR | O_APPEND, 0600);
if (fd == -1) {
lwsl_vhost_warn(wsi->a.vhost, "Failed to append %s", path);
return;
}
/* the first item in the chunk */
if (!strncmp(line, "SERVER_HANDSHAKE_TRAFFIC_SECRET", 31)) {
w += (size_t)write(fd, "\n# ", 3);
wx += 3;
t = lwsl_timestamp(LLL_WARN, ts, sizeof(ts));
wx += (size_t)t;
w += (size_t)write(fd, ts, (size_t)t);
t = lws_snprintf(hdr, sizeof(hdr), "%s\n", wsi->lc.gutag);
w += (size_t)write(fd, hdr, (size_t)t);
wx += (size_t)t;
lwsl_vhost_warn(wsi->a.vhost, "appended ssl keylog: %s", path);
}
wx += strlen(line) + 1;
w += (size_t)write(fd, line,
#if defined(WIN32)
(unsigned int)
#endif
strlen(line));
w += (size_t)write(fd, "\n", 1);
close(fd);
if (w != wx) {
lwsl_vhost_warn(wsi->a.vhost, "Failed to write %s", path);
return;
}
}
#endif
int
lws_tls_client_create_vhost_context(struct lws_vhost *vh,
const struct lws_context_creation_info *info,
@ -887,6 +941,12 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh,
vh->tls.tcr = tcr;
#if defined(LWS_HAVE_SSL_CTX_set_keylog_callback) && \
defined(LWS_WITH_TLS) && defined(LWS_WITH_CLIENT)
if (vh->context->keylog_file[0])
SSL_CTX_set_keylog_callback(vh->tls.ssl_client_ctx, lws_klog_dump);
#endif
#if defined(LWS_WITH_TLS_SESSIONS)
vh->tls_session_cache_max = info->tls_session_cache_max ?
info->tls_session_cache_max : 10;