aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/certs.rs20
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(),
)