rustls/
verify.rs

1use alloc::vec::Vec;
2use core::fmt::Debug;
3
4use pki_types::{CertificateDer, ServerName, UnixTime};
5
6use crate::enums::SignatureScheme;
7use crate::error::{Error, InvalidMessage};
8use crate::msgs::base::PayloadU16;
9use crate::msgs::codec::{Codec, Reader};
10use crate::msgs::handshake::DistinguishedName;
11use crate::sync::Arc;
12
13// Marker types.  These are used to bind the fact some verification
14// (certificate chain or handshake signature) has taken place into
15// protocol states.  We use this to have the compiler check that there
16// are no 'goto fail'-style elisions of important checks before we
17// reach the traffic stage.
18//
19// These types are public, but cannot be directly constructed.  This
20// means their origins can be precisely determined by looking
21// for their `assertion` constructors.
22
23/// Zero-sized marker type representing verification of a signature.
24#[derive(Debug)]
25pub struct HandshakeSignatureValid(());
26
27impl HandshakeSignatureValid {
28    /// Make a `HandshakeSignatureValid`
29    pub fn assertion() -> Self {
30        Self(())
31    }
32}
33
34#[derive(Debug)]
35pub(crate) struct FinishedMessageVerified(());
36
37impl FinishedMessageVerified {
38    pub(crate) fn assertion() -> Self {
39        Self(())
40    }
41}
42
43/// Zero-sized marker type representing verification of a server cert chain.
44#[allow(unreachable_pub)]
45#[derive(Debug)]
46pub struct ServerCertVerified(());
47
48#[allow(unreachable_pub)]
49impl ServerCertVerified {
50    /// Make a `ServerCertVerified`
51    pub fn assertion() -> Self {
52        Self(())
53    }
54}
55
56/// Zero-sized marker type representing verification of a client cert chain.
57#[derive(Debug)]
58pub struct ClientCertVerified(());
59
60impl ClientCertVerified {
61    /// Make a `ClientCertVerified`
62    pub fn assertion() -> Self {
63        Self(())
64    }
65}
66
67/// Something that can verify a server certificate chain, and verify
68/// signatures made by certificates.
69#[allow(unreachable_pub)]
70pub trait ServerCertVerifier: Debug + Send + Sync {
71    /// Verify the end-entity certificate `end_entity` is valid for the
72    /// hostname `dns_name` and chains to at least one trust anchor.
73    ///
74    /// `intermediates` contains all certificates other than `end_entity` that
75    /// were sent as part of the server's [Certificate] message. It is in the
76    /// same order that the server sent them and may be empty.
77    ///
78    /// `ocsp_response` is empty if no OCSP response was received, and that also
79    /// covers the case where `request_ocsp_response()` returns false.
80    ///
81    /// Note that none of the certificates have been parsed yet, so it is the responsibility of
82    /// the implementer to handle invalid data. It is recommended that the implementer returns
83    /// [`Error::InvalidCertificate`] containing [`CertificateError::BadEncoding`] when these cases are encountered.
84    ///
85    /// [Certificate]: https://datatracker.ietf.org/doc/html/rfc8446#section-4.4.2
86    /// [`CertificateError::BadEncoding`]: crate::error::CertificateError::BadEncoding
87    fn verify_server_cert(
88        &self,
89        end_entity: &CertificateDer<'_>,
90        intermediates: &[CertificateDer<'_>],
91        server_name: &ServerName<'_>,
92        ocsp_response: &[u8],
93        now: UnixTime,
94    ) -> Result<ServerCertVerified, Error>;
95
96    /// Verify a signature allegedly by the given server certificate.
97    ///
98    /// `message` is not hashed, and needs hashing during the verification.
99    /// The signature and algorithm are within `dss`.  `cert` contains the
100    /// public key to use.
101    ///
102    /// `cert` has already been validated by [`ServerCertVerifier::verify_server_cert`].
103    ///
104    /// If and only if the signature is valid, return `Ok(HandshakeSignatureValid)`.
105    /// Otherwise, return an error -- rustls will send an alert and abort the
106    /// connection.
107    ///
108    /// This method is only called for TLS1.2 handshakes.  Note that, in TLS1.2,
109    /// SignatureSchemes such as `SignatureScheme::ECDSA_NISTP256_SHA256` are not
110    /// in fact bound to the specific curve implied in their name.
111    fn verify_tls12_signature(
112        &self,
113        message: &[u8],
114        cert: &CertificateDer<'_>,
115        dss: &DigitallySignedStruct,
116    ) -> Result<HandshakeSignatureValid, Error>;
117
118    /// Verify a signature allegedly by the given server certificate.
119    ///
120    /// This method is only called for TLS1.3 handshakes.
121    ///
122    /// This method is very similar to `verify_tls12_signature`: but note the
123    /// tighter ECDSA SignatureScheme semantics -- e.g. `SignatureScheme::ECDSA_NISTP256_SHA256`
124    /// must only validate signatures using public keys on the right curve --
125    /// rustls does not enforce this requirement for you.
126    ///
127    /// `cert` has already been validated by [`ServerCertVerifier::verify_server_cert`].
128    ///
129    /// If and only if the signature is valid, return `Ok(HandshakeSignatureValid)`.
130    /// Otherwise, return an error -- rustls will send an alert and abort the
131    /// connection.
132    fn verify_tls13_signature(
133        &self,
134        message: &[u8],
135        cert: &CertificateDer<'_>,
136        dss: &DigitallySignedStruct,
137    ) -> Result<HandshakeSignatureValid, Error>;
138
139    /// Return the list of SignatureSchemes that this verifier will handle,
140    /// in `verify_tls12_signature` and `verify_tls13_signature` calls.
141    ///
142    /// This should be in priority order, with the most preferred first.
143    fn supported_verify_schemes(&self) -> Vec<SignatureScheme>;
144
145    /// Return true if this verifier will process stapled OCSP responses.
146    ///
147    /// This controls whether a client will ask the server for a stapled OCSP response.
148    /// There is no guarantee the server will provide one.
149    fn request_ocsp_response(&self) -> bool;
150
151    /// Returns whether this verifier requires raw public keys as defined
152    /// in [RFC 7250](https://tools.ietf.org/html/rfc7250).
153    fn requires_raw_public_keys(&self) -> bool {
154        false
155    }
156
157    /// Return the [`DistinguishedName`]s of certificate authorities that this verifier trusts.
158    ///
159    /// If specified, will be sent as the [`certificate_authorities`] extension in ClientHello.
160    /// Note that this is only applicable to TLS 1.3.
161    ///
162    /// [`certificate_authorities`]: https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.4
163    fn root_hint_subjects(&self) -> Option<Arc<[DistinguishedName]>> {
164        None
165    }
166}
167
168/// Something that can verify a client certificate chain
169#[allow(unreachable_pub)]
170pub trait ClientCertVerifier: Debug + Send + Sync {
171    /// Returns `true` to enable the server to request a client certificate and
172    /// `false` to skip requesting a client certificate. Defaults to `true`.
173    fn offer_client_auth(&self) -> bool {
174        true
175    }
176
177    /// Return `true` to require a client certificate and `false` to make
178    /// client authentication optional.
179    /// Defaults to `self.offer_client_auth()`.
180    fn client_auth_mandatory(&self) -> bool {
181        self.offer_client_auth()
182    }
183
184    /// Returns the [`DistinguishedName`] [subjects] that the server will hint to clients to
185    /// identify acceptable authentication trust anchors.
186    ///
187    /// These hint values help the client pick a client certificate it believes the server will
188    /// accept. The hints must be DER-encoded X.500 distinguished names, per [RFC 5280 A.1]. They
189    /// are sent in the [`certificate_authorities`] extension of a [`CertificateRequest`] message
190    /// when [ClientCertVerifier::offer_client_auth] is true. When an empty list is sent the client
191    /// should always provide a client certificate if it has one.
192    ///
193    /// Generally this list should contain the [`DistinguishedName`] of each root trust
194    /// anchor in the root cert store that the server is configured to use for authenticating
195    /// presented client certificates.
196    ///
197    /// In some circumstances this list may be customized to include [`DistinguishedName`] entries
198    /// that do not correspond to a trust anchor in the server's root cert store. For example,
199    /// the server may be configured to trust a root CA that cross-signed an issuer certificate
200    /// that the client considers a trust anchor. From the server's perspective the cross-signed
201    /// certificate is an intermediate, and not present in the server's root cert store. The client
202    /// may have the cross-signed certificate configured as a trust anchor, and be unaware of the
203    /// root CA that cross-signed it. If the server's hints list only contained the subjects of the
204    /// server's root store the client would consider a client certificate issued by the cross-signed
205    /// issuer unacceptable, since its subject was not hinted. To avoid this circumstance the server
206    /// should customize the hints list to include the subject of the cross-signed issuer in addition
207    /// to the subjects from the root cert store.
208    ///
209    /// [subjects]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6
210    /// [RFC 5280 A.1]: https://www.rfc-editor.org/rfc/rfc5280#appendix-A.1
211    /// [`CertificateRequest`]: https://datatracker.ietf.org/doc/html/rfc8446#section-4.3.2
212    /// [`certificate_authorities`]: https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.4
213    fn root_hint_subjects(&self) -> Arc<[DistinguishedName]>;
214
215    /// Verify the end-entity certificate `end_entity` is valid, acceptable,
216    /// and chains to at least one of the trust anchors trusted by
217    /// this verifier.
218    ///
219    /// `intermediates` contains the intermediate certificates the
220    /// client sent along with the end-entity certificate; it is in the same
221    /// order that the peer sent them and may be empty.
222    ///
223    /// Note that none of the certificates have been parsed yet, so it is the responsibility of
224    /// the implementer to handle invalid data. It is recommended that the implementer returns
225    /// an [InvalidCertificate] error with the [BadEncoding] variant when these cases are encountered.
226    ///
227    /// [InvalidCertificate]: Error#variant.InvalidCertificate
228    /// [BadEncoding]: crate::CertificateError#variant.BadEncoding
229    fn verify_client_cert(
230        &self,
231        end_entity: &CertificateDer<'_>,
232        intermediates: &[CertificateDer<'_>],
233        now: UnixTime,
234    ) -> Result<ClientCertVerified, Error>;
235
236    /// Verify a signature allegedly by the given client certificate.
237    ///
238    /// `message` is not hashed, and needs hashing during the verification.
239    /// The signature and algorithm are within `dss`.  `cert` contains the
240    /// public key to use.
241    ///
242    /// `cert` has already been validated by [`ClientCertVerifier::verify_client_cert`].
243    ///
244    /// If and only if the signature is valid, return `Ok(HandshakeSignatureValid)`.
245    /// Otherwise, return an error -- rustls will send an alert and abort the
246    /// connection.
247    ///
248    /// This method is only called for TLS1.2 handshakes.  Note that, in TLS1.2,
249    /// SignatureSchemes such as `SignatureScheme::ECDSA_NISTP256_SHA256` are not
250    /// in fact bound to the specific curve implied in their name.
251    fn verify_tls12_signature(
252        &self,
253        message: &[u8],
254        cert: &CertificateDer<'_>,
255        dss: &DigitallySignedStruct,
256    ) -> Result<HandshakeSignatureValid, Error>;
257
258    /// Verify a signature allegedly by the given client certificate.
259    ///
260    /// This method is only called for TLS1.3 handshakes.
261    ///
262    /// This method is very similar to `verify_tls12_signature`, but note the
263    /// tighter ECDSA SignatureScheme semantics in TLS 1.3. For example,
264    /// `SignatureScheme::ECDSA_NISTP256_SHA256`
265    /// must only validate signatures using public keys on the right curve --
266    /// rustls does not enforce this requirement for you.
267    fn verify_tls13_signature(
268        &self,
269        message: &[u8],
270        cert: &CertificateDer<'_>,
271        dss: &DigitallySignedStruct,
272    ) -> Result<HandshakeSignatureValid, Error>;
273
274    /// Return the list of SignatureSchemes that this verifier will handle,
275    /// in `verify_tls12_signature` and `verify_tls13_signature` calls.
276    ///
277    /// This should be in priority order, with the most preferred first.
278    fn supported_verify_schemes(&self) -> Vec<SignatureScheme>;
279
280    /// Returns whether this verifier requires raw public keys as defined
281    /// in [RFC 7250](https://tools.ietf.org/html/rfc7250).
282    fn requires_raw_public_keys(&self) -> bool {
283        false
284    }
285}
286
287/// Turns off client authentication.
288///
289/// In contrast to using
290/// `WebPkiClientVerifier::builder(roots).allow_unauthenticated().build()`, the `NoClientAuth`
291/// `ClientCertVerifier` will not offer client authentication at all, vs offering but not
292/// requiring it.
293#[allow(clippy::exhaustive_structs)]
294#[derive(Debug)]
295pub struct NoClientAuth;
296
297impl ClientCertVerifier for NoClientAuth {
298    fn offer_client_auth(&self) -> bool {
299        false
300    }
301
302    fn root_hint_subjects(&self) -> Arc<[DistinguishedName]> {
303        unimplemented!();
304    }
305
306    fn verify_client_cert(
307        &self,
308        _end_entity: &CertificateDer<'_>,
309        _intermediates: &[CertificateDer<'_>],
310        _now: UnixTime,
311    ) -> Result<ClientCertVerified, Error> {
312        unimplemented!();
313    }
314
315    fn verify_tls12_signature(
316        &self,
317        _message: &[u8],
318        _cert: &CertificateDer<'_>,
319        _dss: &DigitallySignedStruct,
320    ) -> Result<HandshakeSignatureValid, Error> {
321        unimplemented!();
322    }
323
324    fn verify_tls13_signature(
325        &self,
326        _message: &[u8],
327        _cert: &CertificateDer<'_>,
328        _dss: &DigitallySignedStruct,
329    ) -> Result<HandshakeSignatureValid, Error> {
330        unimplemented!();
331    }
332
333    fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
334        unimplemented!();
335    }
336}
337
338/// This type combines a [`SignatureScheme`] and a signature payload produced with that scheme.
339#[derive(Debug, Clone)]
340pub struct DigitallySignedStruct {
341    /// The [`SignatureScheme`] used to produce the signature.
342    pub scheme: SignatureScheme,
343    sig: PayloadU16,
344}
345
346impl DigitallySignedStruct {
347    pub(crate) fn new(scheme: SignatureScheme, sig: Vec<u8>) -> Self {
348        Self {
349            scheme,
350            sig: PayloadU16::new(sig),
351        }
352    }
353
354    /// Get the signature.
355    pub fn signature(&self) -> &[u8] {
356        &self.sig.0
357    }
358}
359
360impl Codec<'_> for DigitallySignedStruct {
361    fn encode(&self, bytes: &mut Vec<u8>) {
362        self.scheme.encode(bytes);
363        self.sig.encode(bytes);
364    }
365
366    fn read(r: &mut Reader<'_>) -> Result<Self, InvalidMessage> {
367        let scheme = SignatureScheme::read(r)?;
368        let sig = PayloadU16::read(r)?;
369
370        Ok(Self { scheme, sig })
371    }
372}
373
374#[test]
375fn assertions_are_debug() {
376    use std::format;
377
378    assert_eq!(
379        format!("{:?}", ClientCertVerified::assertion()),
380        "ClientCertVerified(())"
381    );
382    assert_eq!(
383        format!("{:?}", HandshakeSignatureValid::assertion()),
384        "HandshakeSignatureValid(())"
385    );
386    assert_eq!(
387        format!("{:?}", FinishedMessageVerified::assertion()),
388        "FinishedMessageVerified(())"
389    );
390    assert_eq!(
391        format!("{:?}", ServerCertVerified::assertion()),
392        "ServerCertVerified(())"
393    );
394}