orca_proxy/acme/
resolver.rs1use std::collections::HashMap;
6use std::sync::{Arc, RwLock};
7
8use rustls::server::{ClientHello, ResolvesServerCert};
9use rustls::sign::CertifiedKey;
10use tracing::debug;
11
12#[derive(Clone, Debug, Default)]
16pub struct DynCertResolver {
17 certs: Arc<RwLock<HashMap<String, Arc<CertifiedKey>>>>,
18}
19
20impl DynCertResolver {
21 pub fn new() -> Self {
22 Self {
23 certs: Arc::new(RwLock::new(HashMap::new())),
24 }
25 }
26
27 pub fn add_cert(&self, domain: &str, key: Arc<CertifiedKey>) {
29 self.certs
30 .write()
31 .expect("cert store poisoned")
32 .insert(domain.to_string(), key);
33 }
34
35 pub fn has_cert(&self, domain: &str) -> bool {
37 self.certs
38 .read()
39 .expect("cert store poisoned")
40 .contains_key(domain)
41 }
42}
43
44impl ResolvesServerCert for DynCertResolver {
45 fn resolve(&self, client_hello: ClientHello<'_>) -> Option<Arc<CertifiedKey>> {
46 let sni = client_hello.server_name()?;
47 let certs = self.certs.read().expect("cert store poisoned");
48 let key = certs.get(sni).cloned();
49 if key.is_none() {
50 debug!(sni, "No cert for SNI hostname");
51 }
52 key
53 }
54}