rustls/
verify.rs

1use std::fmt;
2
3use crate::anchors::{OwnedTrustAnchor, RootCertStore};
4use crate::client::ServerName;
5use crate::enums::SignatureScheme;
6use crate::error::{
7    CertRevocationListError, CertificateError, Error, InvalidMessage, PeerMisbehaved,
8};
9use crate::key::{Certificate, ParsedCertificate};
10#[cfg(feature = "logging")]
11use crate::log::{debug, trace, warn};
12use crate::msgs::base::PayloadU16;
13use crate::msgs::codec::{Codec, Reader};
14use crate::msgs::handshake::DistinguishedName;
15
16use ring::digest::Digest;
17
18use std::sync::Arc;
19use std::time::SystemTime;
20
21type SignatureAlgorithms = &'static [&'static webpki::SignatureAlgorithm];
22
23/// Which signature verification mechanisms we support.  No particular
24/// order.
25static SUPPORTED_SIG_ALGS: SignatureAlgorithms = &[
26    &webpki::ECDSA_P256_SHA256,
27    &webpki::ECDSA_P256_SHA384,
28    &webpki::ECDSA_P384_SHA256,
29    &webpki::ECDSA_P384_SHA384,
30    &webpki::ED25519,
31    &webpki::RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
32    &webpki::RSA_PSS_2048_8192_SHA384_LEGACY_KEY,
33    &webpki::RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
34    &webpki::RSA_PKCS1_2048_8192_SHA256,
35    &webpki::RSA_PKCS1_2048_8192_SHA384,
36    &webpki::RSA_PKCS1_2048_8192_SHA512,
37    &webpki::RSA_PKCS1_3072_8192_SHA384,
38];
39
40// Marker types.  These are used to bind the fact some verification
41// (certificate chain or handshake signature) has taken place into
42// protocol states.  We use this to have the compiler check that there
43// are no 'goto fail'-style elisions of important checks before we
44// reach the traffic stage.
45//
46// These types are public, but cannot be directly constructed.  This
47// means their origins can be precisely determined by looking
48// for their `assertion` constructors.
49
50/// Zero-sized marker type representing verification of a signature.
51#[derive(Debug)]
52#[cfg_attr(docsrs, doc(cfg(feature = "dangerous_configuration")))]
53pub struct HandshakeSignatureValid(());
54
55impl HandshakeSignatureValid {
56    /// Make a `HandshakeSignatureValid`
57    pub fn assertion() -> Self {
58        Self(())
59    }
60}
61
62#[derive(Debug)]
63pub(crate) struct FinishedMessageVerified(());
64
65impl FinishedMessageVerified {
66    pub(crate) fn assertion() -> Self {
67        Self(())
68    }
69}
70
71/// Zero-sized marker type representing verification of a server cert chain.
72#[allow(unreachable_pub)]
73#[derive(Debug)]
74#[cfg_attr(docsrs, doc(cfg(feature = "dangerous_configuration")))]
75pub struct ServerCertVerified(());
76
77#[allow(unreachable_pub)]
78impl ServerCertVerified {
79    /// Make a `ServerCertVerified`
80    pub fn assertion() -> Self {
81        Self(())
82    }
83}
84
85/// Zero-sized marker type representing verification of a client cert chain.
86#[derive(Debug)]
87#[cfg_attr(docsrs, doc(cfg(feature = "dangerous_configuration")))]
88pub struct ClientCertVerified(());
89
90impl ClientCertVerified {
91    /// Make a `ClientCertVerified`
92    pub fn assertion() -> Self {
93        Self(())
94    }
95}
96
97/// Something that can verify a server certificate chain, and verify
98/// signatures made by certificates.
99#[allow(unreachable_pub)]
100#[cfg_attr(docsrs, doc(cfg(feature = "dangerous_configuration")))]
101pub trait ServerCertVerifier: Send + Sync {
102    /// Verify the end-entity certificate `end_entity` is valid for the
103    /// hostname `dns_name` and chains to at least one trust anchor.
104    ///
105    /// `intermediates` contains all certificates other than `end_entity` that
106    /// were sent as part of the server's [Certificate] message. It is in the
107    /// same order that the server sent them and may be empty.
108    ///
109    /// Note that none of the certificates have been parsed yet, so it is the responsibility of
110    /// the implementor to handle invalid data. It is recommended that the implementor returns
111    /// [`Error::InvalidCertificate(CertificateError::BadEncoding)`] when these cases are encountered.
112    ///
113    /// `scts` contains the Signed Certificate Timestamps (SCTs) the server
114    /// sent with the end-entity certificate, if any.
115    ///
116    /// [Certificate]: https://datatracker.ietf.org/doc/html/rfc8446#section-4.4.2
117    fn verify_server_cert(
118        &self,
119        end_entity: &Certificate,
120        intermediates: &[Certificate],
121        server_name: &ServerName,
122        scts: &mut dyn Iterator<Item = &[u8]>,
123        ocsp_response: &[u8],
124        now: SystemTime,
125    ) -> Result<ServerCertVerified, Error>;
126
127    /// Verify a signature allegedly by the given server certificate.
128    ///
129    /// `message` is not hashed, and needs hashing during the verification.
130    /// The signature and algorithm are within `dss`.  `cert` contains the
131    /// public key to use.
132    ///
133    /// `cert` has already been validated by [`ServerCertVerifier::verify_server_cert`].
134    ///
135    /// If and only if the signature is valid, return `Ok(HandshakeSignatureValid)`.
136    /// Otherwise, return an error -- rustls will send an alert and abort the
137    /// connection.
138    ///
139    /// This method is only called for TLS1.2 handshakes.  Note that, in TLS1.2,
140    /// SignatureSchemes such as `SignatureScheme::ECDSA_NISTP256_SHA256` are not
141    /// in fact bound to the specific curve implied in their name.
142    ///
143    /// This trait method has a default implementation that uses webpki to verify
144    /// the signature.
145    fn verify_tls12_signature(
146        &self,
147        message: &[u8],
148        cert: &Certificate,
149        dss: &DigitallySignedStruct,
150    ) -> Result<HandshakeSignatureValid, Error> {
151        verify_signed_struct(message, cert, dss)
152    }
153
154    /// Verify a signature allegedly by the given server certificate.
155    ///
156    /// This method is only called for TLS1.3 handshakes.
157    ///
158    /// This method is very similar to `verify_tls12_signature`: but note the
159    /// tighter ECDSA SignatureScheme semantics -- e.g. `SignatureScheme::ECDSA_NISTP256_SHA256`
160    /// must only validate signatures using public keys on the right curve --
161    /// rustls does not enforce this requirement for you.
162    ///
163    /// `cert` has already been validated by [`ServerCertVerifier::verify_server_cert`].
164    ///
165    /// If and only if the signature is valid, return `Ok(HandshakeSignatureValid)`.
166    /// Otherwise, return an error -- rustls will send an alert and abort the
167    /// connection.
168    ///
169    /// This trait method has a default implementation that uses webpki to verify
170    /// the signature.
171    fn verify_tls13_signature(
172        &self,
173        message: &[u8],
174        cert: &Certificate,
175        dss: &DigitallySignedStruct,
176    ) -> Result<HandshakeSignatureValid, Error> {
177        verify_tls13(message, cert, dss)
178    }
179
180    /// Return the list of SignatureSchemes that this verifier will handle,
181    /// in `verify_tls12_signature` and `verify_tls13_signature` calls.
182    ///
183    /// This should be in priority order, with the most preferred first.
184    ///
185    /// This trait method has a default implementation that reflects the schemes
186    /// supported by webpki.
187    fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
188        WebPkiVerifier::verification_schemes()
189    }
190
191    /// Returns `true` if Rustls should ask the server to send SCTs.
192    ///
193    /// Signed Certificate Timestamps (SCTs) are used for Certificate
194    /// Transparency validation.
195    ///
196    /// The default implementation of this function returns true.
197    fn request_scts(&self) -> bool {
198        true
199    }
200}
201
202impl fmt::Debug for dyn ServerCertVerifier {
203    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
204        write!(f, "dyn ServerCertVerifier")
205    }
206}
207
208/// Something that can verify a client certificate chain
209#[allow(unreachable_pub)]
210#[cfg_attr(docsrs, doc(cfg(feature = "dangerous_configuration")))]
211pub trait ClientCertVerifier: Send + Sync {
212    /// Returns `true` to enable the server to request a client certificate and
213    /// `false` to skip requesting a client certificate. Defaults to `true`.
214    fn offer_client_auth(&self) -> bool {
215        true
216    }
217
218    /// Return `true` to require a client certificate and `false` to make
219    /// client authentication optional.
220    /// Defaults to `Some(self.offer_client_auth())`.
221    fn client_auth_mandatory(&self) -> bool {
222        self.offer_client_auth()
223    }
224
225    /// Returns the [Subjects] of the client authentication trust anchors to
226    /// share with the client when requesting client authentication.
227    ///
228    /// These must be DER-encoded X.500 distinguished names, per RFC 5280.
229    /// They are sent in the [`certificate_authorities`] extension of a
230    /// [`CertificateRequest`] message.
231    ///
232    /// [Subjects]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6
233    /// [`CertificateRequest`]: https://datatracker.ietf.org/doc/html/rfc8446#section-4.3.2
234    /// [`certificate_authorities`]: https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.4
235    ///
236    /// If the return value is empty, no CertificateRequest message will be sent.
237    fn client_auth_root_subjects(&self) -> &[DistinguishedName];
238
239    /// Verify the end-entity certificate `end_entity` is valid, acceptable,
240    /// and chains to at least one of the trust anchors trusted by
241    /// this verifier.
242    ///
243    /// `intermediates` contains the intermediate certificates the
244    /// client sent along with the end-entity certificate; it is in the same
245    /// order that the peer sent them and may be empty.
246    ///
247    /// Note that none of the certificates have been parsed yet, so it is the responsibility of
248    /// the implementor to handle invalid data. It is recommended that the implementor returns
249    /// an [InvalidCertificate] error with the [BadEncoding] variant when these cases are encountered.
250    ///
251    /// [InvalidCertificate]: Error#variant.InvalidCertificate
252    /// [BadEncoding]: CertificateError#variant.BadEncoding
253    fn verify_client_cert(
254        &self,
255        end_entity: &Certificate,
256        intermediates: &[Certificate],
257        now: SystemTime,
258    ) -> Result<ClientCertVerified, Error>;
259
260    /// Verify a signature allegedly by the given client certificate.
261    ///
262    /// `message` is not hashed, and needs hashing during the verification.
263    /// The signature and algorithm are within `dss`.  `cert` contains the
264    /// public key to use.
265    ///
266    /// `cert` has already been validated by [`ClientCertVerifier::verify_client_cert`].
267    ///
268    /// If and only if the signature is valid, return `Ok(HandshakeSignatureValid)`.
269    /// Otherwise, return an error -- rustls will send an alert and abort the
270    /// connection.
271    ///
272    /// This method is only called for TLS1.2 handshakes.  Note that, in TLS1.2,
273    /// SignatureSchemes such as `SignatureScheme::ECDSA_NISTP256_SHA256` are not
274    /// in fact bound to the specific curve implied in their name.
275    ///
276    /// This trait method has a default implementation that uses webpki to verify
277    /// the signature.
278    fn verify_tls12_signature(
279        &self,
280        message: &[u8],
281        cert: &Certificate,
282        dss: &DigitallySignedStruct,
283    ) -> Result<HandshakeSignatureValid, Error> {
284        verify_signed_struct(message, cert, dss)
285    }
286
287    /// Verify a signature allegedly by the given client certificate.
288    ///
289    /// This method is only called for TLS1.3 handshakes.
290    ///
291    /// This method is very similar to `verify_tls12_signature`, but note the
292    /// tighter ECDSA SignatureScheme semantics in TLS 1.3. For example,
293    /// `SignatureScheme::ECDSA_NISTP256_SHA256`
294    /// must only validate signatures using public keys on the right curve --
295    /// rustls does not enforce this requirement for you.
296    ///
297    /// This trait method has a default implementation that uses webpki to verify
298    /// the signature.
299    fn verify_tls13_signature(
300        &self,
301        message: &[u8],
302        cert: &Certificate,
303        dss: &DigitallySignedStruct,
304    ) -> Result<HandshakeSignatureValid, Error> {
305        verify_tls13(message, cert, dss)
306    }
307
308    /// Return the list of SignatureSchemes that this verifier will handle,
309    /// in `verify_tls12_signature` and `verify_tls13_signature` calls.
310    ///
311    /// This should be in priority order, with the most preferred first.
312    ///
313    /// This trait method has a default implementation that reflects the schemes
314    /// supported by webpki.
315    fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
316        WebPkiVerifier::verification_schemes()
317    }
318}
319
320impl fmt::Debug for dyn ClientCertVerifier {
321    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
322        write!(f, "dyn ClientCertVerifier")
323    }
324}
325
326/// Verify that the end-entity certificate `end_entity` is a valid server cert
327/// and chains to at least one of the [OwnedTrustAnchor] in the `roots` [RootCertStore].
328///
329/// `intermediates` contains all certificates other than `end_entity` that
330/// were sent as part of the server's [Certificate] message. It is in the
331/// same order that the server sent them and may be empty.
332#[allow(dead_code)]
333#[cfg_attr(not(feature = "dangerous_configuration"), allow(unreachable_pub))]
334#[cfg_attr(docsrs, doc(cfg(feature = "dangerous_configuration")))]
335pub fn verify_server_cert_signed_by_trust_anchor(
336    cert: &ParsedCertificate,
337    roots: &RootCertStore,
338    intermediates: &[Certificate],
339    now: SystemTime,
340) -> Result<(), Error> {
341    let chain = intermediate_chain(intermediates);
342    let trust_roots = trust_roots(roots);
343    let webpki_now = webpki::Time::try_from(now).map_err(|_| Error::FailedToGetCurrentTime)?;
344
345    cert.0
346        .verify_for_usage(
347            SUPPORTED_SIG_ALGS,
348            &trust_roots,
349            &chain,
350            webpki_now,
351            webpki::KeyUsage::server_auth(),
352            &[], // no CRLs
353        )
354        .map_err(pki_error)
355        .map(|_| ())
356}
357
358/// Verify that the `end_entity` has a name or alternative name matching the `server_name`
359/// note: this only verifies the name and should be used in conjuction with more verification
360/// like [verify_server_cert_signed_by_trust_anchor]
361#[cfg_attr(not(feature = "dangerous_configuration"), allow(unreachable_pub))]
362#[cfg_attr(docsrs, doc(cfg(feature = "dangerous_configuration")))]
363pub fn verify_server_name(cert: &ParsedCertificate, server_name: &ServerName) -> Result<(), Error> {
364    match server_name {
365        ServerName::DnsName(dns_name) => {
366            // unlikely error because dns_name::DnsNameRef and webpki::DnsNameRef
367            // should have the same encoding rules.
368            let dns_name = webpki::DnsNameRef::try_from_ascii_str(dns_name.as_ref())
369                .map_err(|_| Error::InvalidCertificate(CertificateError::BadEncoding))?;
370            let name = webpki::SubjectNameRef::DnsName(dns_name);
371            cert.0
372                .verify_is_valid_for_subject_name(name)
373                .map_err(pki_error)?;
374        }
375        ServerName::IpAddress(ip_addr) => {
376            let ip_addr = webpki::IpAddr::from(*ip_addr);
377            cert.0
378                .verify_is_valid_for_subject_name(webpki::SubjectNameRef::IpAddress(
379                    webpki::IpAddrRef::from(&ip_addr),
380                ))
381                .map_err(pki_error)?;
382        }
383    }
384    Ok(())
385}
386
387impl ServerCertVerifier for WebPkiVerifier {
388    /// Will verify the certificate is valid in the following ways:
389    /// - Signed by a  trusted `RootCertStore` CA
390    /// - Not Expired
391    /// - Valid for DNS entry
392    fn verify_server_cert(
393        &self,
394        end_entity: &Certificate,
395        intermediates: &[Certificate],
396        server_name: &ServerName,
397        scts: &mut dyn Iterator<Item = &[u8]>,
398        ocsp_response: &[u8],
399        now: SystemTime,
400    ) -> Result<ServerCertVerified, Error> {
401        let cert = ParsedCertificate::try_from(end_entity)?;
402
403        verify_server_cert_signed_by_trust_anchor(&cert, &self.roots, intermediates, now)?;
404
405        if let Some(policy) = &self.ct_policy {
406            policy.verify(end_entity, now, scts)?;
407        }
408
409        if !ocsp_response.is_empty() {
410            trace!("Unvalidated OCSP response: {:?}", ocsp_response.to_vec());
411        }
412
413        verify_server_name(&cert, server_name)?;
414        Ok(ServerCertVerified::assertion())
415    }
416}
417
418/// Default `ServerCertVerifier`, see the trait impl for more information.
419#[allow(unreachable_pub)]
420#[cfg_attr(docsrs, doc(cfg(feature = "dangerous_configuration")))]
421pub struct WebPkiVerifier {
422    roots: Arc<RootCertStore>,
423    ct_policy: Option<CertificateTransparencyPolicy>,
424}
425
426#[allow(unreachable_pub)]
427impl WebPkiVerifier {
428    /// Constructs a new `WebPkiVerifier`.
429    ///
430    /// `roots` is the set of trust anchors to trust for issuing server certs.
431    ///
432    /// `ct_logs` is the list of logs that are trusted for Certificate
433    /// Transparency. Currently CT log enforcement is opportunistic; see
434    /// <https://github.com/rustls/rustls/issues/479>.
435    pub fn new(
436        roots: impl Into<Arc<RootCertStore>>,
437        ct_policy: Option<CertificateTransparencyPolicy>,
438    ) -> Self {
439        Self {
440            roots: roots.into(),
441            ct_policy,
442        }
443    }
444
445    /// Returns the signature verification methods supported by
446    /// webpki.
447    pub fn verification_schemes() -> Vec<SignatureScheme> {
448        vec![
449            SignatureScheme::ECDSA_NISTP384_SHA384,
450            SignatureScheme::ECDSA_NISTP256_SHA256,
451            SignatureScheme::ED25519,
452            SignatureScheme::RSA_PSS_SHA512,
453            SignatureScheme::RSA_PSS_SHA384,
454            SignatureScheme::RSA_PSS_SHA256,
455            SignatureScheme::RSA_PKCS1_SHA512,
456            SignatureScheme::RSA_PKCS1_SHA384,
457            SignatureScheme::RSA_PKCS1_SHA256,
458        ]
459    }
460}
461
462/// Policy for enforcing Certificate Transparency.
463///
464/// Because Certificate Transparency logs are sharded on a per-year basis and can be trusted or
465/// distrusted relatively quickly, rustls stores a validation deadline. Server certificates will
466/// be validated against the configured CT logs until the deadline expires. After the deadline,
467/// certificates will no longer be validated, and a warning message will be logged. The deadline
468/// may vary depending on how often you deploy builds with updated dependencies.
469#[allow(unreachable_pub)]
470#[cfg_attr(docsrs, doc(cfg(feature = "dangerous_configuration")))]
471pub struct CertificateTransparencyPolicy {
472    logs: &'static [&'static sct::Log<'static>],
473    validation_deadline: SystemTime,
474}
475
476impl CertificateTransparencyPolicy {
477    /// Create a new policy.
478    #[allow(unreachable_pub)]
479    pub fn new(
480        logs: &'static [&'static sct::Log<'static>],
481        validation_deadline: SystemTime,
482    ) -> Self {
483        Self {
484            logs,
485            validation_deadline,
486        }
487    }
488
489    fn verify(
490        &self,
491        cert: &Certificate,
492        now: SystemTime,
493        scts: &mut dyn Iterator<Item = &[u8]>,
494    ) -> Result<(), Error> {
495        if self.logs.is_empty() {
496            return Ok(());
497        } else if self
498            .validation_deadline
499            .duration_since(now)
500            .is_err()
501        {
502            warn!("certificate transparency logs have expired, validation disabled");
503            return Ok(());
504        }
505
506        let now = unix_time_millis(now)?;
507        let mut last_sct_error = None;
508        for sct in scts {
509            #[cfg_attr(not(feature = "logging"), allow(unused_variables))]
510            match sct::verify_sct(&cert.0, sct, now, self.logs) {
511                Ok(index) => {
512                    debug!(
513                        "Valid SCT signed by {} on {}",
514                        self.logs[index].operated_by, self.logs[index].description
515                    );
516                    return Ok(());
517                }
518                Err(e) => {
519                    if e.should_be_fatal() {
520                        return Err(Error::InvalidSct(e));
521                    }
522                    debug!("SCT ignored because {:?}", e);
523                    last_sct_error = Some(e);
524                }
525            }
526        }
527
528        /* If we were supplied with some logs, and some SCTs,
529         * but couldn't verify any of them, fail the handshake. */
530        if let Some(last_sct_error) = last_sct_error {
531            warn!("No valid SCTs provided");
532            return Err(Error::InvalidSct(last_sct_error));
533        }
534
535        Ok(())
536    }
537}
538
539fn intermediate_chain(intermediates: &[Certificate]) -> Vec<&[u8]> {
540    intermediates
541        .iter()
542        .map(|cert| cert.0.as_ref())
543        .collect()
544}
545
546fn trust_roots(roots: &RootCertStore) -> Vec<webpki::TrustAnchor> {
547    roots
548        .roots
549        .iter()
550        .map(OwnedTrustAnchor::to_trust_anchor)
551        .collect()
552}
553
554/// An unparsed DER encoded Certificate Revocation List (CRL).
555pub struct UnparsedCertRevocationList(pub Vec<u8>);
556
557impl UnparsedCertRevocationList {
558    /// Parse the CRL DER, yielding a [`webpki::CertRevocationList`] or an error if the CRL
559    /// is malformed, or uses unsupported features.
560    pub fn parse(&self) -> Result<webpki::OwnedCertRevocationList, CertRevocationListError> {
561        webpki::BorrowedCertRevocationList::from_der(&self.0)
562            .and_then(|crl| crl.to_owned())
563            .map_err(CertRevocationListError::from)
564    }
565}
566
567/// A `ClientCertVerifier` that will ensure that every client provides a trusted
568/// certificate, without any name checking. Optionally, client certificates will
569/// have their revocation status checked using the DER encoded CRLs provided.
570pub struct AllowAnyAuthenticatedClient {
571    roots: RootCertStore,
572    subjects: Vec<DistinguishedName>,
573    crls: Vec<webpki::OwnedCertRevocationList>,
574}
575
576impl AllowAnyAuthenticatedClient {
577    /// Construct a new `AllowAnyAuthenticatedClient`.
578    ///
579    /// `roots` is the list of trust anchors to use for certificate validation.
580    pub fn new(roots: RootCertStore) -> Self {
581        Self {
582            subjects: roots
583                .roots
584                .iter()
585                .map(|r| r.subject().clone())
586                .collect(),
587            crls: Vec::new(),
588            roots,
589        }
590    }
591
592    /// Update the verifier to validate client certificates against the provided DER format
593    /// unparsed certificate revocation lists (CRLs).
594    pub fn with_crls(
595        self,
596        crls: impl IntoIterator<Item = UnparsedCertRevocationList>,
597    ) -> Result<Self, CertRevocationListError> {
598        Ok(Self {
599            crls: crls
600                .into_iter()
601                .map(|der_crl| der_crl.parse())
602                .collect::<Result<Vec<_>, CertRevocationListError>>()?,
603            ..self
604        })
605    }
606
607    /// Wrap this verifier in an [`Arc`] and coerce it to `dyn ClientCertVerifier`
608    #[inline(always)]
609    pub fn boxed(self) -> Arc<dyn ClientCertVerifier> {
610        // This function is needed because `ClientCertVerifier` is only reachable if the
611        // `dangerous_configuration` feature is enabled, which makes coercing hard to outside users
612        Arc::new(self)
613    }
614}
615
616impl ClientCertVerifier for AllowAnyAuthenticatedClient {
617    fn offer_client_auth(&self) -> bool {
618        true
619    }
620
621    fn client_auth_root_subjects(&self) -> &[DistinguishedName] {
622        &self.subjects
623    }
624
625    fn verify_client_cert(
626        &self,
627        end_entity: &Certificate,
628        intermediates: &[Certificate],
629        now: SystemTime,
630    ) -> Result<ClientCertVerified, Error> {
631        let cert = ParsedCertificate::try_from(end_entity)?;
632        let chain = intermediate_chain(intermediates);
633        let trust_roots = trust_roots(&self.roots);
634        let now = webpki::Time::try_from(now).map_err(|_| Error::FailedToGetCurrentTime)?;
635
636        #[allow(trivial_casts)] // Cast to &dyn trait is required.
637        let crls = self
638            .crls
639            .iter()
640            .map(|crl| crl as &dyn webpki::CertRevocationList)
641            .collect::<Vec<_>>();
642
643        cert.0
644            .verify_for_usage(
645                SUPPORTED_SIG_ALGS,
646                &trust_roots,
647                &chain,
648                now,
649                webpki::KeyUsage::client_auth(),
650                crls.as_slice(),
651            )
652            .map_err(pki_error)
653            .map(|_| ClientCertVerified::assertion())
654    }
655}
656
657/// A `ClientCertVerifier` that will allow both anonymous and authenticated
658/// clients, without any name checking.
659///
660/// Client authentication will be requested during the TLS handshake. If the
661/// client offers a certificate then this acts like
662/// `AllowAnyAuthenticatedClient`, otherwise this acts like `NoClientAuth`.
663pub struct AllowAnyAnonymousOrAuthenticatedClient {
664    inner: AllowAnyAuthenticatedClient,
665}
666
667impl AllowAnyAnonymousOrAuthenticatedClient {
668    /// Construct a new `AllowAnyAnonymousOrAuthenticatedClient`.
669    ///
670    /// `roots` is the list of trust anchors to use for certificate validation.
671    pub fn new(roots: RootCertStore) -> Self {
672        Self {
673            inner: AllowAnyAuthenticatedClient::new(roots),
674        }
675    }
676
677    /// Update the verifier to validate client certificates against the provided DER format
678    /// unparsed certificate revocation lists (CRLs).
679    pub fn with_crls(
680        self,
681        crls: impl IntoIterator<Item = UnparsedCertRevocationList>,
682    ) -> Result<Self, CertRevocationListError> {
683        Ok(Self {
684            inner: self.inner.with_crls(crls)?,
685        })
686    }
687
688    /// Wrap this verifier in an [`Arc`] and coerce it to `dyn ClientCertVerifier`
689    #[inline(always)]
690    pub fn boxed(self) -> Arc<dyn ClientCertVerifier> {
691        // This function is needed because `ClientCertVerifier` is only reachable if the
692        // `dangerous_configuration` feature is enabled, which makes coercing hard to outside users
693        Arc::new(self)
694    }
695}
696
697impl ClientCertVerifier for AllowAnyAnonymousOrAuthenticatedClient {
698    fn offer_client_auth(&self) -> bool {
699        self.inner.offer_client_auth()
700    }
701
702    fn client_auth_mandatory(&self) -> bool {
703        false
704    }
705
706    fn client_auth_root_subjects(&self) -> &[DistinguishedName] {
707        self.inner.client_auth_root_subjects()
708    }
709
710    fn verify_client_cert(
711        &self,
712        end_entity: &Certificate,
713        intermediates: &[Certificate],
714        now: SystemTime,
715    ) -> Result<ClientCertVerified, Error> {
716        self.inner
717            .verify_client_cert(end_entity, intermediates, now)
718    }
719}
720
721pub(crate) fn pki_error(error: webpki::Error) -> Error {
722    use webpki::Error::*;
723    match error {
724        BadDer | BadDerTime => CertificateError::BadEncoding.into(),
725        CertNotValidYet => CertificateError::NotValidYet.into(),
726        CertExpired | InvalidCertValidity => CertificateError::Expired.into(),
727        UnknownIssuer => CertificateError::UnknownIssuer.into(),
728        CertNotValidForName => CertificateError::NotValidForName.into(),
729        CertRevoked => CertificateError::Revoked.into(),
730        IssuerNotCrlSigner => CertRevocationListError::IssuerInvalidForCrl.into(),
731
732        InvalidSignatureForPublicKey
733        | UnsupportedSignatureAlgorithm
734        | UnsupportedSignatureAlgorithmForPublicKey => CertificateError::BadSignature.into(),
735
736        InvalidCrlSignatureForPublicKey
737        | UnsupportedCrlSignatureAlgorithm
738        | UnsupportedCrlSignatureAlgorithmForPublicKey => {
739            CertRevocationListError::BadSignature.into()
740        }
741
742        _ => CertificateError::Other(Arc::new(error)).into(),
743    }
744}
745
746/// Turns off client authentication.
747pub struct NoClientAuth;
748
749impl NoClientAuth {
750    /// Construct a [`NoClientAuth`], wrap it in an [`Arc`] and coerce it to
751    /// `dyn ClientCertVerifier`.
752    #[inline(always)]
753    pub fn boxed() -> Arc<dyn ClientCertVerifier> {
754        // This function is needed because `ClientCertVerifier` is only reachable if the
755        // `dangerous_configuration` feature is enabled, which makes coercing hard to outside users
756        Arc::new(Self)
757    }
758}
759
760impl ClientCertVerifier for NoClientAuth {
761    fn offer_client_auth(&self) -> bool {
762        false
763    }
764
765    fn client_auth_root_subjects(&self) -> &[DistinguishedName] {
766        unimplemented!();
767    }
768
769    fn verify_client_cert(
770        &self,
771        _end_entity: &Certificate,
772        _intermediates: &[Certificate],
773        _now: SystemTime,
774    ) -> Result<ClientCertVerified, Error> {
775        unimplemented!();
776    }
777}
778
779/// This type combines a [`SignatureScheme`] and a signature payload produced with that scheme.
780#[derive(Debug, Clone)]
781pub struct DigitallySignedStruct {
782    /// The [`SignatureScheme`] used to produce the signature.
783    pub scheme: SignatureScheme,
784    sig: PayloadU16,
785}
786
787impl DigitallySignedStruct {
788    pub(crate) fn new(scheme: SignatureScheme, sig: Vec<u8>) -> Self {
789        Self {
790            scheme,
791            sig: PayloadU16::new(sig),
792        }
793    }
794
795    /// Get the signature.
796    pub fn signature(&self) -> &[u8] {
797        &self.sig.0
798    }
799}
800
801impl Codec for DigitallySignedStruct {
802    fn encode(&self, bytes: &mut Vec<u8>) {
803        self.scheme.encode(bytes);
804        self.sig.encode(bytes);
805    }
806
807    fn read(r: &mut Reader) -> Result<Self, InvalidMessage> {
808        let scheme = SignatureScheme::read(r)?;
809        let sig = PayloadU16::read(r)?;
810
811        Ok(Self { scheme, sig })
812    }
813}
814
815static ECDSA_SHA256: SignatureAlgorithms =
816    &[&webpki::ECDSA_P256_SHA256, &webpki::ECDSA_P384_SHA256];
817
818static ECDSA_SHA384: SignatureAlgorithms =
819    &[&webpki::ECDSA_P256_SHA384, &webpki::ECDSA_P384_SHA384];
820
821static ED25519: SignatureAlgorithms = &[&webpki::ED25519];
822
823static RSA_SHA256: SignatureAlgorithms = &[&webpki::RSA_PKCS1_2048_8192_SHA256];
824static RSA_SHA384: SignatureAlgorithms = &[&webpki::RSA_PKCS1_2048_8192_SHA384];
825static RSA_SHA512: SignatureAlgorithms = &[&webpki::RSA_PKCS1_2048_8192_SHA512];
826static RSA_PSS_SHA256: SignatureAlgorithms = &[&webpki::RSA_PSS_2048_8192_SHA256_LEGACY_KEY];
827static RSA_PSS_SHA384: SignatureAlgorithms = &[&webpki::RSA_PSS_2048_8192_SHA384_LEGACY_KEY];
828static RSA_PSS_SHA512: SignatureAlgorithms = &[&webpki::RSA_PSS_2048_8192_SHA512_LEGACY_KEY];
829
830fn convert_scheme(scheme: SignatureScheme) -> Result<SignatureAlgorithms, Error> {
831    match scheme {
832        // nb. for TLS1.2 the curve is not fixed by SignatureScheme.
833        SignatureScheme::ECDSA_NISTP256_SHA256 => Ok(ECDSA_SHA256),
834        SignatureScheme::ECDSA_NISTP384_SHA384 => Ok(ECDSA_SHA384),
835
836        SignatureScheme::ED25519 => Ok(ED25519),
837
838        SignatureScheme::RSA_PKCS1_SHA256 => Ok(RSA_SHA256),
839        SignatureScheme::RSA_PKCS1_SHA384 => Ok(RSA_SHA384),
840        SignatureScheme::RSA_PKCS1_SHA512 => Ok(RSA_SHA512),
841
842        SignatureScheme::RSA_PSS_SHA256 => Ok(RSA_PSS_SHA256),
843        SignatureScheme::RSA_PSS_SHA384 => Ok(RSA_PSS_SHA384),
844        SignatureScheme::RSA_PSS_SHA512 => Ok(RSA_PSS_SHA512),
845
846        _ => Err(PeerMisbehaved::SignedHandshakeWithUnadvertisedSigScheme.into()),
847    }
848}
849
850fn verify_sig_using_any_alg(
851    cert: &webpki::EndEntityCert,
852    algs: SignatureAlgorithms,
853    message: &[u8],
854    sig: &[u8],
855) -> Result<(), webpki::Error> {
856    // TLS doesn't itself give us enough info to map to a single webpki::SignatureAlgorithm.
857    // Therefore, convert_algs maps to several and we try them all.
858    for alg in algs {
859        match cert.verify_signature(alg, message, sig) {
860            Err(webpki::Error::UnsupportedSignatureAlgorithmForPublicKey) => continue,
861            res => return res,
862        }
863    }
864
865    Err(webpki::Error::UnsupportedSignatureAlgorithmForPublicKey)
866}
867
868fn verify_signed_struct(
869    message: &[u8],
870    cert: &Certificate,
871    dss: &DigitallySignedStruct,
872) -> Result<HandshakeSignatureValid, Error> {
873    let possible_algs = convert_scheme(dss.scheme)?;
874    let cert = webpki::EndEntityCert::try_from(cert.0.as_ref()).map_err(pki_error)?;
875
876    verify_sig_using_any_alg(&cert, possible_algs, message, dss.signature())
877        .map_err(pki_error)
878        .map(|_| HandshakeSignatureValid::assertion())
879}
880
881fn convert_alg_tls13(
882    scheme: SignatureScheme,
883) -> Result<&'static webpki::SignatureAlgorithm, Error> {
884    use crate::enums::SignatureScheme::*;
885
886    match scheme {
887        ECDSA_NISTP256_SHA256 => Ok(&webpki::ECDSA_P256_SHA256),
888        ECDSA_NISTP384_SHA384 => Ok(&webpki::ECDSA_P384_SHA384),
889        ED25519 => Ok(&webpki::ED25519),
890        RSA_PSS_SHA256 => Ok(&webpki::RSA_PSS_2048_8192_SHA256_LEGACY_KEY),
891        RSA_PSS_SHA384 => Ok(&webpki::RSA_PSS_2048_8192_SHA384_LEGACY_KEY),
892        RSA_PSS_SHA512 => Ok(&webpki::RSA_PSS_2048_8192_SHA512_LEGACY_KEY),
893        _ => Err(PeerMisbehaved::SignedHandshakeWithUnadvertisedSigScheme.into()),
894    }
895}
896
897/// Constructs the signature message specified in section 4.4.3 of RFC8446.
898pub(crate) fn construct_tls13_client_verify_message(handshake_hash: &Digest) -> Vec<u8> {
899    construct_tls13_verify_message(handshake_hash, b"TLS 1.3, client CertificateVerify\x00")
900}
901
902/// Constructs the signature message specified in section 4.4.3 of RFC8446.
903pub(crate) fn construct_tls13_server_verify_message(handshake_hash: &Digest) -> Vec<u8> {
904    construct_tls13_verify_message(handshake_hash, b"TLS 1.3, server CertificateVerify\x00")
905}
906
907fn construct_tls13_verify_message(
908    handshake_hash: &Digest,
909    context_string_with_0: &[u8],
910) -> Vec<u8> {
911    let mut msg = Vec::new();
912    msg.resize(64, 0x20u8);
913    msg.extend_from_slice(context_string_with_0);
914    msg.extend_from_slice(handshake_hash.as_ref());
915    msg
916}
917
918fn verify_tls13(
919    msg: &[u8],
920    cert: &Certificate,
921    dss: &DigitallySignedStruct,
922) -> Result<HandshakeSignatureValid, Error> {
923    let alg = convert_alg_tls13(dss.scheme)?;
924
925    let cert = webpki::EndEntityCert::try_from(cert.0.as_ref()).map_err(pki_error)?;
926
927    cert.verify_signature(alg, msg, dss.signature())
928        .map_err(pki_error)
929        .map(|_| HandshakeSignatureValid::assertion())
930}
931
932fn unix_time_millis(now: SystemTime) -> Result<u64, Error> {
933    now.duration_since(std::time::UNIX_EPOCH)
934        .map(|dur| dur.as_secs())
935        .map_err(|_| Error::FailedToGetCurrentTime)
936        .and_then(|secs| {
937            secs.checked_mul(1000)
938                .ok_or(Error::FailedToGetCurrentTime)
939        })
940}
941
942#[cfg(test)]
943mod tests {
944    use super::*;
945
946    #[test]
947    fn assertions_are_debug() {
948        assert_eq!(
949            format!("{:?}", ClientCertVerified::assertion()),
950            "ClientCertVerified(())"
951        );
952        assert_eq!(
953            format!("{:?}", HandshakeSignatureValid::assertion()),
954            "HandshakeSignatureValid(())"
955        );
956        assert_eq!(
957            format!("{:?}", FinishedMessageVerified::assertion()),
958            "FinishedMessageVerified(())"
959        );
960        assert_eq!(
961            format!("{:?}", ServerCertVerified::assertion()),
962            "ServerCertVerified(())"
963        );
964    }
965
966    #[test]
967    fn pki_crl_errors() {
968        // CRL signature errors should be turned into BadSignature.
969        assert_eq!(
970            pki_error(webpki::Error::InvalidCrlSignatureForPublicKey),
971            Error::InvalidCertRevocationList(CertRevocationListError::BadSignature),
972        );
973        assert_eq!(
974            pki_error(webpki::Error::UnsupportedCrlSignatureAlgorithm),
975            Error::InvalidCertRevocationList(CertRevocationListError::BadSignature),
976        );
977        assert_eq!(
978            pki_error(webpki::Error::UnsupportedCrlSignatureAlgorithmForPublicKey),
979            Error::InvalidCertRevocationList(CertRevocationListError::BadSignature),
980        );
981
982        // Revoked cert errors should be turned into Revoked.
983        assert_eq!(
984            pki_error(webpki::Error::CertRevoked),
985            Error::InvalidCertificate(CertificateError::Revoked),
986        );
987
988        // Issuer not CRL signer errors should be turned into IssuerInvalidForCrl
989        assert_eq!(
990            pki_error(webpki::Error::IssuerNotCrlSigner),
991            Error::InvalidCertRevocationList(CertRevocationListError::IssuerInvalidForCrl)
992        );
993    }
994}