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