rustls/
verify.rs

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