I am trying to get client certificate information (e.g. SAN(Subject Alternative Name) and fingerprint etc.) based on the mTLS example that s2n-quic provides in the repository: s2n-quic/examples/s2n-mtls at main · aws/s2n-quic · GitHub
I could get SAN value by using with_verify_host_name_callback, but it seems impossible to link that value to connection
.
use s2n_quic::provider::tls::s2n_tls::server::Builder as TlsBuilder;
use s2n_quic::provider::tls::s2n_tls::callbacks::VerifyHostNameCallback;
use s2n_quic::Server;
use std::{error::Error, path::Path};
pub static CA_CERT_PEM: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/certs/ca-cert.pem");
pub static SERVER_CERT_PEM: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/certs/server-cert.pem");
pub static SERVER_KEY_PEM: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/certs/server-key.pem");
struct DumpSan;
impl VerifyHostNameCallback for DumpSan {
fn verify_host_name(&self, host: &str) -> bool {
eprintln!("SAN={host}");
true
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let tls = TlsBuilder::default()
.with_trusted_certificate(Path::new(CA_CERT_PEM))?
.with_certificate(Path::new(SERVER_CERT_PEM), Path::new(SERVER_KEY_PEM))?
.with_client_authentication()?
.with_verify_host_name_callback(DumpSan)?
.build()?;
let mut server = Server::builder()
.with_tls(tls)?
.with_io("127.0.0.1:4433")?
.start()?;
while let Some(mut connection) = server.accept().await {
// spawn a new task for the connection
tokio::spawn(async move {
eprintln!("Connection accepted from {:?}", connection.remote_addr());
eprintln!("Connection Internal ID {:?}", connection.id());
while let Ok(Some(mut stream)) = connection.accept_bidirectional_stream().await {
// spawn a new task for the stream
tokio::spawn(async move {
eprintln!("Stream opened from {:?}", stream.connection().remote_addr());
eprintln!("Stream take_tls_context() {:?}", stream.connection().take_tls_context());
// echo any data back to the stream
while let Ok(Some(data)) = stream.receive().await {
stream.send(data).await.expect("stream should be open");
}
});
}
});
}
Ok(())
}
In order to obtain the client certificate information from connection
, pub fn take_tls_context seems to be useful, but s2n-tls and rustls returns None when I use the function.
I would really appreciate it if you could teach me how to get client certificate information from the connection
.