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 `identity` is `X509` and the end-entity certificate's subject
132 /// public key info does not match that of the `key`'s public key, or if the `key` does not
133 /// have a public key.
134 ///
135 /// This constructor should be used with all [`SigningKey`] implementations
136 /// that can provide a public key, including those provided by rustls itself.
137 #[cfg(feature = "webpki")]
138 pub fn new(identity: Arc<Identity<'static>>, key: Box<dyn SigningKey>) -> Result<Self, Error> {
139 if let Identity::X509(CertificateIdentity { end_entity, .. }) = &*identity {
140 let parsed = ParsedCertificate::try_from(end_entity)?;
141 match (key.public_key(), parsed.subject_public_key_info()) {
142 (None, _) => return Err(Error::InconsistentKeys(InconsistentKeys::Unknown)),
143 (Some(key_spki), cert_spki) if key_spki != cert_spki => {
144 return Err(Error::InconsistentKeys(InconsistentKeys::KeyMismatch));
145 }
146 _ => {}
147 }
148 };
149
150 Ok(Self {
151 identity,
152 key,
153 ocsp: None,
154 })
155 }
156
157 /// Make a new `Credentials` from a raw private key.
158 ///
159 /// Unlike [`Credentials::new()`], this does not check that the end-entity certificate's
160 /// subject key matches `key`'s public key.
161 ///
162 /// This avoids parsing the end-entity certificate, which is useful when using client
163 /// certificates that are not fully standards compliant, but known to usable by the peer.
164 pub fn new_unchecked(identity: Arc<Identity<'static>>, key: Box<dyn SigningKey>) -> Self {
165 Self {
166 identity,
167 key,
168 ocsp: None,
169 }
170 }
171
172 /// Attempt to produce a `SelectedCredential` using one of the given signature schemes.
173 ///
174 /// Calls [`SigningKey::choose_scheme()`] and propagates `cert_chain` and `ocsp`.
175 pub fn signer(&self, sig_schemes: &[SignatureScheme]) -> Option<SelectedCredential> {
176 Some(SelectedCredential {
177 identity: self.identity.clone(),
178 signer: self.key.choose_scheme(sig_schemes)?,
179 ocsp: self.ocsp.clone(),
180 })
181 }
182}
183
184impl Hash for Credentials {
185 fn hash<H: Hasher>(&self, state: &mut H) {
186 self.identity.hash(state);
187 self.ocsp.hash(state);
188 }
189}
190
191/// A packaged-together certificate chain and one-time-use signer.
192///
193/// This is used in the [`ClientCredentialResolver`] and [`ServerCredentialResolver`] traits
194/// as the return value of their `resolve()` methods.
195#[non_exhaustive]
196#[derive(Debug)]
197pub struct SelectedCredential {
198 /// The certificate chain or raw public key.
199 pub identity: Arc<Identity<'static>>,
200 /// The signing key matching the `identity`.
201 pub signer: Box<dyn Signer>,
202 /// An optional OCSP response from the certificate issuer,
203 /// attesting to its continued validity.
204 pub ocsp: Option<Arc<[u8]>>,
205}
206
207/// A peer's identity, depending on the negotiated certificate type.
208#[non_exhaustive]
209#[derive(Clone, Debug, Eq, Hash, PartialEq)]
210pub enum Identity<'a> {
211 /// A standard X.509 certificate chain.
212 ///
213 /// This is the most common case.
214 X509(CertificateIdentity<'a>),
215 /// A raw public key, as defined in [RFC 7250](https://tools.ietf.org/html/rfc7250).
216 RawPublicKey(SubjectPublicKeyInfoDer<'a>),
217}
218
219impl<'a> Identity<'a> {
220 /// Create a `PeerIdentity::X509` from a certificate chain.
221 ///
222 /// Returns `None` if `cert_chain` is empty.
223 pub fn from_cert_chain(mut cert_chain: Vec<CertificateDer<'a>>) -> Result<Self, ApiMisuse> {
224 let mut iter = cert_chain.drain(..);
225 let Some(first) = iter.next() else {
226 return Err(ApiMisuse::EmptyCertificateChain);
227 };
228
229 Ok(Self::X509(CertificateIdentity {
230 end_entity: first,
231 intermediates: iter.collect(),
232 }))
233 }
234
235 pub(crate) fn from_peer(
236 mut cert_chain: Vec<CertificateDer<'a>>,
237 expected: CertificateType,
238 ) -> Result<Option<Self>, Error> {
239 let mut iter = cert_chain.drain(..);
240 let Some(first) = iter.next() else {
241 return Ok(None);
242 };
243
244 match expected {
245 CertificateType::X509 => Ok(Some(Self::X509(CertificateIdentity {
246 end_entity: first,
247 intermediates: iter.collect(),
248 }))),
249 CertificateType::RawPublicKey => match iter.count() {
250 0 => Ok(Some(Self::RawPublicKey(
251 SubjectPublicKeyInfoDer::from(first.as_ref()).into_owned(),
252 ))),
253 _ => Err(PeerIncompatible::MultipleRawKeys.into()),
254 },
255 CertificateType(ty) => Err(PeerIncompatible::UnknownCertificateType(ty).into()),
256 }
257 }
258
259 /// Convert this `PeerIdentity` into an owned version.
260 pub fn into_owned(self) -> Identity<'static> {
261 match self {
262 Self::X509(id) => Identity::X509(id.into_owned()),
263 Self::RawPublicKey(spki) => Identity::RawPublicKey(spki.into_owned()),
264 }
265 }
266
267 pub(crate) fn as_certificates(&'a self) -> impl Iterator<Item = CertificateDer<'a>> + 'a {
268 match self {
269 Self::X509(cert) => IdentityCertificateIterator::X509(
270 iter::once(CertificateDer::from(cert.end_entity.as_ref())).chain(
271 cert.intermediates
272 .iter()
273 .map(|c| CertificateDer::from(c.as_ref())),
274 ),
275 ),
276 Self::RawPublicKey(spki) => IdentityCertificateIterator::RawPublicKey(iter::once(
277 CertificateDer::from(spki.as_ref()),
278 )),
279 }
280 }
281
282 /// Get the public key of this identity as a `SignerPublicKey`.
283 pub fn as_signer(&self) -> SignerPublicKey<'_> {
284 match self {
285 Self::X509(cert) => SignerPublicKey::X509(&cert.end_entity),
286 Self::RawPublicKey(spki) => SignerPublicKey::RawPublicKey(spki),
287 }
288 }
289}
290
291impl<'a> Codec<'a> for Identity<'a> {
292 fn encode(&self, bytes: &mut Vec<u8>) {
293 match self {
294 Self::X509(certificates) => {
295 0u8.encode(bytes);
296 certificates.end_entity.encode(bytes);
297 certificates.intermediates.encode(bytes);
298 }
299 Self::RawPublicKey(spki) => {
300 1u8.encode(bytes);
301 spki.encode(bytes);
302 }
303 }
304 }
305
306 fn read(reader: &mut Reader<'a>) -> Result<Self, InvalidMessage> {
307 match u8::read(reader)? {
308 0 => Ok(Self::X509(CertificateIdentity {
309 end_entity: CertificateDer::read(reader)?.into_owned(),
310 intermediates: Vec::<CertificateDer<'_>>::read(reader)?
311 .into_iter()
312 .collect(),
313 })),
314 1 => Ok(Self::RawPublicKey(
315 SubjectPublicKeyInfoDer::read(reader)?.into_owned(),
316 )),
317 _ => Err(InvalidMessage::UnexpectedMessage(
318 "invalid PeerIdentity discriminant",
319 )),
320 }
321 }
322}
323
324impl<'a> From<VerifiedIdentity<'a>> for Identity<'a> {
325 fn from(val: VerifiedIdentity<'a>) -> Self {
326 val.into_inner()
327 }
328}
329
330enum IdentityCertificateIterator<C, R> {
331 X509(C),
332 RawPublicKey(R),
333}
334
335impl<'a, C, R> Iterator for IdentityCertificateIterator<C, R>
336where
337 C: Iterator<Item = CertificateDer<'a>>,
338 R: Iterator<Item = CertificateDer<'a>>,
339{
340 type Item = CertificateDer<'a>;
341
342 fn next(&mut self) -> Option<Self::Item> {
343 match self {
344 Self::X509(iter) => iter.next(),
345 Self::RawPublicKey(iter) => iter.next(),
346 }
347 }
348}
349
350/// Data required to verify the peer's identity.
351#[non_exhaustive]
352#[derive(Clone, Debug, Eq, Hash, PartialEq)]
353pub struct CertificateIdentity<'a> {
354 /// Certificate for the entity being verified.
355 pub end_entity: CertificateDer<'a>,
356 /// All certificates other than `end_entity` received in the peer's `Certificate` message.
357 ///
358 /// It is in the same order that the peer sent them and may be empty.
359 pub intermediates: Vec<CertificateDer<'a>>,
360}
361
362impl<'a> CertificateIdentity<'a> {
363 /// Create a new `CertificateIdentity` from an end-entity certificate and intermediates.
364 pub fn new(end_entity: CertificateDer<'a>, intermediates: Vec<CertificateDer<'a>>) -> Self {
365 Self {
366 end_entity,
367 intermediates,
368 }
369 }
370
371 /// Convert this `CertificateIdentity` into an owned version.
372 pub fn into_owned(self) -> CertificateIdentity<'static> {
373 CertificateIdentity {
374 end_entity: self.end_entity.into_owned(),
375 intermediates: self
376 .intermediates
377 .into_iter()
378 .map(|cert| cert.into_owned())
379 .collect(),
380 }
381 }
382}
383
384/// An abstract signing key.
385///
386/// This interface is used by rustls to use a private signing key
387/// for authentication. This includes server and client authentication.
388///
389/// Objects of this type are always used within Rustls as
390/// `Arc<dyn SigningKey>`. There are no concrete public structs in Rustls
391/// that implement this trait.
392///
393/// You can obtain a `SigningKey` by calling the [`KeyProvider::load_private_key()`]
394/// method, which is usually referenced via [`CryptoProvider::key_provider`].
395///
396/// The `KeyProvider` method `load_private_key()` is called under the hood by
397/// [`ConfigBuilder::with_single_cert()`],
398/// [`ConfigBuilder::with_client_auth_cert()`], and
399/// [`ConfigBuilder::with_single_cert_with_ocsp()`].
400///
401/// A signing key created outside of the `KeyProvider` extension trait can be used
402/// to create a [`Credentials`], which in turn can be used to create a
403/// [`ServerNameResolver`]. Alternately, a `Credentials` can be returned from a
404/// custom implementation of the [`ServerCredentialResolver`] or [`ClientCredentialResolver`] traits.
405///
406/// [`KeyProvider::load_private_key()`]: crate::crypto::KeyProvider::load_private_key
407/// [`ConfigBuilder::with_single_cert()`]: crate::ConfigBuilder::with_single_cert
408/// [`ConfigBuilder::with_single_cert_with_ocsp()`]: crate::ConfigBuilder::with_single_cert_with_ocsp
409/// [`ConfigBuilder::with_client_auth_cert()`]: crate::ConfigBuilder::with_client_auth_cert
410/// [`ServerNameResolver`]: crate::server::ServerNameResolver
411/// [`ServerCredentialResolver`]: crate::server::ServerCredentialResolver
412/// [`ClientCredentialResolver`]: crate::client::ClientCredentialResolver
413pub trait SigningKey: Debug + Send + Sync {
414 /// Choose a `SignatureScheme` from those offered.
415 ///
416 /// Expresses the choice by returning something that implements `Signer`,
417 /// using the chosen scheme.
418 fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>>;
419
420 /// Get the RFC 5280-compliant SubjectPublicKeyInfo (SPKI) of this [`SigningKey`].
421 ///
422 /// If an implementation does not have the ability to derive this,
423 /// it can return `None`.
424 fn public_key(&self) -> Option<SubjectPublicKeyInfoDer<'_>>;
425}
426
427/// A thing that can sign a message.
428pub trait Signer: Debug + Send + Sync {
429 /// Signs `message` using the selected scheme.
430 ///
431 /// `message` is not hashed; the implementer must hash it using the hash function
432 /// implicit in [`Self::scheme()`].
433 ///
434 /// The returned signature format is also defined by [`Self::scheme()`].
435 fn sign(self: Box<Self>, message: &[u8]) -> Result<Vec<u8>, Error>;
436
437 /// Reveals which scheme will be used when you call [`Self::sign()`].
438 fn scheme(&self) -> SignatureScheme;
439}
440
441/// Convert a public key and algorithm identifier into [`SubjectPublicKeyInfoDer`].
442///
443/// In the returned encoding, `alg_id` is used as the `algorithm` field, and `public_key` is
444/// wrapped inside an ASN.1 `BIT STRING` and then used as the `subjectPublicKey` field.
445pub fn public_key_to_spki(
446 alg_id: &AlgorithmIdentifier,
447 public_key: impl AsRef<[u8]>,
448) -> SubjectPublicKeyInfoDer<'static> {
449 // SubjectPublicKeyInfo ::= SEQUENCE {
450 // algorithm AlgorithmIdentifier,
451 // subjectPublicKey BIT STRING }
452 //
453 // AlgorithmIdentifier ::= SEQUENCE {
454 // algorithm OBJECT IDENTIFIER,
455 // parameters ANY DEFINED BY algorithm OPTIONAL }
456 //
457 // note that the `pki_types::AlgorithmIdentifier` type is the
458 // concatenation of `algorithm` and `parameters`, but misses the
459 // outer `Sequence`.
460
461 let mut spki_inner = x509::wrap_in_sequence(alg_id.as_ref());
462 spki_inner.extend(&x509::wrap_in_bit_string(public_key.as_ref()));
463
464 let spki = x509::wrap_in_sequence(&spki_inner);
465
466 SubjectPublicKeyInfoDer::from(spki)
467}
468
469/// Specific failure cases from [`Credentials::new()`] or a [`crate::crypto::SigningKey`] that cannot produce a corresponding public key.
470///
471/// [`Credentials::new()`]: crate::crypto::Credentials::new()
472#[non_exhaustive]
473#[derive(Clone, Copy, Debug, Eq, PartialEq)]
474pub enum InconsistentKeys {
475 /// The public key returned by the [`SigningKey`] does not match the public key information in the certificate.
476 ///
477 /// [`SigningKey`]: crate::crypto::SigningKey
478 KeyMismatch,
479
480 /// The [`SigningKey`] cannot produce its corresponding public key.
481 ///
482 /// [`SigningKey`]: crate::crypto::SigningKey
483 Unknown,
484}