diff options
author | metamuffin <metamuffin@disroot.org> | 2024-11-25 10:43:05 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-11-25 10:43:17 +0100 |
commit | 163c801aa8ecbc5b037a8c19267893a2bc636f87 (patch) | |
tree | 68c23e26ffcedb8861809652e02553f728f7085b | |
parent | cc5d7c08cca9cb4a14f1f99355262b9b3ff04b0c (diff) | |
download | gnix-163c801aa8ecbc5b037a8c19267893a2bc636f87.tar gnix-163c801aa8ecbc5b037a8c19267893a2bc636f87.tar.bz2 gnix-163c801aa8ecbc5b037a8c19267893a2bc636f87.tar.zst |
support wildcard certificate autoselection
-rw-r--r-- | src/certs.rs | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/src/certs.rs b/src/certs.rs index 84d0fca..05a25c7 100644 --- a/src/certs.rs +++ b/src/certs.rs @@ -19,6 +19,7 @@ use webpki::EndEntityCert; pub struct CertPool { provider: &'static Arc<CryptoProvider>, domains: HashMap<String, Arc<CertifiedKey>>, + wildcards: HashMap<String, Arc<CertifiedKey>>, fallback: Option<Arc<CertifiedKey>>, } @@ -27,6 +28,7 @@ impl Default for CertPool { Self { provider: CryptoProvider::get_default().unwrap(), domains: Default::default(), + wildcards: Default::default(), fallback: None, } } @@ -77,9 +79,14 @@ impl CertPool { for c in &certs { let eec = EndEntityCert::try_from(c).unwrap(); for name in eec.valid_dns_names() { - debug!("loaded key for {name:?}"); let ck = CertifiedKey::new(certs.clone(), skey.clone()); - self.domains.insert(name.to_owned(), Arc::new(ck)); + if let Some(name) = name.strip_prefix("*.") { + debug!("loaded wildcard key for {name:?}"); + self.wildcards.insert(name.to_owned(), Arc::new(ck)); + } else { + debug!("loaded key for {name:?}"); + self.domains.insert(name.to_owned(), Arc::new(ck)); + } } } } @@ -89,9 +96,16 @@ impl CertPool { impl ResolvesServerCert for CertPool { fn resolve(&self, client_hello: ClientHello<'_>) -> Option<Arc<CertifiedKey>> { + let sname = client_hello.server_name()?; Some( self.domains - .get(client_hello.server_name()?) + .get(sname) + .or_else(|| { + // Removing first label seems fine since wildcards are not recursive. + sname + .split_once(".") + .and_then(|(_, sname)| self.wildcards.get(sname)) + }) .or(self.fallback.as_ref())? .clone(), ) |