/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-0.23.35/src/webpki/mod.rs
Line | Count | Source |
1 | | use alloc::vec::Vec; |
2 | | use core::fmt; |
3 | | |
4 | | use pki_types::CertificateRevocationListDer; |
5 | | use webpki::{CertRevocationList, InvalidNameContext, OwnedCertRevocationList}; |
6 | | |
7 | | use crate::error::{ |
8 | | CertRevocationListError, CertificateError, Error, ExtendedKeyPurpose, OtherError, |
9 | | }; |
10 | | #[cfg(feature = "std")] |
11 | | use crate::sync::Arc; |
12 | | |
13 | | mod anchors; |
14 | | mod client_verifier; |
15 | | mod server_verifier; |
16 | | mod verify; |
17 | | |
18 | | pub use anchors::RootCertStore; |
19 | | pub use client_verifier::{ClientCertVerifierBuilder, WebPkiClientVerifier}; |
20 | | pub use server_verifier::{ServerCertVerifierBuilder, WebPkiServerVerifier}; |
21 | | // Conditionally exported from crate. |
22 | | #[allow(unreachable_pub)] |
23 | | pub use verify::{ |
24 | | ParsedCertificate, verify_server_cert_signed_by_trust_anchor, verify_server_name, |
25 | | }; |
26 | | pub use verify::{ |
27 | | WebPkiSupportedAlgorithms, verify_tls12_signature, verify_tls13_signature, |
28 | | verify_tls13_signature_with_raw_key, |
29 | | }; |
30 | | |
31 | | /// An error that can occur when building a certificate verifier. |
32 | | #[derive(Debug, Clone)] |
33 | | #[non_exhaustive] |
34 | | pub enum VerifierBuilderError { |
35 | | /// No root trust anchors were provided. |
36 | | NoRootAnchors, |
37 | | /// A provided CRL could not be parsed. |
38 | | InvalidCrl(CertRevocationListError), |
39 | | } |
40 | | |
41 | | impl From<CertRevocationListError> for VerifierBuilderError { |
42 | 0 | fn from(value: CertRevocationListError) -> Self { |
43 | 0 | Self::InvalidCrl(value) |
44 | 0 | } |
45 | | } |
46 | | |
47 | | impl fmt::Display for VerifierBuilderError { |
48 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
49 | 0 | match self { |
50 | 0 | Self::NoRootAnchors => write!(f, "no root trust anchors were provided"), |
51 | 0 | Self::InvalidCrl(e) => write!(f, "provided CRL could not be parsed: {e:?}"), |
52 | | } |
53 | 0 | } |
54 | | } |
55 | | |
56 | | #[cfg(feature = "std")] |
57 | | impl std::error::Error for VerifierBuilderError {} |
58 | | |
59 | 0 | fn pki_error(error: webpki::Error) -> Error { |
60 | | use webpki::Error::*; |
61 | 0 | match error { |
62 | 0 | BadDer | BadDerTime | TrailingData(_) => CertificateError::BadEncoding.into(), |
63 | 0 | CertNotValidYet { time, not_before } => { |
64 | 0 | CertificateError::NotValidYetContext { time, not_before }.into() |
65 | | } |
66 | 0 | CertExpired { time, not_after } => { |
67 | 0 | CertificateError::ExpiredContext { time, not_after }.into() |
68 | | } |
69 | 0 | InvalidCertValidity => CertificateError::Expired.into(), |
70 | 0 | UnknownIssuer => CertificateError::UnknownIssuer.into(), |
71 | | CertNotValidForName(InvalidNameContext { |
72 | 0 | expected, |
73 | 0 | presented, |
74 | 0 | }) => CertificateError::NotValidForNameContext { |
75 | 0 | expected, |
76 | 0 | presented, |
77 | 0 | } |
78 | 0 | .into(), |
79 | 0 | CertRevoked => CertificateError::Revoked.into(), |
80 | 0 | UnknownRevocationStatus => CertificateError::UnknownRevocationStatus.into(), |
81 | 0 | CrlExpired { time, next_update } => { |
82 | 0 | CertificateError::ExpiredRevocationListContext { time, next_update }.into() |
83 | | } |
84 | 0 | IssuerNotCrlSigner => CertRevocationListError::IssuerInvalidForCrl.into(), |
85 | | |
86 | 0 | InvalidSignatureForPublicKey => CertificateError::BadSignature.into(), |
87 | | #[allow(deprecated)] |
88 | | UnsupportedSignatureAlgorithm | UnsupportedSignatureAlgorithmForPublicKey => { |
89 | 0 | CertificateError::UnsupportedSignatureAlgorithm.into() |
90 | | } |
91 | 0 | UnsupportedSignatureAlgorithmContext(cx) => { |
92 | 0 | CertificateError::UnsupportedSignatureAlgorithmContext { |
93 | 0 | signature_algorithm_id: cx.signature_algorithm_id, |
94 | 0 | supported_algorithms: cx.supported_algorithms, |
95 | 0 | } |
96 | 0 | .into() |
97 | | } |
98 | 0 | UnsupportedSignatureAlgorithmForPublicKeyContext(cx) => { |
99 | 0 | CertificateError::UnsupportedSignatureAlgorithmForPublicKeyContext { |
100 | 0 | signature_algorithm_id: cx.signature_algorithm_id, |
101 | 0 | public_key_algorithm_id: cx.public_key_algorithm_id, |
102 | 0 | } |
103 | 0 | .into() |
104 | | } |
105 | | |
106 | 0 | InvalidCrlSignatureForPublicKey => CertRevocationListError::BadSignature.into(), |
107 | | #[allow(deprecated)] |
108 | | UnsupportedCrlSignatureAlgorithm | UnsupportedCrlSignatureAlgorithmForPublicKey => { |
109 | 0 | CertRevocationListError::UnsupportedSignatureAlgorithm.into() |
110 | | } |
111 | 0 | UnsupportedCrlSignatureAlgorithmContext(cx) => { |
112 | 0 | CertRevocationListError::UnsupportedSignatureAlgorithmContext { |
113 | 0 | signature_algorithm_id: cx.signature_algorithm_id, |
114 | 0 | supported_algorithms: cx.supported_algorithms, |
115 | 0 | } |
116 | 0 | .into() |
117 | | } |
118 | 0 | UnsupportedCrlSignatureAlgorithmForPublicKeyContext(cx) => { |
119 | 0 | CertRevocationListError::UnsupportedSignatureAlgorithmForPublicKeyContext { |
120 | 0 | signature_algorithm_id: cx.signature_algorithm_id, |
121 | 0 | public_key_algorithm_id: cx.public_key_algorithm_id, |
122 | 0 | } |
123 | 0 | .into() |
124 | | } |
125 | | |
126 | | #[allow(deprecated)] |
127 | 0 | RequiredEkuNotFound => CertificateError::InvalidPurpose.into(), |
128 | 0 | RequiredEkuNotFoundContext(webpki::RequiredEkuNotFoundContext { required, present }) => { |
129 | | CertificateError::InvalidPurposeContext { |
130 | 0 | required: ExtendedKeyPurpose::for_values(required.oid_values()), |
131 | 0 | presented: present |
132 | 0 | .into_iter() |
133 | 0 | .map(|eku| ExtendedKeyPurpose::for_values(eku.into_iter())) |
134 | 0 | .collect(), |
135 | | } |
136 | 0 | .into() |
137 | | } |
138 | | |
139 | 0 | _ => CertificateError::Other(OtherError( |
140 | 0 | #[cfg(feature = "std")] |
141 | 0 | Arc::new(error), |
142 | 0 | )) |
143 | 0 | .into(), |
144 | | } |
145 | 0 | } |
146 | | |
147 | 0 | fn crl_error(e: webpki::Error) -> CertRevocationListError { |
148 | | use webpki::Error::*; |
149 | 0 | match e { |
150 | 0 | InvalidCrlSignatureForPublicKey => CertRevocationListError::BadSignature, |
151 | | #[allow(deprecated)] |
152 | | UnsupportedCrlSignatureAlgorithm | UnsupportedCrlSignatureAlgorithmForPublicKey => { |
153 | 0 | CertRevocationListError::UnsupportedSignatureAlgorithm |
154 | | } |
155 | 0 | UnsupportedCrlSignatureAlgorithmContext(cx) => { |
156 | 0 | CertRevocationListError::UnsupportedSignatureAlgorithmContext { |
157 | 0 | signature_algorithm_id: cx.signature_algorithm_id, |
158 | 0 | supported_algorithms: cx.supported_algorithms, |
159 | 0 | } |
160 | | } |
161 | 0 | UnsupportedSignatureAlgorithmForPublicKeyContext(cx) => { |
162 | 0 | CertRevocationListError::UnsupportedSignatureAlgorithmForPublicKeyContext { |
163 | 0 | signature_algorithm_id: cx.signature_algorithm_id, |
164 | 0 | public_key_algorithm_id: cx.public_key_algorithm_id, |
165 | 0 | } |
166 | | } |
167 | 0 | InvalidCrlNumber => CertRevocationListError::InvalidCrlNumber, |
168 | 0 | InvalidSerialNumber => CertRevocationListError::InvalidRevokedCertSerialNumber, |
169 | 0 | IssuerNotCrlSigner => CertRevocationListError::IssuerInvalidForCrl, |
170 | 0 | MalformedExtensions | BadDer | BadDerTime => CertRevocationListError::ParseError, |
171 | 0 | UnsupportedCriticalExtension => CertRevocationListError::UnsupportedCriticalExtension, |
172 | 0 | UnsupportedCrlVersion => CertRevocationListError::UnsupportedCrlVersion, |
173 | 0 | UnsupportedDeltaCrl => CertRevocationListError::UnsupportedDeltaCrl, |
174 | 0 | UnsupportedIndirectCrl => CertRevocationListError::UnsupportedIndirectCrl, |
175 | 0 | UnsupportedRevocationReason => CertRevocationListError::UnsupportedRevocationReason, |
176 | | |
177 | 0 | _ => CertRevocationListError::Other(OtherError( |
178 | 0 | #[cfg(feature = "std")] |
179 | 0 | Arc::new(e), |
180 | 0 | )), |
181 | | } |
182 | 0 | } |
183 | | |
184 | 0 | fn parse_crls( |
185 | 0 | crls: Vec<CertificateRevocationListDer<'_>>, |
186 | 0 | ) -> Result<Vec<CertRevocationList<'_>>, CertRevocationListError> { |
187 | 0 | crls.iter() |
188 | 0 | .map(|der| OwnedCertRevocationList::from_der(der.as_ref()).map(Into::into)) |
189 | 0 | .collect::<Result<Vec<_>, _>>() |
190 | 0 | .map_err(crl_error) |
191 | 0 | } |
192 | | |
193 | | #[cfg(test)] |
194 | | mod tests { |
195 | | use super::*; |
196 | | use alloc::vec; |
197 | | |
198 | | #[test] |
199 | | fn pki_crl_errors() { |
200 | | // CRL signature errors should be turned into BadSignature. |
201 | | assert_eq!( |
202 | | pki_error(webpki::Error::InvalidCrlSignatureForPublicKey), |
203 | | Error::InvalidCertRevocationList(CertRevocationListError::BadSignature), |
204 | | ); |
205 | | |
206 | | #[allow(deprecated)] |
207 | | { |
208 | | assert_eq!( |
209 | | pki_error(webpki::Error::UnsupportedCrlSignatureAlgorithm), |
210 | | Error::InvalidCertRevocationList( |
211 | | CertRevocationListError::UnsupportedSignatureAlgorithm |
212 | | ), |
213 | | ); |
214 | | assert_eq!( |
215 | | pki_error(webpki::Error::UnsupportedCrlSignatureAlgorithmForPublicKey), |
216 | | Error::InvalidCertRevocationList( |
217 | | CertRevocationListError::UnsupportedSignatureAlgorithm |
218 | | ), |
219 | | ); |
220 | | } |
221 | | |
222 | | assert_eq!( |
223 | | pki_error(webpki::Error::UnsupportedCrlSignatureAlgorithmContext( |
224 | | webpki::UnsupportedSignatureAlgorithmContext { |
225 | | signature_algorithm_id: vec![], |
226 | | supported_algorithms: vec![], |
227 | | } |
228 | | )), |
229 | | Error::InvalidCertRevocationList( |
230 | | CertRevocationListError::UnsupportedSignatureAlgorithmContext { |
231 | | signature_algorithm_id: vec![], |
232 | | supported_algorithms: vec![], |
233 | | } |
234 | | ) |
235 | | ); |
236 | | assert_eq!( |
237 | | pki_error( |
238 | | webpki::Error::UnsupportedCrlSignatureAlgorithmForPublicKeyContext( |
239 | | webpki::UnsupportedSignatureAlgorithmForPublicKeyContext { |
240 | | signature_algorithm_id: vec![], |
241 | | public_key_algorithm_id: vec![], |
242 | | } |
243 | | ) |
244 | | ), |
245 | | Error::InvalidCertRevocationList( |
246 | | CertRevocationListError::UnsupportedSignatureAlgorithmForPublicKeyContext { |
247 | | signature_algorithm_id: vec![], |
248 | | public_key_algorithm_id: vec![], |
249 | | } |
250 | | ) |
251 | | ); |
252 | | |
253 | | // Revoked cert errors should be turned into Revoked. |
254 | | assert_eq!( |
255 | | pki_error(webpki::Error::CertRevoked), |
256 | | Error::InvalidCertificate(CertificateError::Revoked), |
257 | | ); |
258 | | |
259 | | // Issuer not CRL signer errors should be turned into IssuerInvalidForCrl |
260 | | assert_eq!( |
261 | | pki_error(webpki::Error::IssuerNotCrlSigner), |
262 | | Error::InvalidCertRevocationList(CertRevocationListError::IssuerInvalidForCrl) |
263 | | ); |
264 | | } |
265 | | |
266 | | #[test] |
267 | | fn crl_error_from_webpki() { |
268 | | use CertRevocationListError::*; |
269 | | #[allow(deprecated)] |
270 | | let testcases = &[ |
271 | | (webpki::Error::InvalidCrlSignatureForPublicKey, BadSignature), |
272 | | ( |
273 | | webpki::Error::UnsupportedCrlSignatureAlgorithm, |
274 | | UnsupportedSignatureAlgorithm, |
275 | | ), |
276 | | ( |
277 | | webpki::Error::UnsupportedCrlSignatureAlgorithmForPublicKey, |
278 | | UnsupportedSignatureAlgorithm, |
279 | | ), |
280 | | (webpki::Error::InvalidCrlNumber, InvalidCrlNumber), |
281 | | ( |
282 | | webpki::Error::InvalidSerialNumber, |
283 | | InvalidRevokedCertSerialNumber, |
284 | | ), |
285 | | (webpki::Error::IssuerNotCrlSigner, IssuerInvalidForCrl), |
286 | | (webpki::Error::MalformedExtensions, ParseError), |
287 | | (webpki::Error::BadDer, ParseError), |
288 | | (webpki::Error::BadDerTime, ParseError), |
289 | | ( |
290 | | webpki::Error::UnsupportedCriticalExtension, |
291 | | UnsupportedCriticalExtension, |
292 | | ), |
293 | | (webpki::Error::UnsupportedCrlVersion, UnsupportedCrlVersion), |
294 | | (webpki::Error::UnsupportedDeltaCrl, UnsupportedDeltaCrl), |
295 | | ( |
296 | | webpki::Error::UnsupportedIndirectCrl, |
297 | | UnsupportedIndirectCrl, |
298 | | ), |
299 | | ( |
300 | | webpki::Error::UnsupportedRevocationReason, |
301 | | UnsupportedRevocationReason, |
302 | | ), |
303 | | ]; |
304 | | for t in testcases { |
305 | | assert_eq!(crl_error(t.0.clone()), t.1); |
306 | | } |
307 | | |
308 | | assert!(matches!( |
309 | | crl_error(webpki::Error::NameConstraintViolation), |
310 | | Other(..) |
311 | | )); |
312 | | } |
313 | | } |