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