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}