From 89a8467956328b6193a457841928ad88c535a50b Mon Sep 17 00:00:00 2001 From: Tiga Ultraman Date: Thu, 7 Nov 2024 16:45:56 +0800 Subject: [PATCH] add store keylog file Signed-off-by: Tiga Ultraman --- ylong_http_client/src/async_impl/client.rs | 14 +++++++++++ .../src/util/c_openssl/adapter.rs | 8 +++++++ .../src/util/c_openssl/ffi/callback.rs | 23 ++++++++++++++++++- .../src/util/c_openssl/ffi/ssl.rs | 5 ++++ .../src/util/c_openssl/ssl/ctx.rs | 13 ++++++++--- 5 files changed, 59 insertions(+), 4 deletions(-) diff --git a/ylong_http_client/src/async_impl/client.rs b/ylong_http_client/src/async_impl/client.rs index b505020..03cd8c4 100644 --- a/ylong_http_client/src/async_impl/client.rs +++ b/ylong_http_client/src/async_impl/client.rs @@ -800,6 +800,20 @@ impl ClientBuilder { self } + /// Stores the keying material to SSLKEYLOGFILE. + /// + /// # Examples + /// + /// ``` + /// use ylong_http_client::async_impl::ClientBuilder; + /// + /// let builder = ClientBuilder::new().store_keylog_file(); + /// ``` + pub fn store_keylog_file(mut self) -> Self { + self.tls = self.tls.store_keylog(); + self + } + /// Loads trusted root certificates from a file. The file should contain a /// sequence of PEM-formatted CA certificates. /// diff --git a/ylong_http_client/src/util/c_openssl/adapter.rs b/ylong_http_client/src/util/c_openssl/adapter.rs index d2d5820..39d1aa8 100644 --- a/ylong_http_client/src/util/c_openssl/adapter.rs +++ b/ylong_http_client/src/util/c_openssl/adapter.rs @@ -331,6 +331,14 @@ impl TlsConfigBuilder { self } + pub(crate) fn store_keylog(mut self) -> Self { + self.inner = self.inner.map(|mut builder| { + builder.set_keylog_callback(); + builder + }); + self + } + /// Controls the use of TLS server name indication. /// /// Defaults to `true` -- sets sni. diff --git a/ylong_http_client/src/util/c_openssl/ffi/callback.rs b/ylong_http_client/src/util/c_openssl/ffi/callback.rs index 04d133c..b682fb0 100644 --- a/ylong_http_client/src/util/c_openssl/ffi/callback.rs +++ b/ylong_http_client/src/util/c_openssl/ffi/callback.rs @@ -11,8 +11,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::ffi::{c_int, c_void}; +use std::ffi::{c_char, c_int, c_void, CStr}; +use std::io::Write; +use crate::util::c_openssl::ffi::ssl::SSL; use crate::util::c_openssl::ffi::x509::X509_STORE_CTX; use crate::util::c_openssl::foreign::ForeignRef; use crate::util::c_openssl::x509::X509StoreContextRef; @@ -26,3 +28,22 @@ pub(crate) extern "C" fn cert_verify(ctx: *mut X509_STORE_CTX, arg: *mut c_void) verifier.verify(&ServerCerts::new(ctx)) as c_int } } + +pub(crate) extern "C" fn ssl_ctx_keylog_cb_func(_ssl: *const SSL, line: *const c_char) { + if let Some(path) = std::env::var_os("SSLKEYLOGFILE") { + let mut file = std::fs::OpenOptions::new() + .create(true) + .append(true) + .open(path) + .unwrap(); + + let data = unsafe { CStr::from_ptr(line).to_bytes() }; + + let mut line = Vec::with_capacity(data.len() + 1); + line.extend_from_slice(data); + line.push(b'\n'); + + file.write_all(&line[..]).ok(); + file.flush().ok(); + } +} diff --git a/ylong_http_client/src/util/c_openssl/ffi/ssl.rs b/ylong_http_client/src/util/c_openssl/ffi/ssl.rs index cd5c952..0f1fb22 100644 --- a/ylong_http_client/src/util/c_openssl/ffi/ssl.rs +++ b/ylong_http_client/src/util/c_openssl/ffi/ssl.rs @@ -125,6 +125,11 @@ extern "C" { arg: *mut c_void, ); + pub(crate) fn SSL_CTX_set_keylog_callback( + ctx: *mut SSL_CTX, + callback: Option, + ); + #[cfg(feature = "c_boringssl")] pub(crate) fn SSL_CTX_set_min_proto_version( ctx: *mut SSL_CTX, diff --git a/ylong_http_client/src/util/c_openssl/ssl/ctx.rs b/ylong_http_client/src/util/c_openssl/ssl/ctx.rs index c23bd61..682be09 100644 --- a/ylong_http_client/src/util/c_openssl/ssl/ctx.rs +++ b/ylong_http_client/src/util/c_openssl/ssl/ctx.rs @@ -29,15 +29,15 @@ use crate::util::c_openssl::error::ErrorStack; use crate::util::c_openssl::ffi::ssl::SSL_CTX_ctrl; use crate::util::c_openssl::ffi::ssl::{ SSL_CTX_load_verify_locations, SSL_CTX_new, SSL_CTX_set_alpn_protos, SSL_CTX_set_cert_store, - SSL_CTX_set_cert_verify_callback, SSL_CTX_set_cipher_list, SSL_CTX_up_ref, - SSL_CTX_use_certificate_chain_file, SSL_CTX_use_certificate_file, SSL_CTX, + SSL_CTX_set_cert_verify_callback, SSL_CTX_set_cipher_list, SSL_CTX_set_keylog_callback, + SSL_CTX_up_ref, SSL_CTX_use_certificate_chain_file, SSL_CTX_use_certificate_file, SSL_CTX, }; #[cfg(feature = "c_boringssl")] use crate::util::c_openssl::ffi::ssl::{ SSL_CTX_set1_sigalgs_list, SSL_CTX_set_max_proto_version, SSL_CTX_set_min_proto_version, }; use crate::util::c_openssl::foreign::{Foreign, ForeignRef}; -use crate::util::c_openssl::{cert_verify, check_ptr, check_ret, ssl_init}; +use crate::util::c_openssl::{cert_verify, check_ptr, check_ret, ssl_ctx_keylog_cb_func, ssl_init}; use crate::util::config::tls::DefaultCertVerifier; #[cfg(feature = "__c_openssl")] @@ -266,6 +266,13 @@ impl SslContextBuilder { } } + pub(crate) fn set_keylog_callback(&mut self) { + let ptr = self.as_ptr_mut(); + unsafe { + SSL_CTX_set_keylog_callback(ptr, Some(ssl_ctx_keylog_cb_func)); + } + } + pub(crate) fn set_cert_store(&mut self, cert_store: X509Store) { let ptr = self.as_ptr_mut(); unsafe { -- Gitee