rustls/crypto/signer.rs
1use alloc::boxed::Box;
2use alloc::vec::Vec;
3use core::fmt::Debug;
4use core::hash::{Hash, Hasher};
5use core::iter;
6
7#[cfg(feature = "webpki")]
8use pki_types::PrivateKeyDer;
9use pki_types::{AlgorithmIdentifier, CertificateDer, SubjectPublicKeyInfoDer};
10
11#[cfg(feature = "webpki")]
12use super::CryptoProvider;
13use crate::client::{ClientCredentialResolver, CredentialRequest};
14use crate::crypto::SignatureScheme;
15use crate::enums::CertificateType;
16use crate::error::{ApiMisuse, Error, InvalidMessage, PeerIncompatible};
17use crate::msgs::{Codec, Reader};
18use crate::server::{ClientHello, ServerCredentialResolver};
19use crate::sync::Arc;
20pub use crate::verify::VerifiedIdentity;
21#[cfg(feature = "webpki")]
22use crate::webpki::ParsedCertificate;
23use crate::{DynHasher, SignerPublicKey, x509};
24
25/// Server certificate resolver which always resolves to the same identity and key.
26///
27/// For use with [`ConfigBuilder::with_server_credential_resolver()`] or
28/// [`ConfigBuilder::with_client_credential_resolver()`].
29///
30/// [`ConfigBuilder::with_server_credential_resolver()`]: crate::ConfigBuilder::with_server_credential_resolver
31/// [`ConfigBuilder::with_client_credential_resolver()`]: crate::ConfigBuilder::with_client_credential_resolver
32#[derive(Debug, Hash)]
33pub struct SingleCredential {
34 credentials: Credentials,
35 types: &'static [CertificateType],
36}
37
38impl From<Credentials> for SingleCredential {
39 fn from(credentials: Credentials) -> Self {
40 match &*credentials.identity {
41 Identity::X509(_) => Self {
42 credentials,
43 types: &[CertificateType::X509],
44 },
45 Identity::RawPublicKey(_) => Self {
46 credentials,
47 types: &[CertificateType::RawPublicKey],
48 },
49 }
50 }
51}
52
53impl ClientCredentialResolver for SingleCredential {
54 fn resolve(&self, request: &CredentialRequest<'_>) -> Option<SelectedCredential> {
55 match (&*self.credentials.identity, request.negotiated_type()) {
56 (Identity::X509(_), CertificateType::X509)
57 | (Identity::RawPublicKey(_), CertificateType::RawPublicKey) => self
58 .credentials
59 .signer(request.signature_schemes()),
60 _ => None,
61 }
62 }
63
64 fn supported_certificate_types(&self) -> &'static [CertificateType] {
65 self.types
66 }
67
68 fn hash_config(&self, h: &mut dyn Hasher) {
69 self.hash(&mut DynHasher(h));
70 }
71}
72
73impl ServerCredentialResolver for SingleCredential {
74 fn resolve(&self, client_hello: &ClientHello<'_>) -> Result<SelectedCredential, Error> {
75 self.credentials
76 .signer(client_hello.signature_schemes())
77 .ok_or(Error::PeerIncompatible(
78 PeerIncompatible::NoSignatureSchemesInCommon,
79 ))
80 }
81
82 fn supported_certificate_types(&self) -> &'static [CertificateType] {
83 self.types
84 }
85}
86
87/// A packaged-together certificate chain, matching `SigningKey` and
88/// optional stapled OCSP response.
89///
90/// Note: this struct is also used to represent an [RFC 7250] raw public key,
91/// when the client/server is configured to use raw public keys instead of
92/// certificates.
93///
94/// [RFC 7250]: https://tools.ietf.org/html/rfc7250
95#[non_exhaustive]
96#[derive(Debug)]
97pub struct Credentials {
98 /// The certificate chain or raw public key.
99 pub identity: Arc<Identity<'static>>,
100 /// The signing key matching the `identity`.
101 pub key: Box<dyn SigningKey>,
102 /// An optional OCSP response from the certificate issuer,
103 /// attesting to its continued validity.
104 pub ocsp: Option<Arc<[u8]>>,
105}
106
107impl Credentials {
108 /// Create a new [`Credentials`] from a certificate chain and DER-encoded private key.
109 ///
110 /// Attempt to parse the private key with the given [`CryptoProvider`]'s [`KeyProvider`] and
111 /// verify that it matches the public key in the first certificate of the `identity`
112 /// if possible (if it is an `X509` identity).
113 ///
114 /// [`KeyProvider`]: crate::crypto::KeyProvider
115 #[cfg(feature = "webpki")]
116 pub fn from_der(
117 identity: Arc<Identity<'static>>,
118 key: PrivateKeyDer<'static>,
119 provider: &CryptoProvider,
120 ) -> Result<Self, Error> {
121 Self::new(
122 identity,
123 provider
124 .key_provider
125 .load_private_key(key)?,
126 )
127 }
128
129 /// Make a new [`Credentials`], with the given identity and key.
130 ///
131 /// Yields [`Error::InconsistentKeys`] if the public key asserted by `identity` does not match
132 /// that derived from `key`, or if the `key` cannot derive its public key.
133 ///
134 /// Use [`Self::new_unchecked()`] to avoid this consistency check.
135 ///
136 /// This constructor should be used with all [`SigningKey`] implementations
137 /// that can provide a public key, including those provided by rustls itself.
138 #[cfg(feature = "webpki")]
139 pub fn new(identity: Arc<Identity<'static>>, key: Box<dyn SigningKey>) -> Result<Self, Error> {
140 let id_spki = match &*identity {
141 Identity::X509(CertificateIdentity { end_entity, .. }) => {
142 let parsed = ParsedCertificate::try_from(end_entity)?;
143 &parsed.subject_public_key_info()
144 }
145 Identity::RawPublicKey(spki) => spki,
146 };
147
148 match (key.public_key(), id_spki) {
149 (None, _) => return Err(Error::InconsistentKeys(InconsistentKeys::Unknown)),
150 (Some(key_spki), id_spki) if key_spki != *id_spki => {
151 return Err(Error::InconsistentKeys(InconsistentKeys::KeyMismatch));
152 }
153 _ => {}
154 }
155
156 Ok(Self {
157 identity,
158 key,
159 ocsp: None,
160 })
161 }
162
163 /// Make a new `Credentials` without a consistency check.
164 ///
165 /// Unlike [`Credentials::new()`], this does not check if the public key asserted by `identity`
166 /// matches that derived from `key`.
167 ///
168 /// This avoids parsing the end-entity certificate, which is useful when using client
169 /// certificates that are not fully standards compliant, but known to usable by the peer.
170 pub fn new_unchecked(identity: Arc<Identity<'static>>, key: Box<dyn SigningKey>) -> Self {
171 Self {
172 identity,
173 key,
174 ocsp: None,
175 }
176 }
177
178 /// Attempt to produce a `SelectedCredential` using one of the given signature schemes.
179 ///
180 /// Calls [`SigningKey::choose_scheme()`] and propagates `identity` and `ocsp`.
181 pub fn signer(&self, sig_schemes: &[SignatureScheme]) -> Option<SelectedCredential> {
182 Some(SelectedCredential {
183 identity: self.identity.clone(),
184 signer: self.key.choose_scheme(sig_schemes)?,
185 ocsp: self.ocsp.clone(),
186 })
187 }
188}
189
190impl Hash for Credentials {
191 fn hash<H: Hasher>(&self, state: &mut H) {
192 self.identity.hash(state);
193 self.ocsp.hash(state);
194 }
195}
196
197/// A packaged-together certificate chain and one-time-use signer.
198///
199/// This is used in the [`ClientCredentialResolver`] and [`ServerCredentialResolver`] traits
200/// as the return value of their `resolve()` methods.
201#[non_exhaustive]
202#[derive(Debug)]
203pub struct SelectedCredential {
204 /// The certificate chain or raw public key.
205 pub identity: Arc<Identity<'static>>,
206 /// The signing key matching the `identity`.
207 pub signer: Box<dyn Signer>,
208 /// An optional OCSP response from the certificate issuer,
209 /// attesting to its continued validity.
210 pub ocsp: Option<Arc<[u8]>>,
211}
212
213/// A peer's identity, depending on the negotiated certificate type.
214#[non_exhaustive]
215#[derive(Clone, Debug, Eq, Hash, PartialEq)]
216pub enum Identity<'a> {
217 /// A standard X.509 certificate chain.
218 ///
219 /// This is the most common case.
220 X509(CertificateIdentity<'a>),
221 /// A raw public key, as defined in [RFC 7250](https://tools.ietf.org/html/rfc7250).
222 RawPublicKey(SubjectPublicKeyInfoDer<'a>),
223}
224
225impl<'a> Identity<'a> {
226 /// Create a `PeerIdentity::X509` from a certificate chain.
227 ///
228 /// Returns `None` if `cert_chain` is empty.
229 pub fn from_cert_chain(mut cert_chain: Vec<CertificateDer<'a>>) -> Result<Self, ApiMisuse> {
230 let mut iter = cert_chain.drain(..);
231 let Some(first) = iter.next() else {
232 return Err(ApiMisuse::EmptyCertificateChain);
233 };
234
235 Ok(Self::X509(CertificateIdentity {
236 end_entity: first,
237 intermediates: iter.collect(),
238 }))
239 }
240
241 pub(crate) fn from_peer(
242 mut cert_chain: Vec<CertificateDer<'a>>,
243 expected: CertificateType,
244 ) -> Result<Option<Self>, Error> {
245 let mut iter = cert_chain.drain(..);
246 let Some(first) = iter.next() else {
247 return Ok(None);
248 };
249
250 match expected {
251 CertificateType::X509 => Ok(Some(Self::X509(CertificateIdentity {
252 end_entity: first,
253 intermediates: iter.collect(),
254 }))),
255 CertificateType::RawPublicKey => match iter.count() {
256 0 => Ok(Some(Self::RawPublicKey(
257 SubjectPublicKeyInfoDer::from(first.as_ref()).into_owned(),
258 ))),
259 _ => Err(PeerIncompatible::MultipleRawKeys.into()),
260 },
261 CertificateType(ty) => Err(PeerIncompatible::UnknownCertificateType(ty).into()),
262 }
263 }
264
265 /// Convert this `PeerIdentity` into an owned version.
266 pub fn into_owned(self) -> Identity<'static> {
267 match self {
268 Self::X509(id) => Identity::X509(id.into_owned()),
269 Self::RawPublicKey(spki) => Identity::RawPublicKey(spki.into_owned()),
270 }
271 }
272
273 pub(crate) fn as_certificates(&'a self) -> impl Iterator<Item = CertificateDer<'a>> + 'a {
274 match self {
275 Self::X509(cert) => IdentityCertificateIterator::X509(
276 iter::once(CertificateDer::from(cert.end_entity.as_ref())).chain(
277 cert.intermediates
278 .iter()
279 .map(|c| CertificateDer::from(c.as_ref())),
280 ),
281 ),
282 Self::RawPublicKey(spki) => IdentityCertificateIterator::RawPublicKey(iter::once(
283 CertificateDer::from(spki.as_ref()),
284 )),
285 }
286 }
287
288 /// Get the public key of this identity as a `SignerPublicKey`.
289 pub fn as_signer(&self) -> SignerPublicKey<'_> {
290 match self {
291 Self::X509(cert) => SignerPublicKey::X509(&cert.end_entity),
292 Self::RawPublicKey(spki) => SignerPublicKey::RawPublicKey(spki),
293 }
294 }
295}
296
297impl<'a> Codec<'a> for Identity<'a> {
298 fn encode(&self, bytes: &mut Vec<u8>) {
299 match self {
300 Self::X509(certificates) => {
301 0u8.encode(bytes);
302 certificates.end_entity.encode(bytes);
303 certificates.intermediates.encode(bytes);
304 }
305 Self::RawPublicKey(spki) => {
306 1u8.encode(bytes);
307 spki.encode(bytes);
308 }
309 }
310 }
311
312 fn read(reader: &mut Reader<'a>) -> Result<Self, InvalidMessage> {
313 match u8::read(reader)? {
314 0 => Ok(Self::X509(CertificateIdentity {
315 end_entity: CertificateDer::read(reader)?.into_owned(),
316 intermediates: Vec::<CertificateDer<'_>>::read(reader)?
317 .into_iter()
318 .collect(),
319 })),
320 1 => Ok(Self::RawPublicKey(
321 SubjectPublicKeyInfoDer::read(reader)?.into_owned(),
322 )),
323 _ => Err(InvalidMessage::UnexpectedMessage(
324 "invalid PeerIdentity discriminant",
325 )),
326 }
327 }
328}
329
330impl<'a> From<VerifiedIdentity<'a>> for Identity<'a> {
331 fn from(val: VerifiedIdentity<'a>) -> Self {
332 val.into_inner()
333 }
334}
335
336enum IdentityCertificateIterator<C, R> {
337 X509(C),
338 RawPublicKey(R),
339}
340
341impl<'a, C, R> Iterator for IdentityCertificateIterator<C, R>
342where
343 C: Iterator<Item = CertificateDer<'a>>,
344 R: Iterator<Item = CertificateDer<'a>>,
345{
346 type Item = CertificateDer<'a>;
347
348 fn next(&mut self) -> Option<Self::Item> {
349 match self {
350 Self::X509(iter) => iter.next(),
351 Self::RawPublicKey(iter) => iter.next(),
352 }
353 }
354}
355
356/// Data required to verify the peer's identity.
357#[non_exhaustive]
358#[derive(Clone, Debug, Eq, Hash, PartialEq)]
359pub struct CertificateIdentity<'a> {
360 /// Certificate for the entity being verified.
361 pub end_entity: CertificateDer<'a>,
362 /// All certificates other than `end_entity` received in the peer's `Certificate` message.
363 ///
364 /// It is in the same order that the peer sent them and may be empty.
365 pub intermediates: Vec<CertificateDer<'a>>,
366}
367
368impl<'a> CertificateIdentity<'a> {
369 /// Create a new `CertificateIdentity` from an end-entity certificate and intermediates.
370 pub fn new(end_entity: CertificateDer<'a>, intermediates: Vec<CertificateDer<'a>>) -> Self {
371 Self {
372 end_entity,
373 intermediates,
374 }
375 }
376
377 /// Convert this `CertificateIdentity` into an owned version.
378 pub fn into_owned(self) -> CertificateIdentity<'static> {
379 CertificateIdentity {
380 end_entity: self.end_entity.into_owned(),
381 intermediates: self
382 .intermediates
383 .into_iter()
384 .map(|cert| cert.into_owned())
385 .collect(),
386 }
387 }
388}
389
390/// An abstract signing key.
391///
392/// This interface is used by rustls to use a private signing key
393/// for authentication. This includes server and client authentication.
394///
395/// Objects of this type are always used within Rustls as
396/// `Arc<dyn SigningKey>`. There are no concrete public structs in Rustls
397/// that implement this trait.
398///
399/// You can obtain a `SigningKey` by calling the [`KeyProvider::load_private_key()`]
400/// method, which is usually referenced via [`CryptoProvider::key_provider`].
401///
402/// The `KeyProvider` method `load_private_key()` is called under the hood by
403/// [`ConfigBuilder::with_single_cert()`],
404/// [`ConfigBuilder::with_client_auth_cert()`], and
405/// [`ConfigBuilder::with_single_cert_with_ocsp()`].
406///
407/// A signing key created outside of the `KeyProvider` extension trait can be used
408/// to create a [`Credentials`], which in turn can be used to create a
409/// [`ServerNameResolver`]. Alternately, a `Credentials` can be returned from a
410/// custom implementation of the [`ServerCredentialResolver`] or [`ClientCredentialResolver`] traits.
411///
412/// [`KeyProvider::load_private_key()`]: crate::crypto::KeyProvider::load_private_key
413/// [`ConfigBuilder::with_single_cert()`]: crate::ConfigBuilder::with_single_cert
414/// [`ConfigBuilder::with_single_cert_with_ocsp()`]: crate::ConfigBuilder::with_single_cert_with_ocsp
415/// [`ConfigBuilder::with_client_auth_cert()`]: crate::ConfigBuilder::with_client_auth_cert
416/// [`ServerNameResolver`]: crate::server::ServerNameResolver
417/// [`ServerCredentialResolver`]: crate::server::ServerCredentialResolver
418/// [`ClientCredentialResolver`]: crate::client::ClientCredentialResolver
419pub trait SigningKey: Debug + Send + Sync {
420 /// Choose a `SignatureScheme` from those offered.
421 ///
422 /// Expresses the choice by returning something that implements `Signer`,
423 /// using the chosen scheme.
424 fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>>;
425
426 /// Get the RFC 5280-compliant SubjectPublicKeyInfo (SPKI) of this [`SigningKey`].
427 ///
428 /// If an implementation does not have the ability to derive this,
429 /// it can return `None`.
430 fn public_key(&self) -> Option<SubjectPublicKeyInfoDer<'_>>;
431}
432
433/// A thing that can sign a message.
434pub trait Signer: Debug + Send + Sync {
435 /// Signs `message` using the selected scheme.
436 ///
437 /// `message` is not hashed; the implementer must hash it using the hash function
438 /// implicit in [`Self::scheme()`].
439 ///
440 /// The returned signature format is also defined by [`Self::scheme()`].
441 fn sign(self: Box<Self>, message: &[u8]) -> Result<Vec<u8>, Error>;
442
443 /// Reveals which scheme will be used when you call [`Self::sign()`].
444 fn scheme(&self) -> SignatureScheme;
445}
446
447/// Convert a public key and algorithm identifier into [`SubjectPublicKeyInfoDer`].
448///
449/// In the returned encoding, `alg_id` is used as the `algorithm` field, and `public_key` is
450/// wrapped inside an ASN.1 `BIT STRING` and then used as the `subjectPublicKey` field.
451pub fn public_key_to_spki(
452 alg_id: &AlgorithmIdentifier,
453 public_key: impl AsRef<[u8]>,
454) -> SubjectPublicKeyInfoDer<'static> {
455 // SubjectPublicKeyInfo ::= SEQUENCE {
456 // algorithm AlgorithmIdentifier,
457 // subjectPublicKey BIT STRING }
458 //
459 // AlgorithmIdentifier ::= SEQUENCE {
460 // algorithm OBJECT IDENTIFIER,
461 // parameters ANY DEFINED BY algorithm OPTIONAL }
462 //
463 // note that the `pki_types::AlgorithmIdentifier` type is the
464 // concatenation of `algorithm` and `parameters`, but misses the
465 // outer `Sequence`.
466
467 let mut spki_inner = x509::wrap_in_sequence(alg_id.as_ref());
468 spki_inner.extend(&x509::wrap_in_bit_string(public_key.as_ref()));
469
470 let spki = x509::wrap_in_sequence(&spki_inner);
471
472 SubjectPublicKeyInfoDer::from(spki)
473}
474
475/// Specific failure cases from [`Credentials::new()`] or a [`crate::crypto::SigningKey`] that cannot produce a corresponding public key.
476///
477/// [`Credentials::new()`]: crate::crypto::Credentials::new()
478#[non_exhaustive]
479#[derive(Clone, Copy, Debug, Eq, PartialEq)]
480pub enum InconsistentKeys {
481 /// The public key returned by the [`SigningKey`] does not match the public key asserted by the identity.
482 ///
483 /// [`SigningKey`]: crate::crypto::SigningKey
484 KeyMismatch,
485
486 /// The [`SigningKey`] cannot produce its corresponding public key.
487 ///
488 /// [`SigningKey`]: crate::crypto::SigningKey
489 Unknown,
490}