Skip to main content

rustls_spiffe/
svid_extractor.rs

1use rustls::pki_types::CertificateDer;
2use spiffe::SpiffeId;
3use tokio::net::TcpStream;
4use tokio_rustls::server::TlsStream;
5use x509_parser::prelude::GeneralName;
6
7/// Extract the leaf [`CertificateDer`] from a [`TlsStream`]
8#[inline]
9#[must_use]
10pub fn extract_leaf_cert(stream: &TlsStream<TcpStream>) -> Option<&CertificateDer<'_>> {
11    let (_, state) = stream.get_ref();
12    let peer_certificates = state.peer_certificates()?;
13    let leaf = peer_certificates.first()?;
14    Some(leaf)
15}
16
17/// Extract a [`SpiffeId`] from a [`CertificateDer`] if the certificate is a valid X509-SVID
18#[inline]
19#[must_use]
20pub fn extract_spiffe_id(leaf: Option<&CertificateDer<'_>>) -> Option<SpiffeId> {
21    let leaf = leaf?;
22    let (_, cert) = x509_parser::parse_x509_certificate(leaf).ok()?;
23    let san = cert.subject_alternative_name().ok()??;
24    let uri = san.value.general_names.iter().find_map(|gn| match gn {
25        GeneralName::URI(uri) => Some(*uri),
26        _ => None,
27    })?;
28    SpiffeId::try_from(uri).ok()
29}