Pass client certs

This commit is contained in:
Pascal Engélibert 2026-02-27 13:48:57 +01:00
commit c6a30519e2
2 changed files with 47 additions and 4 deletions

View file

@ -24,6 +24,10 @@ use tokio_rustls::{
danger::{HandshakeSignatureValid, ServerCertVerifier},
},
pki_types::ServerName,
pki_types::{
CertificateDer,
pem::{self, PemObject, SectionKind},
},
},
};
@ -90,6 +94,7 @@ pub async fn play(
use_tls: bool,
connect_to: (String, u16),
repeat: u32,
cert_path: Option<&str>,
debug: bool,
) {
// Semaphore used to limit the number of concurrent clients.
@ -124,11 +129,45 @@ pub async fn play(
});
if use_tls {
let mut config = tokio_rustls::rustls::ClientConfig::builder()
let config_builder = tokio_rustls::rustls::ClientConfig::builder();
let mut config = if let Some(cert_path) = cert_path {
let mut certs = tokio_rustls::rustls::RootCertStore::empty();
for file in std::fs::read_dir(cert_path).unwrap_or_else(|e| {
panic!("Cannot read certificate directory `{cert_path}`: {e:?}")
}) {
match file {
Ok(file) => {
if file.file_name().as_encoded_bytes().ends_with(b".crt") {
for section in
<(pem::SectionKind, Vec<u8>) as PemObject>::pem_file_iter(
file.path(),
)
.unwrap()
{
let (kind, data) = section.unwrap();
if kind == SectionKind::Certificate {
let (_rem, cert) =
x509_parser::parse_x509_certificate(&data).unwrap();
if cert.is_ca() {
certs
.add(CertificateDer::from_slice(Box::leak(
data.to_vec().into_boxed_slice(),
)))
.unwrap();
}
}
}
}
}
Err(e) => eprintln!("Error listing cert directory: {e:?}"),
}
}
config_builder.with_root_certificates(certs)
} else {
config_builder.with_platform_verifier().unwrap()
//.dangerous()
//.with_custom_certificate_verifier(Arc::new(DummyCertVerifier))
.with_platform_verifier()
.unwrap()
}
.with_no_client_auth();
let mut enable_early_data = false;
for (var, val) in std::env::vars() {

View file

@ -61,6 +61,9 @@ struct OptClient {
/// Only play this record
#[argp(option)]
record: Option<u64>,
/// Path to PEM certificates (if not provided, use system's certificates)
#[argp(option, short = 'c')]
certs: Option<String>,
/// Print debug info
#[argp(switch, short = 'd')]
debug: bool,
@ -142,6 +145,7 @@ async fn main() {
subopt.tls,
(subopt.connect_addr, subopt.connect_port),
subopt.repeat,
subopt.certs.as_deref(),
subopt.debug,
)
.await;