Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#[cfg(feature = "rustls-native-certs")]
use std::io;
use std::sync::Arc;

#[cfg(any(
feature = "rustls-platform-verifier",
feature = "rustls-native-certs",
feature = "webpki-roots"
))]
use rustls::client::WantsClientCert;
use rustls::{ClientConfig, ConfigBuilder, WantsVerifier};
use rustls::{ClientConfig, ConfigBuilder, KeyLog, KeyLogFile, WantsVerifier};
#[cfg(feature = "rustls-native-certs")]
use rustls_native_certs::CertificateResult;
#[cfg(feature = "rustls-platform-verifier")]
Expand Down Expand Up @@ -125,6 +126,38 @@ impl ConfigBuilderExt for ConfigBuilder<ClientConfig, WantsVerifier> {
}
}

/// Methods for enabling TLS key logging on a `ClientConfig`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be tempted to put a warning after this headline similar to the one the Rusts docs have for KeyLog to emphasize this should be used carefully:

Secrets passed over the interface are extremely sensitive and can break the security of past, present and future sessions.

///
/// Naturally, secrets passed over the interface are *extremely*
/// sensitive and can break the security of past, present and
/// future sessions.
pub trait ClientConfigKeyLogExt {
/// Replace the `key_log` sink with a custom implementation.
fn with_key_log(self, key_log: Arc<dyn KeyLog>) -> Self;

/// Replace the `key_log` sink with NSS-style key logging to the file
/// named by `SSLKEYLOGFILE`.
///
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe worth using the word "replace" somewhere here similar to the other fn to emphasize if you call with_key_log(...) and then with_key_log_file(...) it isn't setting up both, it's stomping the first.

/// If `SSLKEYLOGFILE` is unset, this is a no-op (matches `rustls`’ behavior).
fn with_key_log_file(self) -> Self;
}

impl ClientConfigKeyLogExt for ClientConfig {
fn with_key_log(mut self, key_log: Arc<dyn KeyLog>) -> Self {
self.key_log = key_log;

self
}

fn with_key_log_file(mut self) -> Self {
// `KeyLogFile::new()` internally reads SSLKEYLOGFILE and either opens the file
// or becomes a sink that does nothing. Safe to enable unconditionally.
self.key_log = Arc::new(KeyLogFile::new());

self
}
}

mod sealed {
use super::*;

Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ mod log {
pub(crate) use warn_ as warn;
}

pub use crate::config::ConfigBuilderExt;
pub use crate::config::{ClientConfigKeyLogExt, ConfigBuilderExt};
pub use crate::connector::builder::ConnectorBuilder as HttpsConnectorBuilder;
pub use crate::connector::{
DefaultServerNameResolver, FixedServerNameResolver, HttpsConnector, ResolveServerName,
Expand Down
Loading