rustls/
verify.rs

1use alloc::vec::Vec;
2use core::fmt::Debug;
3
4use pki_types::{CertificateDer, ServerName, SubjectPublicKeyInfoDer, UnixTime};
5
6use crate::crypto::Identity;
7use crate::enums::{CertificateType, SignatureScheme};
8use crate::error::{Error, InvalidMessage};
9use crate::msgs::base::PayloadU16;
10use crate::msgs::codec::{Codec, Reader};
11use crate::msgs::handshake::DistinguishedName;
12use crate::sync::Arc;
13
14// Marker types.  These are used to bind the fact some verification
15// (certificate chain or handshake signature) has taken place into
16// protocol states.  We use this to have the compiler check that there
17// are no 'goto fail'-style elisions of important checks before we
18// reach the traffic stage.
19//
20// These types are public, but cannot be directly constructed.  This
21// means their origins can be precisely determined by looking
22// for their `assertion` constructors.
23
24/// Something that can verify a server certificate chain, and verify
25/// signatures made by certificates.
26#[allow(unreachable_pub)]
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
102/// Data required to verify a server's identity.
103#[allow(unreachable_pub)]
104#[non_exhaustive]
105#[derive(Debug)]
106pub struct ServerIdentity<'a> {
107    /// Identity information presented by the server.
108    pub identity: &'a Identity<'a>,
109    /// The server name the client specified when connecting to the server.
110    pub server_name: &'a ServerName<'a>,
111    /// OCSP response stapled to the server's `Certificate` message, if any.
112    ///
113    /// Empty if no OCSP response was received, and that also
114    /// covers the case where `request_ocsp_response()` returns false.
115    pub ocsp_response: &'a [u8],
116    /// Current time against which time-sensitive inputs should be validated.
117    pub now: UnixTime,
118}
119
120/// Something that can verify a client certificate chain
121#[allow(unreachable_pub)]
122pub trait ClientVerifier: Debug + Send + Sync {
123    /// Verify the client's identity.
124    ///
125    /// Note that none of the certificates have been parsed yet, so it is the responsibility of
126    /// the implementer to handle invalid data. It is recommended that the implementer returns
127    /// a [`CertificateError::BadEncoding`] error when these cases are encountered.
128    ///
129    /// [`CertificateError::BadEncoding`]: crate::error::CertificateError::BadEncoding
130    fn verify_identity(&self, identity: &ClientIdentity<'_>) -> Result<PeerVerified, Error>;
131
132    /// Verify a signature allegedly by the given client certificate.
133    ///
134    /// If and only if the signature is valid, return `Ok(HandshakeSignatureValid)`.
135    /// Otherwise, return an error -- rustls will send an alert and abort the
136    /// connection.
137    ///
138    /// This method is only called for TLS1.2 handshakes.  Note that, in TLS1.2,
139    /// SignatureSchemes such as `SignatureScheme::ECDSA_NISTP256_SHA256` are not
140    /// in fact bound to the specific curve implied in their name.
141    fn verify_tls12_signature(
142        &self,
143        input: &SignatureVerificationInput<'_>,
144    ) -> Result<HandshakeSignatureValid, Error>;
145
146    /// Verify a signature allegedly by the given client certificate.
147    ///
148    /// This method is only called for TLS1.3 handshakes.
149    ///
150    /// This method is very similar to `verify_tls12_signature`, but note the
151    /// tighter ECDSA SignatureScheme semantics in TLS 1.3. For example,
152    /// `SignatureScheme::ECDSA_NISTP256_SHA256`
153    /// must only validate signatures using public keys on the right curve --
154    /// rustls does not enforce this requirement for you.
155    fn verify_tls13_signature(
156        &self,
157        input: &SignatureVerificationInput<'_>,
158    ) -> Result<HandshakeSignatureValid, Error>;
159
160    /// Returns the [`DistinguishedName`] [subjects] that the server will hint to clients to
161    /// identify acceptable authentication trust anchors.
162    ///
163    /// These hint values help the client pick a client certificate it believes the server will
164    /// accept. The hints must be DER-encoded X.500 distinguished names, per [RFC 5280 A.1]. They
165    /// are sent in the [`certificate_authorities`] extension of a [`CertificateRequest`] message
166    /// when [ClientVerifier::offer_client_auth] is true. When an empty list is sent the client
167    /// should always provide a client certificate if it has one.
168    ///
169    /// Generally this list should contain the [`DistinguishedName`] of each root trust
170    /// anchor in the root cert store that the server is configured to use for authenticating
171    /// presented client certificates.
172    ///
173    /// In some circumstances this list may be customized to include [`DistinguishedName`] entries
174    /// that do not correspond to a trust anchor in the server's root cert store. For example,
175    /// the server may be configured to trust a root CA that cross-signed an issuer certificate
176    /// that the client considers a trust anchor. From the server's perspective the cross-signed
177    /// certificate is an intermediate, and not present in the server's root cert store. The client
178    /// may have the cross-signed certificate configured as a trust anchor, and be unaware of the
179    /// root CA that cross-signed it. If the server's hints list only contained the subjects of the
180    /// server's root store the client would consider a client certificate issued by the cross-signed
181    /// issuer unacceptable, since its subject was not hinted. To avoid this circumstance the server
182    /// should customize the hints list to include the subject of the cross-signed issuer in addition
183    /// to the subjects from the root cert store.
184    ///
185    /// [subjects]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6
186    /// [RFC 5280 A.1]: https://www.rfc-editor.org/rfc/rfc5280#appendix-A.1
187    /// [`CertificateRequest`]: https://datatracker.ietf.org/doc/html/rfc8446#section-4.3.2
188    /// [`certificate_authorities`]: https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.4
189    fn root_hint_subjects(&self) -> Arc<[DistinguishedName]>;
190
191    /// Return `true` to require a client certificate and `false` to make
192    /// client authentication optional.
193    /// Defaults to `self.offer_client_auth()`.
194    fn client_auth_mandatory(&self) -> bool {
195        self.offer_client_auth()
196    }
197
198    /// Returns `true` to enable the server to request a client certificate and
199    /// `false` to skip requesting a client certificate. Defaults to `true`.
200    fn offer_client_auth(&self) -> bool {
201        true
202    }
203
204    /// Return the list of SignatureSchemes that this verifier will handle,
205    /// in `verify_tls12_signature` and `verify_tls13_signature` calls.
206    ///
207    /// This should be in priority order, with the most preferred first.
208    fn supported_verify_schemes(&self) -> Vec<SignatureScheme>;
209
210    /// Returns which [`CertificateType`]s this verifier supports.
211    ///
212    /// Returning an empty slice will result in an error. The default implementation signals
213    /// support for X.509 certificates. Implementations should return the same value every time.
214    ///
215    /// See [RFC 7250](https://tools.ietf.org/html/rfc7250) for more information.
216    fn supported_certificate_types(&self) -> &'static [CertificateType] {
217        &[CertificateType::X509]
218    }
219}
220
221/// Data required to verify a client's identity.
222#[allow(unreachable_pub)]
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#[allow(unreachable_pub)]
234#[non_exhaustive]
235#[derive(Debug)]
236pub struct SignatureVerificationInput<'a> {
237    /// The message is not hashed, and needs hashing during verification.
238    pub message: &'a [u8],
239    /// The public key to use.
240    ///
241    /// `signer` has already been validated by the point this is called.
242    pub signer: &'a SignerPublicKey<'a>,
243    /// The signature scheme and payload.
244    pub signature: &'a DigitallySignedStruct,
245}
246
247/// Public key used to verify a signature.
248///
249/// Used as part of [`SignatureVerificationInput`].
250#[allow(unreachable_pub)]
251#[non_exhaustive]
252#[derive(Debug)]
253pub enum SignerPublicKey<'a> {
254    /// An X.509 certificate for the signing peer.
255    X509(&'a CertificateDer<'a>),
256    /// A raw public key, as defined in [RFC 7250](https://tools.ietf.org/html/rfc7250).
257    RawPublicKey(&'a SubjectPublicKeyInfoDer<'a>),
258}
259
260/// Turns off client authentication.
261///
262/// In contrast to using
263/// `WebPkiClientVerifier::builder(roots).allow_unauthenticated().build()`, the `NoClientAuth`
264/// `ClientVerifier` will not offer client authentication at all, vs offering but not
265/// requiring it.
266#[allow(clippy::exhaustive_structs)]
267#[derive(Debug)]
268pub struct NoClientAuth;
269
270impl ClientVerifier for NoClientAuth {
271    fn verify_identity(&self, _identity: &ClientIdentity<'_>) -> Result<PeerVerified, Error> {
272        unimplemented!();
273    }
274
275    fn verify_tls12_signature(
276        &self,
277        _input: &SignatureVerificationInput<'_>,
278    ) -> Result<HandshakeSignatureValid, Error> {
279        unimplemented!();
280    }
281
282    fn verify_tls13_signature(
283        &self,
284        _input: &SignatureVerificationInput<'_>,
285    ) -> Result<HandshakeSignatureValid, Error> {
286        unimplemented!();
287    }
288
289    fn root_hint_subjects(&self) -> Arc<[DistinguishedName]> {
290        unimplemented!();
291    }
292
293    fn offer_client_auth(&self) -> bool {
294        false
295    }
296
297    fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
298        unimplemented!();
299    }
300}
301
302/// This type combines a [`SignatureScheme`] and a signature payload produced with that scheme.
303#[derive(Debug, Clone)]
304pub struct DigitallySignedStruct {
305    /// The [`SignatureScheme`] used to produce the signature.
306    pub scheme: SignatureScheme,
307    sig: PayloadU16,
308}
309
310impl DigitallySignedStruct {
311    pub(crate) fn new(scheme: SignatureScheme, sig: Vec<u8>) -> Self {
312        Self {
313            scheme,
314            sig: PayloadU16::new(sig),
315        }
316    }
317
318    /// Get the signature.
319    pub fn signature(&self) -> &[u8] {
320        &self.sig.0
321    }
322}
323
324impl Codec<'_> for DigitallySignedStruct {
325    fn encode(&self, bytes: &mut Vec<u8>) {
326        self.scheme.encode(bytes);
327        self.sig.encode(bytes);
328    }
329
330    fn read(r: &mut Reader<'_>) -> Result<Self, InvalidMessage> {
331        let scheme = SignatureScheme::read(r)?;
332        let sig = PayloadU16::read(r)?;
333
334        Ok(Self { scheme, sig })
335    }
336}
337
338/// Zero-sized marker type representing verification of a signature.
339#[derive(Debug)]
340pub struct HandshakeSignatureValid(());
341
342impl HandshakeSignatureValid {
343    /// Make a `HandshakeSignatureValid`
344    pub fn assertion() -> Self {
345        Self(())
346    }
347}
348
349#[derive(Debug)]
350pub(crate) struct FinishedMessageVerified(());
351
352impl FinishedMessageVerified {
353    pub(crate) fn assertion() -> Self {
354        Self(())
355    }
356}
357
358/// Zero-sized marker type representing verification of the peer's identity.
359#[derive(Debug)]
360pub struct PeerVerified(());
361
362impl PeerVerified {
363    /// Make a `PeerVerified`
364    pub fn assertion() -> Self {
365        Self(())
366    }
367}
368
369#[test]
370fn assertions_are_debug() {
371    use std::format;
372
373    assert_eq!(
374        format!("{:?}", PeerVerified::assertion()),
375        "PeerVerified(())"
376    );
377    assert_eq!(
378        format!("{:?}", HandshakeSignatureValid::assertion()),
379        "HandshakeSignatureValid(())"
380    );
381    assert_eq!(
382        format!("{:?}", FinishedMessageVerified::assertion()),
383        "FinishedMessageVerified(())"
384    );
385}