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(err:Error::NoCertificatesPresented)
113 }
114}
115