From 799ff9ef17ab91b27a1cf96cfbdae8c2a3e6a806 Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Fri, 26 May 2023 18:58:38 -0400 Subject: [PATCH] Added two tests for `Verifier`, covering Tofu success cases. TODO: implement failing tests and check that the proper errors are returned. --- src/sender/verifier.rs | 37 +++++++++++++++++-- .../gemini.example.org/fingerprint.txt | 1 + 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 test/certificates/gemini.example.org/fingerprint.txt 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