1use std::time::Duration;
4
5use rustls_pki_types::{self as webpki_types, pem::PemObject};
6use serde::{Deserialize, Serialize};
7
8use crate::connection::ServerName;
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct CertificateDer(pub Vec<u8>);
13
14impl CertificateDer {
15 pub fn from_pem_slice(pem: &[u8]) -> Result<Self, PemError> {
17 let der = webpki_types::CertificateDer::from_pem_slice(pem).map_err(|_| PemError {})?;
18
19 Ok(Self(der.to_vec()))
20 }
21}
22
23#[derive(Debug, Clone, zeroize::ZeroizeOnDrop, Serialize, Deserialize)]
25pub struct PrivateKeyDer(pub Vec<u8>);
26
27impl PrivateKeyDer {
28 pub fn from_pem_slice(pem: &[u8]) -> Result<Self, PemError> {
30 let der = webpki_types::PrivateKeyDer::from_pem_slice(pem).map_err(|_| PemError {})?;
31
32 Ok(Self(der.secret_der().to_vec()))
33 }
34}
35
36#[derive(Debug, thiserror::Error)]
38#[error("failed to parse PEM object")]
39pub struct PemError {}
40
41#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct RootCertStore {
47 pub roots: Vec<CertificateDer>,
49}
50
51impl RootCertStore {
52 pub fn empty() -> Self {
54 Self { roots: Vec::new() }
55 }
56}
57
58#[derive(Debug)]
60pub struct ServerCertVerifier {
61 roots: Vec<webpki_types::TrustAnchor<'static>>,
62}
63
64impl ServerCertVerifier {
65 pub fn new(roots: &RootCertStore) -> Result<Self, ServerCertVerifierError> {
67 let roots = roots
68 .roots
69 .iter()
70 .map(|cert| {
71 webpki::anchor_from_trusted_cert(&webpki_types::CertificateDer::from(
72 cert.0.as_slice(),
73 ))
74 .map(|anchor| anchor.to_owned())
75 .map_err(|err| ServerCertVerifierError::InvalidRootCertificate {
76 cert: cert.clone(),
77 reason: err.to_string(),
78 })
79 })
80 .collect::<Result<Vec<_>, _>>()?;
81
82 Ok(Self { roots })
83 }
84
85 pub fn mozilla() -> Self {
88 Self {
89 roots: webpki_roots::TLS_SERVER_ROOTS.to_vec(),
90 }
91 }
92
93 pub fn verify_server_cert(
103 &self,
104 end_entity: &CertificateDer,
105 intermediates: &[CertificateDer],
106 server_name: &ServerName,
107 time: u64,
108 ) -> Result<(), ServerCertVerifierError> {
109 let cert = webpki_types::CertificateDer::from(end_entity.0.as_slice());
110 let cert = webpki::EndEntityCert::try_from(&cert).map_err(|e| {
111 ServerCertVerifierError::InvalidEndEntityCertificate {
112 cert: end_entity.clone(),
113 reason: e.to_string(),
114 }
115 })?;
116 let intermediates = intermediates
117 .iter()
118 .map(|c| webpki_types::CertificateDer::from(c.0.as_slice()))
119 .collect::<Vec<_>>();
120 let server_name = server_name.to_webpki();
121 let time = webpki_types::UnixTime::since_unix_epoch(Duration::from_secs(time));
122
123 cert.verify_for_usage(
124 webpki::ALL_VERIFICATION_ALGS,
125 &self.roots,
126 &intermediates,
127 time,
128 webpki::KeyUsage::server_auth(),
129 None,
130 None,
131 )
132 .map(|_| ())
133 .map_err(|_| ServerCertVerifierError::InvalidPath)?;
134
135 cert.verify_is_valid_for_subject_name(&server_name)
136 .map_err(|_| ServerCertVerifierError::InvalidServerName)?;
137
138 Ok(())
139 }
140}
141
142#[derive(Debug, thiserror::Error)]
144#[error("server certificate verification failed: {0}")]
145pub enum ServerCertVerifierError {
146 #[error("root certificate store contains invalid certificate: {reason}")]
148 InvalidRootCertificate {
149 cert: CertificateDer,
151 reason: String,
153 },
154 #[error("end-entity certificate is invalid: {reason}")]
156 InvalidEndEntityCertificate {
157 cert: CertificateDer,
159 reason: String,
161 },
162 #[error("failed to verify certificate path to provided trust anchors")]
164 InvalidPath,
165 #[error("failed to verify certificate is valid for provided server name")]
167 InvalidServerName,
168}