rustls/crypto/
signer.rs

1use crate::enums::{SignatureAlgorithm, SignatureScheme};
2use crate::error::Error;
3
4use pki_types::CertificateDer;
5
6use alloc::boxed::Box;
7use alloc::sync::Arc;
8use alloc::vec::Vec;
9use core::fmt::Debug;
10
11/// An abstract signing key.
12///
13/// This interface is used by rustls to use a private signing key
14/// for authentication.  This includes server and client authentication.
15///
16/// Objects of this type are always used within Rustls as
17/// `Arc<dyn SigningKey>`. There are no concrete public structs in Rustls
18/// that implement this trait.
19///
20/// There are two main ways to get a signing key:
21///
22///  - [`KeyProvider::load_private_key()`], or
23///  - some other method outside of the `KeyProvider` extension trait,
24///    for instance:
25///    - [`crypto::ring::sign::any_ecdsa_type()`]
26///    - [`crypto::ring::sign::any_eddsa_type()`]
27///    - [`crypto::ring::sign::any_supported_type()`]
28///    - [`crypto::aws_lc_rs::sign::any_ecdsa_type()`]
29///    - [`crypto::aws_lc_rs::sign::any_eddsa_type()`]
30///    - [`crypto::aws_lc_rs::sign::any_supported_type()`]
31///
32/// The `KeyProvider` method `load_private_key()` is called under the hood by
33/// [`ConfigBuilder::with_single_cert()`],
34/// [`ConfigBuilder::with_client_auth_cert()`], and
35/// [`ConfigBuilder::with_single_cert_with_ocsp()`].
36///
37/// A signing key created outside of the `KeyProvider` extension trait can be used
38/// to create a [`CertifiedKey`], which in turn can be used to create a
39/// [`ResolvesServerCertUsingSni`]. Alternately, a `CertifiedKey` can be returned from a
40/// custom implementation of the [`ResolvesServerCert`] or [`ResolvesClientCert`] traits.
41///
42/// [`KeyProvider::load_private_key()`]: crate::crypto::KeyProvider::load_private_key
43/// [`ConfigBuilder::with_single_cert()`]: crate::ConfigBuilder::with_single_cert
44/// [`ConfigBuilder::with_single_cert_with_ocsp()`]: crate::ConfigBuilder::with_single_cert_with_ocsp
45/// [`ConfigBuilder::with_client_auth_cert()`]: crate::ConfigBuilder::with_client_auth_cert
46/// [`crypto::ring::sign::any_ecdsa_type()`]: crate::crypto::ring::sign::any_ecdsa_type
47/// [`crypto::ring::sign::any_eddsa_type()`]: crate::crypto::ring::sign::any_eddsa_type
48/// [`crypto::ring::sign::any_supported_type()`]: crate::crypto::ring::sign::any_supported_type
49/// [`crypto::aws_lc_rs::sign::any_ecdsa_type()`]: crate::crypto::aws_lc_rs::sign::any_ecdsa_type
50/// [`crypto::aws_lc_rs::sign::any_eddsa_type()`]: crate::crypto::aws_lc_rs::sign::any_eddsa_type
51/// [`crypto::aws_lc_rs::sign::any_supported_type()`]: crate::crypto::aws_lc_rs::sign::any_supported_type
52/// [`ResolvesServerCertUsingSni`]: crate::server::ResolvesServerCertUsingSni
53/// [`ResolvesServerCert`]: crate::server::ResolvesServerCert
54/// [`ResolvesClientCert`]: crate::client::ResolvesClientCert
55pub trait SigningKey: Debug + Send + Sync {
56    /// Choose a `SignatureScheme` from those offered.
57    ///
58    /// Expresses the choice by returning something that implements `Signer`,
59    /// using the chosen scheme.
60    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>>;
61
62    /// What kind of key we have.
63    fn algorithm(&self) -> SignatureAlgorithm;
64}
65
66/// A thing that can sign a message.
67pub trait Signer: Debug + Send + Sync {
68    /// Signs `message` using the selected scheme.
69    ///
70    /// `message` is not hashed; the implementer must hash it using the hash function
71    /// implicit in [`Self::scheme()`].
72    ///
73    /// The returned signature format is also defined by [`Self::scheme()`].
74    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error>;
75
76    /// Reveals which scheme will be used when you call [`Self::sign()`].
77    fn scheme(&self) -> SignatureScheme;
78}
79
80/// A packaged-together certificate chain, matching `SigningKey` and
81/// optional stapled OCSP response.
82#[derive(Clone, Debug)]
83pub struct CertifiedKey {
84    /// The certificate chain.
85    pub cert: Vec<CertificateDer<'static>>,
86
87    /// The certified key.
88    pub key: Arc<dyn SigningKey>,
89
90    /// An optional OCSP response from the certificate issuer,
91    /// attesting to its continued validity.
92    pub ocsp: Option<Vec<u8>>,
93}
94
95impl CertifiedKey {
96    /// Make a new CertifiedKey, with the given chain and key.
97    ///
98    /// The cert chain must not be empty. The first certificate in the chain
99    /// must be the end-entity certificate.
100    pub fn new(cert: Vec<CertificateDer<'static>>, key: Arc<dyn SigningKey>) -> Self {
101        Self {
102            cert,
103            key,
104            ocsp: None,
105        }
106    }
107
108    /// The end-entity certificate.
109    pub fn end_entity_cert(&self) -> Result<&CertificateDer<'_>, Error> {
110        self.cert
111            .first()
112            .ok_or(Error::NoCertificatesPresented)
113    }
114}