]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
rustls: Add support for SSLKEYLOGFILE
authorYedaya Katsman <yedaya.ka@gmail.com>
Mon, 21 Oct 2024 20:28:28 +0000 (23:28 +0300)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 27 Mar 2025 07:47:43 +0000 (08:47 +0100)
With rustls-ffi 0.15+ we can set up a callback for writing TLS secrets
hooked up to call Curl_tls_keylog_write. To make sure the associated
file is cleaned up we update the Curl_ssl struct for the rustls-ffi vtls
backend to have a cleanup callback.

Closes #16828

docs/cmdline-opts/_ENVIRONMENT.md
lib/vtls/keylog.c
lib/vtls/rustls.c

index 97c75bcb723f8fa110e7f8fc8261cd089231e973..d415f2aa19da20e517b92110986b9bb198cb759d 100644 (file)
@@ -102,7 +102,7 @@ If you set this environment variable to a filename, curl stores TLS secrets
 from its connections in that file when invoked to enable you to analyze the
 TLS traffic in real time using network analyzing tools such as Wireshark. This
 works with the following TLS backends: OpenSSL, LibreSSL (TLS 1.2 max),
-BoringSSL, GnuTLS and wolfSSL.
+BoringSSL, GnuTLS, wolfSSL and Rustls.
 
 ## `USERPROFILE` <dir>
 On Windows, this variable is used when trying to find the home directory. If
index 32ccd38cc7b891734977ee6bac868313d50729e1..1e76845b33153346690e679c5a85b045d55541b0 100644 (file)
@@ -27,7 +27,8 @@
   defined(USE_GNUTLS) || \
   defined(USE_WOLFSSL) || \
   (defined(USE_NGTCP2) && defined(USE_NGHTTP3)) || \
-  defined(USE_QUICHE)
+  defined(USE_QUICHE) || \
+  defined(USE_RUSTLS)
 
 #include "keylog.h"
 #include <curl/curl.h>
index 6117ada0d255d905632ed62227b5944aa67e3248..3d5d573c045fea23ab10241dadb22b9910a4a084 100644 (file)
@@ -38,6 +38,7 @@
 #include "vtls.h"
 #include "vtls_int.h"
 #include "rustls.h"
+#include "keylog.h"
 #include "strerror.h"
 #include "cipher_suite.h"
 #include "x509asn1.h"
@@ -518,6 +519,19 @@ add_ciphers:
   *selected_size = count;
 }
 
+static void
+cr_keylog_log_cb(struct rustls_str label,
+                 const uint8_t *client_random, size_t client_random_len,
+                 const uint8_t *secret, size_t secret_len)
+{
+  char clabel[KEYLOG_LABEL_MAXLEN];
+  (void)client_random_len;
+  DEBUGASSERT(client_random_len == CLIENT_RANDOM_SIZE);
+  /* Turning a "rustls_str" into a null delimited "c" string */
+  msnprintf(clabel, label.len + 1, "%.*s", (int)label.len, label.data);
+  Curl_tls_keylog_write(clabel, client_random, secret, secret_len);
+}
+
 static CURLcode
 init_config_builder(struct Curl_easy *data,
                     const struct ssl_primary_config *conn_config,
@@ -774,6 +788,29 @@ cleanup:
   return result;
 }
 
+static CURLcode
+init_config_builder_keylog(struct Curl_easy *data,
+                           struct rustls_client_config_builder *builder)
+{
+  rustls_result rr;
+
+  Curl_tls_keylog_open();
+  if(!Curl_tls_keylog_enabled()) {
+    return CURLE_OK;
+  }
+
+  rr = rustls_client_config_builder_set_key_log(builder,
+                                                cr_keylog_log_cb,
+                                                NULL);
+  if(rr != RUSTLS_RESULT_OK) {
+    rustls_failf(data, rr, "rustls_client_config_builder_set_key_log");
+    Curl_tls_keylog_close();
+    return map_error(rr);
+  }
+
+  return CURLE_OK;
+}
+
 static CURLcode
 cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
                 struct rustls_ssl_backend_data *const backend)
@@ -819,6 +856,12 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
     }
   }
 
+  result = init_config_builder_keylog(data, config_builder);
+  if(result != CURLE_OK) {
+    rustls_client_config_builder_free(config_builder);
+    return result;
+  }
+
   rr = rustls_client_config_builder_build(
     config_builder,
     &backend->config);
@@ -1125,6 +1168,11 @@ cr_random(struct Curl_easy *data, unsigned char *entropy, size_t length)
   return map_error(rresult);
 }
 
+static void cr_cleanup(void)
+{
+  Curl_tls_keylog_close();
+}
+
 const struct Curl_ssl Curl_ssl_rustls = {
   { CURLSSLBACKEND_RUSTLS, "rustls" },
   SSLSUPP_CAINFO_BLOB |            /* supports */
@@ -1135,7 +1183,7 @@ const struct Curl_ssl Curl_ssl_rustls = {
   sizeof(struct rustls_ssl_backend_data),
 
   NULL,                            /* init */
-  NULL,                            /* cleanup */
+  cr_cleanup,                      /* cleanup */
   cr_version,                      /* version */
   cr_shutdown,                     /* shutdown */
   cr_data_pending,                 /* data_pending */