39 lines
1.6 KiB
Rust
39 lines
1.6 KiB
Rust
use crate::fingerprint::Fingerprint;
|
|
use rustls::{client::{ServerCertVerified, ServerCertVerifier}, Certificate};
|
|
use super::store::CertificateStore;
|
|
|
|
pub struct Verifier<'a, T: CertificateStore> {
|
|
store: &'a T,
|
|
}
|
|
|
|
impl<'a, T: CertificateStore + Sync> ServerCertVerifier for Verifier<'a, T> {
|
|
fn verify_server_cert(
|
|
&self,
|
|
end_entity: &Certificate,
|
|
_intermediates: &[Certificate],
|
|
server_name: &rustls::ServerName,
|
|
_scts: &mut dyn Iterator<Item = &[u8]>,
|
|
_ocsp_response: &[u8],
|
|
_now: std::time::SystemTime,
|
|
) -> Result<ServerCertVerified, rustls::Error> {
|
|
let fp = end_entity.fingerprint().map_err(|e| rustls::Error::General(e.to_string()))?;
|
|
let name = match server_name {
|
|
rustls::ServerName::DnsName(n) => n.as_ref().to_string(),
|
|
rustls::ServerName::IpAddress(ip) => ip.to_string(),
|
|
_ => todo!()
|
|
};
|
|
if let Some(fingerprint) = match server_name {
|
|
rustls::ServerName::DnsName(n) => self.store.get(n.as_ref()),
|
|
rustls::ServerName::IpAddress(ip) => self.store.get(&ip.to_string()),
|
|
_ => todo!(),
|
|
} {
|
|
if fingerprint == fp.1 && name == fp.0 {
|
|
return Ok(ServerCertVerified::assertion());
|
|
}
|
|
} else {
|
|
// todo: need a way to update `self.store`. Probably will require
|
|
// an Arc<Mutex<T>> for interior mutability
|
|
}
|
|
return Err(rustls::Error::General("Unrecognized certificate".to_string()));
|
|
}
|
|
}
|