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:
parent
e88a1b1b32
commit
b8c4820be4
6 changed files with 88 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue