diff --git a/src/sender/verifier.rs b/src/sender/verifier.rs index afecf56..29ebcb4 100644 --- a/src/sender/verifier.rs +++ b/src/sender/verifier.rs @@ -13,7 +13,21 @@ use { #[derive(Debug)] /// A verifier is used to verify certificates sent by the receiving server -/// during the tls handshake. +/// during the tls handshake. For convenience the [CertificateStore] trait +/// is implemented for [std::collections::HashMap] and +/// [std::collections::BTreeMap], so a Verifier can easily +/// be constructed from those types. +/// +/// This type is passed to [rustls::client::DangerousClientConfig::set_certificate_verifier] +/// in order to allow Tofu certificate validation. +/// # Examples +/// Create a Verifier from a HashMap +/// ``` +/// use std::collections::HashMap; +/// use dory::prelude::{CertificateStore, Verifier}; +/// +/// let verifier: Verifier> = HashMap::new().into(); +/// ``` pub struct Verifier { /// An item which serves as storage for certificates pub store: Arc>, @@ -86,6 +100,8 @@ mod tests { use super::*; const CERT: &[u8] = include_bytes!("../../test/certificates/gemini.example.org/cert.der"); + const FP: &'static str = + include_str!("../../test/certificates/gemini.example.org/fingerprint.txt"); #[test] fn tofu() { @@ -93,7 +109,22 @@ mod tests { let cert = rustls::Certificate(CERT.into()); let name = rustls::ServerName::try_from("gemini.example.org").unwrap(); let now = time::SystemTime::now(); - let mut scts: Vec<&[u8]> = vec![]; - let res = verifier.verify_server_cert(&cert, &[], &name, &mut scts.iter(), &[], now); + let scts: Vec<&[u8]> = vec![]; + let res = + verifier.verify_server_cert(&cert, &[], &name, &mut scts.iter().copied(), &[], now); + assert!(res.is_ok()); + } + + #[test] + fn verify_previously_trusted() { + let verifier: Verifier> = + HashMap::from([("gemini.example.org".to_string(), FP.to_string())]).into(); + let cert = rustls::Certificate(CERT.into()); + let name = rustls::ServerName::try_from("gemini.example.org").unwrap(); + let now = time::SystemTime::now(); + let scts: Vec<&[u8]> = vec![]; + let res = + verifier.verify_server_cert(&cert, &[], &name, &mut scts.iter().copied(), &[], now); + assert!(res.is_ok()); } } diff --git a/test/certificates/gemini.example.org/fingerprint.txt b/test/certificates/gemini.example.org/fingerprint.txt new file mode 100644 index 0000000..cdb7c9e --- /dev/null +++ b/test/certificates/gemini.example.org/fingerprint.txt @@ -0,0 +1 @@ +018a3210fe625b380e2021c1c3a5a6b0092f105e9350b62b72b97b73206fee69 \ No newline at end of file