summaryrefslogtreecommitdiff
path: root/src/certs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/certs.rs')
-rw-r--r--src/certs.rs24
1 files changed, 22 insertions, 2 deletions
diff --git a/src/certs.rs b/src/certs.rs
index 27aab51..84d0fca 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>>,
+ fallback: Option<Arc<CertifiedKey>>,
}
impl Default for CertPool {
@@ -26,16 +27,30 @@ impl Default for CertPool {
Self {
provider: CryptoProvider::get_default().unwrap(),
domains: Default::default(),
+ fallback: None,
}
}
}
impl CertPool {
- pub fn load(roots: &[PathBuf]) -> Result<Self> {
+ pub fn load(roots: &[PathBuf], fallback: Option<PathBuf>) -> Result<Self> {
let mut s = Self::default();
for r in roots {
s.load_recursive(&r)?;
}
+ if let Some(path) = fallback {
+ let keypath = path.join("privkey.pem");
+ let certpath = if path.join("fullchain.pem").exists() {
+ path.join("fullchain.pem")
+ } else {
+ path.join("cert.pem")
+ };
+ let certs = load_certs(&certpath)?;
+ let key = load_private_key(&keypath)?;
+ let skey = s.provider.key_provider.load_private_key(key)?;
+ let ck = CertifiedKey::new(certs.clone(), skey.clone());
+ s.fallback = Some(Arc::new(ck))
+ }
Ok(s)
}
@@ -74,7 +89,12 @@ impl CertPool {
impl ResolvesServerCert for CertPool {
fn resolve(&self, client_hello: ClientHello<'_>) -> Option<Arc<CertifiedKey>> {
- Some(self.domains.get(client_hello.server_name()?)?.clone())
+ Some(
+ self.domains
+ .get(client_hello.server_name()?)
+ .or(self.fallback.as_ref())?
+ .clone(),
+ )
}
}