1 use sct;
2 use std;
3 use std::sync::Arc;
4 use webpki;
5
6 use crate::anchors::OwnedTrustAnchor;
7 use crate::anchors::{DistinguishedNames, RootCertStore};
8 use crate::error::TLSError;
9 use crate::key::Certificate;
10 #[cfg(feature = "logging")]
11 use crate::log::{debug, trace, warn};
12 use crate::msgs::enums::SignatureScheme;
13 use crate::msgs::handshake::DigitallySignedStruct;
14 use crate::msgs::handshake::SCTList;
15
16 type SignatureAlgorithms = &'static [&'static webpki::SignatureAlgorithm];
17
18 /// Which signature verification mechanisms we support. No particular
19 /// order.
20 static SUPPORTED_SIG_ALGS: SignatureAlgorithms = &[
21 &webpki::ECDSA_P256_SHA256,
22 &webpki::ECDSA_P256_SHA384,
23 &webpki::ECDSA_P384_SHA256,
24 &webpki::ECDSA_P384_SHA384,
25 &webpki::ED25519,
26 &webpki::RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
27 &webpki::RSA_PSS_2048_8192_SHA384_LEGACY_KEY,
28 &webpki::RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
29 &webpki::RSA_PKCS1_2048_8192_SHA256,
30 &webpki::RSA_PKCS1_2048_8192_SHA384,
31 &webpki::RSA_PKCS1_2048_8192_SHA512,
32 &webpki::RSA_PKCS1_3072_8192_SHA384,
33 ];
34
35 /// Marker types. These are used to bind the fact some verification
36 /// (certificate chain or handshake signature) has taken place into
37 /// protocol states. We use this to have the compiler check that there
38 /// are no 'goto fail'-style elisions of important checks before we
39 /// reach the traffic stage.
40 ///
41 /// These types are public, but cannot be directly constructed. This
42 /// means their origins can be precisely determined by looking
43 /// for their `assertion` constructors.
44 pub struct HandshakeSignatureValid(());
45 impl HandshakeSignatureValid {
46 /// Make a `HandshakeSignatureValid`
assertion() -> Self47 pub fn assertion() -> Self {
48 Self { 0: () }
49 }
50 }
51
52 pub struct FinishedMessageVerified(());
53 impl FinishedMessageVerified {
assertion() -> Self54 pub fn assertion() -> Self {
55 Self { 0: () }
56 }
57 }
58
59 /// Zero-sized marker type representing verification of a server cert chain.
60 pub struct ServerCertVerified(());
61 impl ServerCertVerified {
62 /// Make a `ServerCertVerified`
assertion() -> Self63 pub fn assertion() -> Self {
64 Self { 0: () }
65 }
66 }
67
68 /// Zero-sized marker type representing verification of a client cert chain.
69 pub struct ClientCertVerified(());
70 impl ClientCertVerified {
71 /// Make a `ClientCertVerified`
assertion() -> Self72 pub fn assertion() -> Self {
73 Self { 0: () }
74 }
75 }
76
77 /// Something that can verify a server certificate chain, and verify
78 /// signatures made by certificates.
79 pub trait ServerCertVerifier: Send + Sync {
80 /// Verify a the certificate chain `presented_certs` against the roots
81 /// configured in `roots`. Make sure that `dns_name` is quoted by
82 /// the top certificate in the chain.
verify_server_cert( &self, roots: &RootCertStore, presented_certs: &[Certificate], dns_name: webpki::DNSNameRef, ocsp_response: &[u8], ) -> Result<ServerCertVerified, TLSError>83 fn verify_server_cert(
84 &self,
85 roots: &RootCertStore,
86 presented_certs: &[Certificate],
87 dns_name: webpki::DNSNameRef,
88 ocsp_response: &[u8],
89 ) -> Result<ServerCertVerified, TLSError>;
90
91 /// Verify a signature allegedly by the given server certificate.
92 ///
93 /// `message` is not hashed, and needs hashing during the verification.
94 /// The signature and algorithm are within `dss`. `cert` contains the
95 /// public key to use.
96 ///
97 /// `cert` is the same certificate that was previously validated by a
98 /// call to `verify_server_cert`.
99 ///
100 /// If and only if the signature is valid, return HandshakeSignatureValid.
101 /// Otherwise, return an error -- rustls will send an alert and abort the
102 /// connection.
103 ///
104 /// This method is only called for TLS1.2 handshakes. Note that, in TLS1.2,
105 /// SignatureSchemes such as `SignatureScheme::ECDSA_NISTP256_SHA256` are not
106 /// in fact bound to the specific curve implied in their name.
107 ///
108 /// This trait method has a default implementation that uses webpki to verify
109 /// the signature.
verify_tls12_signature( &self, message: &[u8], cert: &Certificate, dss: &DigitallySignedStruct, ) -> Result<HandshakeSignatureValid, TLSError>110 fn verify_tls12_signature(
111 &self,
112 message: &[u8],
113 cert: &Certificate,
114 dss: &DigitallySignedStruct,
115 ) -> Result<HandshakeSignatureValid, TLSError> {
116 verify_signed_struct(message, cert, dss)
117 }
118
119
120 /// Verify a signature allegedly by the given server certificate.
121 ///
122 /// This method is only called for TLS1.3 handshakes.
123 ///
124 /// This method is very similar to `verify_tls12_signature`: but note the
125 /// tighter ECDSA SignatureScheme semantics -- eg `SignatureScheme::ECDSA_NISTP256_SHA256`
126 /// must only validate signatures using public keys on the right curve --
127 /// rustls does not enforce this requirement for you.
128 ///
129 /// This trait method has a default implementation that uses webpki to verify
130 /// the signature.
verify_tls13_signature( &self, message: &[u8], cert: &Certificate, dss: &DigitallySignedStruct, ) -> Result<HandshakeSignatureValid, TLSError>131 fn verify_tls13_signature(
132 &self,
133 message: &[u8],
134 cert: &Certificate,
135 dss: &DigitallySignedStruct,
136 ) -> Result<HandshakeSignatureValid, TLSError> {
137 verify_tls13(message, cert, dss)
138 }
139
140 /// Return the list of SignatureSchemes that this verifier will handle,
141 /// in `verify_tls12_signature` and `verify_tls13_signature` calls.
142 ///
143 /// This should be in priority order, with the most preferred first.
144 ///
145 /// This trait mehod has a default implementation that reflects the schemes
146 /// supported by webpki.
supported_verify_schemes(&self) -> Vec<SignatureScheme>147 fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
148 WebPKIVerifier::verification_schemes()
149 }
150 }
151
152 /// Something that can verify a client certificate chain
153 pub trait ClientCertVerifier: Send + Sync {
154 /// Returns `true` to enable the server to request a client certificate and
155 /// `false` to skip requesting a client certificate. Defaults to `true`.
offer_client_auth(&self) -> bool156 fn offer_client_auth(&self) -> bool {
157 true
158 }
159
160 /// Return `Some(true)` to require a client certificate and `Some(false)` to make
161 /// client authentication optional. Return `None` to abort the connection.
162 /// Defaults to `Some(self.offer_client_auth())`.
163 ///
164 /// `sni` is the server name quoted by the client in its ClientHello; it has
165 /// been validated as a proper DNS name but is otherwise untrusted.
client_auth_mandatory(&self, _sni: Option<&webpki::DNSName>) -> Option<bool>166 fn client_auth_mandatory(&self, _sni: Option<&webpki::DNSName>) -> Option<bool> {
167 Some(self.offer_client_auth())
168 }
169
170 /// Returns the subject names of the client authentication trust anchors to
171 /// share with the client when requesting client authentication.
172 ///
173 /// Return `None` to abort the connection.
174 ///
175 /// `sni` is the server name quoted by the client in its ClientHello; it has
176 /// been validated as a proper DNS name but is otherwise untrusted.
client_auth_root_subjects( &self, sni: Option<&webpki::DNSName>, ) -> Option<DistinguishedNames>177 fn client_auth_root_subjects(
178 &self,
179 sni: Option<&webpki::DNSName>,
180 ) -> Option<DistinguishedNames>;
181
182 /// Verify a certificate chain. `presented_certs` is the certificate chain from the client.
183 ///
184 /// `sni` is the server name quoted by the client in its ClientHello; it has
185 /// been validated as a proper DNS name but is otherwise untrusted.
verify_client_cert( &self, presented_certs: &[Certificate], sni: Option<&webpki::DNSName>, ) -> Result<ClientCertVerified, TLSError>186 fn verify_client_cert(
187 &self,
188 presented_certs: &[Certificate],
189 sni: Option<&webpki::DNSName>,
190 ) -> Result<ClientCertVerified, TLSError>;
191
192 /// Verify a signature allegedly by the given server certificate.
193 ///
194 /// `message` is not hashed, and needs hashing during the verification.
195 /// The signature and algorithm are within `dss`. `cert` contains the
196 /// public key to use.
197 ///
198 /// `cert` is the same certificate that was previously validated by a
199 /// call to `verify_server_cert`.
200 ///
201 /// If and only if the signature is valid, return HandshakeSignatureValid.
202 /// Otherwise, return an error -- rustls will send an alert and abort the
203 /// connection.
204 ///
205 /// This method is only called for TLS1.2 handshakes. Note that, in TLS1.2,
206 /// SignatureSchemes such as `SignatureScheme::ECDSA_NISTP256_SHA256` are not
207 /// in fact bound to the specific curve implied in their name.
208 ///
209 /// This trait method has a default implementation that uses webpki to verify
210 /// the signature.
verify_tls12_signature( &self, message: &[u8], cert: &Certificate, dss: &DigitallySignedStruct, ) -> Result<HandshakeSignatureValid, TLSError>211 fn verify_tls12_signature(
212 &self,
213 message: &[u8],
214 cert: &Certificate,
215 dss: &DigitallySignedStruct,
216 ) -> Result<HandshakeSignatureValid, TLSError> {
217 verify_signed_struct(message, cert, dss)
218 }
219
220
221 /// Verify a signature allegedly by the given server certificate.
222 ///
223 /// This method is only called for TLS1.3 handshakes.
224 ///
225 /// This method is very similar to `verify_tls12_signature`: but note the
226 /// tighter ECDSA SignatureScheme semantics -- eg `SignatureScheme::ECDSA_NISTP256_SHA256`
227 /// must only validate signatures using public keys on the right curve --
228 /// rustls does not enforce this requirement for you.
229 ///
230 /// This trait method has a default implementation that uses webpki to verify
231 /// the signature.
verify_tls13_signature( &self, message: &[u8], cert: &Certificate, dss: &DigitallySignedStruct, ) -> Result<HandshakeSignatureValid, TLSError>232 fn verify_tls13_signature(
233 &self,
234 message: &[u8],
235 cert: &Certificate,
236 dss: &DigitallySignedStruct,
237 ) -> Result<HandshakeSignatureValid, TLSError> {
238 verify_tls13(message, cert, dss)
239 }
240
241 /// Return the list of SignatureSchemes that this verifier will handle,
242 /// in `verify_tls12_signature` and `verify_tls13_signature` calls.
243 ///
244 /// This should be in priority order, with the most preferred first.
245 ///
246 /// This trait mehod has a default implementation that reflects the schemes
247 /// supported by webpki.
supported_verify_schemes(&self) -> Vec<SignatureScheme>248 fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
249 WebPKIVerifier::verification_schemes()
250 }
251 }
252
253 impl ServerCertVerifier for WebPKIVerifier {
254 /// Will verify the certificate is valid in the following ways:
255 /// - Signed by a trusted `RootCertStore` CA
256 /// - Not Expired
257 /// - Valid for DNS entry
258 /// - OCSP data is present
verify_server_cert( &self, roots: &RootCertStore, presented_certs: &[Certificate], dns_name: webpki::DNSNameRef, ocsp_response: &[u8], ) -> Result<ServerCertVerified, TLSError>259 fn verify_server_cert(
260 &self,
261 roots: &RootCertStore,
262 presented_certs: &[Certificate],
263 dns_name: webpki::DNSNameRef,
264 ocsp_response: &[u8],
265 ) -> Result<ServerCertVerified, TLSError> {
266 let (cert, chain, trustroots) = prepare(roots, presented_certs)?;
267 let now = (self.time)()?;
268 let cert = cert
269 .verify_is_valid_tls_server_cert(
270 SUPPORTED_SIG_ALGS,
271 &webpki::TLSServerTrustAnchors(&trustroots),
272 &chain,
273 now,
274 )
275 .map_err(TLSError::WebPKIError)
276 .map(|_| cert)?;
277
278 if !ocsp_response.is_empty() {
279 trace!("Unvalidated OCSP response: {:?}", ocsp_response.to_vec());
280 }
281
282 cert.verify_is_valid_for_dns_name(dns_name)
283 .map_err(TLSError::WebPKIError)
284 .map(|_| ServerCertVerified::assertion())
285 }
286 }
287
288 /// Default `ServerCertVerifier`, see the trait impl for more information.
289 pub struct WebPKIVerifier {
290 /// time provider
291 pub time: fn() -> Result<webpki::Time, TLSError>,
292 }
293
294 impl WebPKIVerifier {
295 /// Create a new `WebPKIVerifier`
new() -> WebPKIVerifier296 pub fn new() -> WebPKIVerifier {
297 WebPKIVerifier { time: try_now }
298 }
299
300 /// Returns the signature verification methods supported by
301 /// webpki.
verification_schemes() -> Vec<SignatureScheme>302 pub fn verification_schemes() -> Vec<SignatureScheme> {
303 vec![
304 SignatureScheme::ECDSA_NISTP384_SHA384,
305 SignatureScheme::ECDSA_NISTP256_SHA256,
306 SignatureScheme::ED25519,
307 SignatureScheme::RSA_PSS_SHA512,
308 SignatureScheme::RSA_PSS_SHA384,
309 SignatureScheme::RSA_PSS_SHA256,
310 SignatureScheme::RSA_PKCS1_SHA512,
311 SignatureScheme::RSA_PKCS1_SHA384,
312 SignatureScheme::RSA_PKCS1_SHA256,
313 ]
314 }
315 }
316
317 type CertChainAndRoots<'a, 'b> = (
318 webpki::EndEntityCert<'a>,
319 Vec<&'a [u8]>,
320 Vec<webpki::TrustAnchor<'b>>,
321 );
322
prepare<'a, 'b>( roots: &'b RootCertStore, presented_certs: &'a [Certificate], ) -> Result<CertChainAndRoots<'a, 'b>, TLSError>323 fn prepare<'a, 'b>(
324 roots: &'b RootCertStore,
325 presented_certs: &'a [Certificate],
326 ) -> Result<CertChainAndRoots<'a, 'b>, TLSError> {
327 if presented_certs.is_empty() {
328 return Err(TLSError::NoCertificatesPresented);
329 }
330
331 // EE cert must appear first.
332 let cert = webpki::EndEntityCert::from(&presented_certs[0].0).map_err(TLSError::WebPKIError)?;
333
334 let chain: Vec<&'a [u8]> = presented_certs
335 .iter()
336 .skip(1)
337 .map(|cert| cert.0.as_ref())
338 .collect();
339
340 let trustroots: Vec<webpki::TrustAnchor> = roots
341 .roots
342 .iter()
343 .map(OwnedTrustAnchor::to_trust_anchor)
344 .collect();
345
346 Ok((cert, chain, trustroots))
347 }
348
try_now() -> Result<webpki::Time, TLSError>349 fn try_now() -> Result<webpki::Time, TLSError> {
350 webpki::Time::try_from(std::time::SystemTime::now())
351 .map_err(|_| TLSError::FailedToGetCurrentTime)
352 }
353
354 /// A `ClientCertVerifier` that will ensure that every client provides a trusted
355 /// certificate, without any name checking.
356 pub struct AllowAnyAuthenticatedClient {
357 roots: RootCertStore,
358 }
359
360 impl AllowAnyAuthenticatedClient {
361 /// Construct a new `AllowAnyAuthenticatedClient`.
362 ///
363 /// `roots` is the list of trust anchors to use for certificate validation.
new(roots: RootCertStore) -> Arc<dyn ClientCertVerifier>364 pub fn new(roots: RootCertStore) -> Arc<dyn ClientCertVerifier> {
365 Arc::new(AllowAnyAuthenticatedClient { roots })
366 }
367 }
368
369 impl ClientCertVerifier for AllowAnyAuthenticatedClient {
offer_client_auth(&self) -> bool370 fn offer_client_auth(&self) -> bool {
371 true
372 }
373
client_auth_mandatory(&self, _sni: Option<&webpki::DNSName>) -> Option<bool>374 fn client_auth_mandatory(&self, _sni: Option<&webpki::DNSName>) -> Option<bool> {
375 Some(true)
376 }
377
client_auth_root_subjects( &self, _sni: Option<&webpki::DNSName>, ) -> Option<DistinguishedNames>378 fn client_auth_root_subjects(
379 &self,
380 _sni: Option<&webpki::DNSName>,
381 ) -> Option<DistinguishedNames> {
382 Some(self.roots.get_subjects())
383 }
384
verify_client_cert( &self, presented_certs: &[Certificate], _sni: Option<&webpki::DNSName>, ) -> Result<ClientCertVerified, TLSError>385 fn verify_client_cert(
386 &self,
387 presented_certs: &[Certificate],
388 _sni: Option<&webpki::DNSName>,
389 ) -> Result<ClientCertVerified, TLSError> {
390 let (cert, chain, trustroots) = prepare(&self.roots, presented_certs)?;
391 let now = try_now()?;
392 cert.verify_is_valid_tls_client_cert(
393 SUPPORTED_SIG_ALGS,
394 &webpki::TLSClientTrustAnchors(&trustroots),
395 &chain,
396 now,
397 )
398 .map_err(TLSError::WebPKIError)
399 .map(|_| ClientCertVerified::assertion())
400 }
401 }
402
403 /// A `ClientCertVerifier` that will allow both anonymous and authenticated
404 /// clients, without any name checking.
405 ///
406 /// Client authentication will be requested during the TLS handshake. If the
407 /// client offers a certificate then this acts like
408 /// `AllowAnyAuthenticatedClient`, otherwise this acts like `NoClientAuth`.
409 pub struct AllowAnyAnonymousOrAuthenticatedClient {
410 inner: AllowAnyAuthenticatedClient,
411 }
412
413 impl AllowAnyAnonymousOrAuthenticatedClient {
414 /// Construct a new `AllowAnyAnonymousOrAuthenticatedClient`.
415 ///
416 /// `roots` is the list of trust anchors to use for certificate validation.
new(roots: RootCertStore) -> Arc<dyn ClientCertVerifier>417 pub fn new(roots: RootCertStore) -> Arc<dyn ClientCertVerifier> {
418 Arc::new(AllowAnyAnonymousOrAuthenticatedClient {
419 inner: AllowAnyAuthenticatedClient { roots },
420 })
421 }
422 }
423
424 impl ClientCertVerifier for AllowAnyAnonymousOrAuthenticatedClient {
offer_client_auth(&self) -> bool425 fn offer_client_auth(&self) -> bool {
426 self.inner.offer_client_auth()
427 }
428
client_auth_mandatory(&self, _sni: Option<&webpki::DNSName>) -> Option<bool>429 fn client_auth_mandatory(&self, _sni: Option<&webpki::DNSName>) -> Option<bool> {
430 Some(false)
431 }
432
client_auth_root_subjects( &self, sni: Option<&webpki::DNSName>, ) -> Option<DistinguishedNames>433 fn client_auth_root_subjects(
434 &self,
435 sni: Option<&webpki::DNSName>,
436 ) -> Option<DistinguishedNames> {
437 self.inner
438 .client_auth_root_subjects(sni)
439 }
440
verify_client_cert( &self, presented_certs: &[Certificate], sni: Option<&webpki::DNSName>, ) -> Result<ClientCertVerified, TLSError>441 fn verify_client_cert(
442 &self,
443 presented_certs: &[Certificate],
444 sni: Option<&webpki::DNSName>,
445 ) -> Result<ClientCertVerified, TLSError> {
446 self.inner
447 .verify_client_cert(presented_certs, sni)
448 }
449 }
450
451 /// Turns off client authentication.
452 pub struct NoClientAuth;
453
454 impl NoClientAuth {
455 /// Constructs a `NoClientAuth` and wraps it in an `Arc`.
new() -> Arc<dyn ClientCertVerifier>456 pub fn new() -> Arc<dyn ClientCertVerifier> {
457 Arc::new(NoClientAuth)
458 }
459 }
460
461 impl ClientCertVerifier for NoClientAuth {
offer_client_auth(&self) -> bool462 fn offer_client_auth(&self) -> bool {
463 false
464 }
465
client_auth_root_subjects( &self, _sni: Option<&webpki::DNSName>, ) -> Option<DistinguishedNames>466 fn client_auth_root_subjects(
467 &self,
468 _sni: Option<&webpki::DNSName>,
469 ) -> Option<DistinguishedNames> {
470 unimplemented!();
471 }
472
verify_client_cert( &self, _presented_certs: &[Certificate], _sni: Option<&webpki::DNSName>, ) -> Result<ClientCertVerified, TLSError>473 fn verify_client_cert(
474 &self,
475 _presented_certs: &[Certificate],
476 _sni: Option<&webpki::DNSName>,
477 ) -> Result<ClientCertVerified, TLSError> {
478 unimplemented!();
479 }
480 }
481
482 static ECDSA_SHA256: SignatureAlgorithms =
483 &[&webpki::ECDSA_P256_SHA256, &webpki::ECDSA_P384_SHA256];
484
485 static ECDSA_SHA384: SignatureAlgorithms =
486 &[&webpki::ECDSA_P256_SHA384, &webpki::ECDSA_P384_SHA384];
487
488 static ED25519: SignatureAlgorithms = &[&webpki::ED25519];
489
490 static RSA_SHA256: SignatureAlgorithms = &[&webpki::RSA_PKCS1_2048_8192_SHA256];
491 static RSA_SHA384: SignatureAlgorithms = &[&webpki::RSA_PKCS1_2048_8192_SHA384];
492 static RSA_SHA512: SignatureAlgorithms = &[&webpki::RSA_PKCS1_2048_8192_SHA512];
493 static RSA_PSS_SHA256: SignatureAlgorithms = &[&webpki::RSA_PSS_2048_8192_SHA256_LEGACY_KEY];
494 static RSA_PSS_SHA384: SignatureAlgorithms = &[&webpki::RSA_PSS_2048_8192_SHA384_LEGACY_KEY];
495 static RSA_PSS_SHA512: SignatureAlgorithms = &[&webpki::RSA_PSS_2048_8192_SHA512_LEGACY_KEY];
496
convert_scheme(scheme: SignatureScheme) -> Result<SignatureAlgorithms, TLSError>497 fn convert_scheme(scheme: SignatureScheme) -> Result<SignatureAlgorithms, TLSError> {
498 match scheme {
499 // nb. for TLS1.2 the curve is not fixed by SignatureScheme.
500 SignatureScheme::ECDSA_NISTP256_SHA256 => Ok(ECDSA_SHA256),
501 SignatureScheme::ECDSA_NISTP384_SHA384 => Ok(ECDSA_SHA384),
502
503 SignatureScheme::ED25519 => Ok(ED25519),
504
505 SignatureScheme::RSA_PKCS1_SHA256 => Ok(RSA_SHA256),
506 SignatureScheme::RSA_PKCS1_SHA384 => Ok(RSA_SHA384),
507 SignatureScheme::RSA_PKCS1_SHA512 => Ok(RSA_SHA512),
508
509 SignatureScheme::RSA_PSS_SHA256 => Ok(RSA_PSS_SHA256),
510 SignatureScheme::RSA_PSS_SHA384 => Ok(RSA_PSS_SHA384),
511 SignatureScheme::RSA_PSS_SHA512 => Ok(RSA_PSS_SHA512),
512
513 _ => {
514 let error_msg = format!("received unadvertised sig scheme {:?}", scheme);
515 Err(TLSError::PeerMisbehavedError(error_msg))
516 }
517 }
518 }
519
verify_sig_using_any_alg( cert: &webpki::EndEntityCert, algs: SignatureAlgorithms, message: &[u8], sig: &[u8], ) -> Result<(), webpki::Error>520 fn verify_sig_using_any_alg(
521 cert: &webpki::EndEntityCert,
522 algs: SignatureAlgorithms,
523 message: &[u8],
524 sig: &[u8],
525 ) -> Result<(), webpki::Error> {
526 // TLS doesn't itself give us enough info to map to a single webpki::SignatureAlgorithm.
527 // Therefore, convert_algs maps to several and we try them all.
528 for alg in algs {
529 match cert.verify_signature(alg, message, sig) {
530 Err(webpki::Error::UnsupportedSignatureAlgorithmForPublicKey) => continue,
531 res => return res,
532 }
533 }
534
535 Err(webpki::Error::UnsupportedSignatureAlgorithmForPublicKey)
536 }
537
verify_signed_struct( message: &[u8], cert: &Certificate, dss: &DigitallySignedStruct, ) -> Result<HandshakeSignatureValid, TLSError>538 fn verify_signed_struct(
539 message: &[u8],
540 cert: &Certificate,
541 dss: &DigitallySignedStruct,
542 ) -> Result<HandshakeSignatureValid, TLSError> {
543 let possible_algs = convert_scheme(dss.scheme)?;
544 let cert = webpki::EndEntityCert::from(&cert.0).map_err(TLSError::WebPKIError)?;
545
546 verify_sig_using_any_alg(&cert, possible_algs, message, &dss.sig.0)
547 .map_err(TLSError::WebPKIError)
548 .map(|_| HandshakeSignatureValid::assertion())
549 }
550
convert_alg_tls13( scheme: SignatureScheme, ) -> Result<&'static webpki::SignatureAlgorithm, TLSError>551 fn convert_alg_tls13(
552 scheme: SignatureScheme,
553 ) -> Result<&'static webpki::SignatureAlgorithm, TLSError> {
554 use crate::msgs::enums::SignatureScheme::*;
555
556 match scheme {
557 ECDSA_NISTP256_SHA256 => Ok(&webpki::ECDSA_P256_SHA256),
558 ECDSA_NISTP384_SHA384 => Ok(&webpki::ECDSA_P384_SHA384),
559 ED25519 => Ok(&webpki::ED25519),
560 RSA_PSS_SHA256 => Ok(&webpki::RSA_PSS_2048_8192_SHA256_LEGACY_KEY),
561 RSA_PSS_SHA384 => Ok(&webpki::RSA_PSS_2048_8192_SHA384_LEGACY_KEY),
562 RSA_PSS_SHA512 => Ok(&webpki::RSA_PSS_2048_8192_SHA512_LEGACY_KEY),
563 _ => {
564 let error_msg = format!("received unsupported sig scheme {:?}", scheme);
565 Err(TLSError::PeerMisbehavedError(error_msg))
566 }
567 }
568 }
569
570 /// Constructs the signature message specified in section 4.4.3 of RFC8446.
construct_tls13_client_verify_message(handshake_hash: &[u8]) -> Vec<u8>571 pub fn construct_tls13_client_verify_message(handshake_hash: &[u8]) -> Vec<u8> {
572 construct_tls13_verify_message(handshake_hash, b"TLS 1.3, client CertificateVerify\x00")
573 }
574
575 /// Constructs the signature message specified in section 4.4.3 of RFC8446.
construct_tls13_server_verify_message(handshake_hash: &[u8]) -> Vec<u8>576 pub fn construct_tls13_server_verify_message(handshake_hash: &[u8]) -> Vec<u8> {
577 construct_tls13_verify_message(handshake_hash, b"TLS 1.3, server CertificateVerify\x00")
578 }
579
construct_tls13_verify_message(handshake_hash: &[u8], context_string_with_0: &[u8]) -> Vec<u8>580 fn construct_tls13_verify_message(handshake_hash: &[u8], context_string_with_0: &[u8]) -> Vec<u8> {
581 let mut msg = Vec::new();
582 msg.resize(64, 0x20u8);
583 msg.extend_from_slice(context_string_with_0);
584 msg.extend_from_slice(handshake_hash);
585 msg
586 }
587
verify_tls13( msg: &[u8], cert: &Certificate, dss: &DigitallySignedStruct, ) -> Result<HandshakeSignatureValid, TLSError>588 fn verify_tls13(
589 msg: &[u8],
590 cert: &Certificate,
591 dss: &DigitallySignedStruct,
592 ) -> Result<HandshakeSignatureValid, TLSError> {
593 let alg = convert_alg_tls13(dss.scheme)?;
594
595
596 let cert = webpki::EndEntityCert::from(&cert.0).map_err(TLSError::WebPKIError)?;
597
598 cert.verify_signature(alg, &msg, &dss.sig.0)
599 .map_err(TLSError::WebPKIError)
600 .map(|_| HandshakeSignatureValid::assertion())
601 }
602
unix_time_millis() -> Result<u64, TLSError>603 fn unix_time_millis() -> Result<u64, TLSError> {
604 std::time::SystemTime::now()
605 .duration_since(std::time::UNIX_EPOCH)
606 .map(|dur| dur.as_secs())
607 .map_err(|_| TLSError::FailedToGetCurrentTime)
608 .and_then(|secs| {
609 secs.checked_mul(1000)
610 .ok_or(TLSError::FailedToGetCurrentTime)
611 })
612 }
613
verify_scts(cert: &Certificate, scts: &SCTList, logs: &[&sct::Log]) -> Result<(), TLSError>614 pub fn verify_scts(cert: &Certificate, scts: &SCTList, logs: &[&sct::Log]) -> Result<(), TLSError> {
615 let mut valid_scts = 0;
616 let now = unix_time_millis()?;
617 let mut last_sct_error = None;
618
619 for sct in scts {
620 #[cfg_attr(not(feature = "logging"), allow(unused_variables))]
621 match sct::verify_sct(&cert.0, &sct.0, now, logs) {
622 Ok(index) => {
623 debug!(
624 "Valid SCT signed by {} on {}",
625 logs[index].operated_by, logs[index].description
626 );
627 valid_scts += 1;
628 }
629 Err(e) => {
630 if e.should_be_fatal() {
631 return Err(TLSError::InvalidSCT(e));
632 }
633 debug!("SCT ignored because {:?}", e);
634 last_sct_error = Some(e);
635 }
636 }
637 }
638
639 /* If we were supplied with some logs, and some SCTs,
640 * but couldn't verify any of them, fail the handshake. */
641 if !logs.is_empty() && !scts.is_empty() && valid_scts == 0 {
642 warn!("No valid SCTs provided");
643 return Err(TLSError::InvalidSCT(last_sct_error.unwrap()));
644 }
645
646 Ok(())
647 }
648