aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/certs.rs24
-rw-r--r--src/config.rs1
-rw-r--r--src/main.rs2
3 files changed, 24 insertions, 3 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(),
+ )
}
}
diff --git a/src/config.rs b/src/config.rs
index 6a22657..a6f7d1b 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -61,6 +61,7 @@ pub struct HttpsConfig {
pub bind: Vec<SocketAddr>,
#[serde(deserialize_with = "seq_or_not")]
pub cert_path: Vec<PathBuf>,
+ pub cert_fallback: Option<PathBuf>,
}
// try deser Vec<T> but fall back to deser T and putting that in Vec
diff --git a/src/main.rs b/src/main.rs
index 56a9b19..e286924 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -146,7 +146,7 @@ async fn serve_https(state: Arc<State>) -> Result<()> {
None => return Ok(()),
};
let tls_config = {
- let certs = CertPool::load(&https_config.cert_path)?;
+ let certs = CertPool::load(&https_config.cert_path, https_config.cert_fallback.clone())?;
let mut cfg = rustls::ServerConfig::builder()
.with_no_client_auth()
.with_cert_resolver(Arc::new(certs));