rustls/crypto/
signer.rs

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