deltachat/net/tls/
danger.rs1use rustls::RootCertStore;
6use rustls::client::{verify_server_cert_signed_by_trust_anchor, verify_server_name};
7use rustls::pki_types::{CertificateDer, ServerName, UnixTime};
8use rustls::server::ParsedCertificate;
9use tokio_rustls::rustls;
10
11use crate::net::tls::spki::spki_hash;
12
13#[derive(Debug)]
14pub(super) struct CustomCertificateVerifier {
15 root_cert_store: RootCertStore,
17
18 spki_hash: Option<String>,
20}
21
22impl CustomCertificateVerifier {
23 pub(super) fn new(spki_hash: Option<String>) -> Self {
24 let root_cert_store =
25 RootCertStore::from_iter(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
26 Self {
27 root_cert_store,
28 spki_hash,
29 }
30 }
31}
32
33impl rustls::client::danger::ServerCertVerifier for CustomCertificateVerifier {
34 fn verify_server_cert(
35 &self,
36 end_entity: &CertificateDer<'_>,
37 intermediates: &[CertificateDer<'_>],
38 server_name: &ServerName<'_>,
39 _ocsp_response: &[u8],
48 now: UnixTime,
49 ) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
50 let parsed_certificate = ParsedCertificate::try_from(end_entity)?;
51
52 let spki = parsed_certificate.subject_public_key_info();
53
54 let provider = rustls::crypto::ring::default_provider();
55
56 if let ServerName::DnsName(dns_name) = server_name
57 && dns_name.as_ref().starts_with("_")
58 {
59 } else if let Some(hash) = &self.spki_hash
66 && spki_hash(&spki) == *hash
67 {
68 } else {
72 verify_server_cert_signed_by_trust_anchor(
76 &parsed_certificate,
77 &self.root_cert_store,
78 intermediates,
79 now,
80 provider.signature_verification_algorithms.all,
81 )?;
82 }
83
84 verify_server_name(&parsed_certificate, server_name)?;
91 Ok(rustls::client::danger::ServerCertVerified::assertion())
92 }
93
94 fn verify_tls12_signature(
95 &self,
96 message: &[u8],
97 cert: &CertificateDer<'_>,
98 dss: &rustls::DigitallySignedStruct,
99 ) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
100 let provider = rustls::crypto::ring::default_provider();
101 let supported_schemes = &provider.signature_verification_algorithms;
102 rustls::crypto::verify_tls12_signature(message, cert, dss, supported_schemes)
103 }
104
105 fn verify_tls13_signature(
106 &self,
107 message: &[u8],
108 cert: &CertificateDer<'_>,
109 dss: &rustls::DigitallySignedStruct,
110 ) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
111 let provider = rustls::crypto::ring::default_provider();
112 let supported_schemes = &provider.signature_verification_algorithms;
113 rustls::crypto::verify_tls13_signature(message, cert, dss, supported_schemes)
114 }
115
116 fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
117 let provider = rustls::crypto::ring::default_provider();
118 provider
119 .signature_verification_algorithms
120 .supported_schemes()
121 }
122}