Skip to content

Commit ee2f9fe

Browse files
committed
Add: LeafCertificateVerifier and make all verifier public
1 parent e371e3f commit ee2f9fe

1 file changed

Lines changed: 76 additions & 1 deletion

File tree

crate/tls-cert/src/lib.rs

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::sync::Arc;
2+
13
use rustls::{
24
DigitallySignedStruct, SignatureScheme,
35
client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier},
@@ -24,7 +26,7 @@ pub enum Error {
2426
}
2527

2628
#[derive(Debug)]
27-
pub(crate) struct NoVerifier;
29+
pub struct NoVerifier;
2830

2931
impl ServerCertVerifier for NoVerifier {
3032
fn verify_server_cert(
@@ -64,6 +66,79 @@ impl ServerCertVerifier for NoVerifier {
6466
}
6567
}
6668

69+
/// A TLS verifier adding the ability to match the leaf certificate with a trusted one.
70+
#[derive(Debug)]
71+
pub struct LeafCertificateVerifier {
72+
// The certificate we expect to see in the TLS connection
73+
expected_cert: CertificateDer<'static>,
74+
// A default verifier to run anyway
75+
default_verifier: Arc<dyn ServerCertVerifier>,
76+
}
77+
78+
impl LeafCertificateVerifier {
79+
pub fn new(
80+
expected_cert: &CertificateDer<'static>,
81+
default_verifier: Arc<dyn ServerCertVerifier>,
82+
) -> Self {
83+
Self {
84+
expected_cert: expected_cert.clone(),
85+
default_verifier,
86+
}
87+
}
88+
}
89+
90+
impl ServerCertVerifier for LeafCertificateVerifier {
91+
fn verify_server_cert(
92+
&self,
93+
end_entity: &CertificateDer<'_>,
94+
intermediates: &[CertificateDer<'_>],
95+
server_name: &ServerName<'_>,
96+
ocsp_response: &[u8],
97+
now: UnixTime,
98+
) -> Result<ServerCertVerified, rustls::Error> {
99+
// Verify the leaf certificate
100+
if !end_entity.eq(&self.expected_cert) {
101+
return Err(rustls::Error::General(
102+
"Leaf certificate doesn't match the expected one".to_owned(),
103+
));
104+
}
105+
106+
// Now proceed with typical verifications
107+
self.default_verifier.verify_server_cert(
108+
end_entity,
109+
intermediates,
110+
server_name,
111+
ocsp_response,
112+
now,
113+
)
114+
}
115+
116+
fn verify_tls12_signature(
117+
&self,
118+
_message: &[u8],
119+
_cert: &CertificateDer<'_>,
120+
_dss: &DigitallySignedStruct,
121+
) -> Result<HandshakeSignatureValid, rustls::Error> {
122+
Ok(HandshakeSignatureValid::assertion())
123+
}
124+
125+
fn verify_tls13_signature(
126+
&self,
127+
_message: &[u8],
128+
_cert: &CertificateDer<'_>,
129+
_dss: &DigitallySignedStruct,
130+
) -> Result<HandshakeSignatureValid, rustls::Error> {
131+
Ok(HandshakeSignatureValid::assertion())
132+
}
133+
134+
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
135+
rustls::crypto::aws_lc_rs::default_provider()
136+
.signature_verification_algorithms
137+
.supported_schemes()
138+
.to_vec()
139+
}
140+
}
141+
67142
pub fn get_tls_certificates(host: &str, port: u16) -> Result<Vec<Vec<u8>>, Error> {
68143
// Build TLS config with NO verification
69144
let config = std::sync::Arc::new(

0 commit comments

Comments
 (0)