1use crate::sign::SigningKey;
2use crate::suites;
3use crate::{Error, NamedGroup};
4
5use alloc::boxed::Box;
6use alloc::sync::Arc;
7use alloc::vec::Vec;
8use core::fmt::Debug;
9
10use pki_types::PrivateKeyDer;
11use zeroize::Zeroize;
12
13#[cfg(all(doc, feature = "tls12"))]
14use crate::Tls12CipherSuite;
15#[cfg(doc)]
16use crate::{
17 client, crypto, server, sign, ClientConfig, ConfigBuilder, ServerConfig, SupportedCipherSuite,
18 Tls13CipherSuite,
19};
20
21pub use crate::webpki::{
22 verify_tls12_signature, verify_tls13_signature, WebPkiSupportedAlgorithms,
23};
24
25/// *ring* based CryptoProvider.
26#[cfg(feature = "ring")]
27pub mod ring;
28
29/// aws-lc-rs-based CryptoProvider.
30#[cfg(feature = "aws_lc_rs")]
31pub mod aws_lc_rs;
32
33/// TLS message encryption/decryption interfaces.
34pub mod cipher;
35
36/// Hashing interfaces.
37pub mod hash;
38
39/// HMAC interfaces.
40pub mod hmac;
41
42/// Cryptography specific to TLS1.2.
43pub mod tls12;
44
45/// Cryptography specific to TLS1.3.
46pub mod tls13;
47
48/// Hybrid public key encryption (RFC 9180).
49#[doc(hidden)]
50pub mod hpke;
51
52// Message signing interfaces. Re-exported under rustls::sign. Kept crate-internal here to
53// avoid having two import paths to the same types.
54pub(crate) mod signer;
55
56pub use crate::rand::GetRandomFailed;
57
58pub use crate::suites::CipherSuiteCommon;
59
60pub use crate::msgs::handshake::KeyExchangeAlgorithm;
61
62/// Controls core cryptography used by rustls.
63///
64/// This crate comes with two built-in options, provided as
65/// `CryptoProvider` structures:
66///
67/// - [`crypto::ring::default_provider`]: (behind the `ring` crate feature, which
68/// is enabled by default). This provider uses the [*ring*](https://github.com/briansmith/ring)
69/// crate.
70/// - [`crypto::aws_lc_rs::default_provider`]: (behind the `aws_lc_rs` feature,
71/// which is optional). This provider uses the [aws-lc-rs](https://github.com/aws/aws-lc-rs)
72/// crate.
73///
74/// This structure provides defaults. Everything in it can be overridden at
75/// runtime by replacing field values as needed.
76///
77/// # Using a specific `CryptoProvider`
78///
79/// Supply the provider when constructing your [`ClientConfig`] or [`ServerConfig`]:
80///
81/// - [`ClientConfig::builder_with_provider()`]
82/// - [`ServerConfig::builder_with_provider()`]
83///
84/// When creating and configuring a webpki-backed client or server certificate verifier, a choice of
85/// provider is also needed to start the configuration process:
86///
87/// - [`client::WebPkiServerVerifier::builder_with_provider()`]
88/// - [`server::WebPkiClientVerifier::builder_with_provider()`]
89///
90/// # Making a custom `CryptoProvider`
91///
92/// Your goal will be to populate a [`crypto::CryptoProvider`] struct instance.
93///
94/// ## Which elements are required?
95///
96/// There is no requirement that the individual elements (`SupportedCipherSuite`, `SupportedKxGroup`,
97/// `SigningKey`, etc.) come from the same crate. It is allowed and expected that uninteresting
98/// elements would be delegated back to one of the default providers (statically) or a parent
99/// provider (dynamically).
100///
101/// For example, if we want to make a provider that just overrides key loading in the config builder
102/// API ([`ConfigBuilder::with_single_cert`] etc.), it might look like this:
103///
104/// ```
105/// # #[cfg(feature = "ring")] {
106/// # use std::sync::Arc;
107/// # mod fictious_hsm_api { pub fn load_private_key(key_der: pki_types::PrivateKeyDer<'static>) -> ! { unreachable!(); } }
108/// use rustls::crypto::ring;
109///
110/// pub fn provider() -> rustls::crypto::CryptoProvider {
111/// rustls::crypto::CryptoProvider{
112/// key_provider: &HsmKeyLoader,
113/// ..ring::default_provider()
114/// }
115/// }
116///
117/// #[derive(Debug)]
118/// struct HsmKeyLoader;
119///
120/// impl rustls::crypto::KeyProvider for HsmKeyLoader {
121/// fn load_private_key(&self, key_der: pki_types::PrivateKeyDer<'static>) -> Result<Arc<dyn rustls::sign::SigningKey>, rustls::Error> {
122/// fictious_hsm_api::load_private_key(key_der)
123/// }
124/// }
125/// # }
126/// ```
127///
128/// ## References to the individual elements
129///
130/// The elements are documented separately:
131///
132/// - **Random** - see [`crypto::SecureRandom::fill()`].
133/// - **Cipher suites** - see [`SupportedCipherSuite`], [`Tls12CipherSuite`], and
134/// [`Tls13CipherSuite`].
135/// - **Key exchange groups** - see [`crypto::SupportedKxGroup`].
136/// - **Signature verification algorithms** - see [`crypto::WebPkiSupportedAlgorithms`].
137/// - **Authentication key loading** - see [`crypto::KeyProvider::load_private_key()`] and
138/// [`sign::SigningKey`].
139///
140/// # Example code
141///
142/// See [provider-example/] for a full client and server example that uses
143/// cryptography from the [rust-crypto] and [dalek-cryptography] projects.
144///
145/// ```shell
146/// $ cargo run --example client | head -3
147/// Current ciphersuite: TLS13_CHACHA20_POLY1305_SHA256
148/// HTTP/1.1 200 OK
149/// Content-Type: text/html; charset=utf-8
150/// Content-Length: 19899
151/// ```
152///
153/// [provider-example/]: https://github.com/rustls/rustls/tree/main/provider-example/
154/// [rust-crypto]: https://github.com/rustcrypto
155/// [dalek-cryptography]: https://github.com/dalek-cryptography
156#[derive(Debug, Clone)]
157pub struct CryptoProvider {
158 /// List of supported ciphersuites, in preference order -- the first element
159 /// is the highest priority.
160 ///
161 /// The `SupportedCipherSuite` type carries both configuration and implementation.
162 pub cipher_suites: Vec<suites::SupportedCipherSuite>,
163
164 /// List of supported key exchange groups, in preference order -- the
165 /// first element is the highest priority.
166 ///
167 /// The first element in this list is the _default key share algorithm_,
168 /// and in TLS1.3 a key share for it is sent in the client hello.
169 ///
170 /// The `SupportedKxGroup` type carries both configuration and implementation.
171 pub kx_groups: Vec<&'static dyn SupportedKxGroup>,
172
173 /// List of signature verification algorithms for use with webpki.
174 ///
175 /// These are used for both certificate chain verification and handshake signature verification.
176 ///
177 /// This is called by [`ConfigBuilder::with_root_certificates()`],
178 /// [`server::WebPkiClientVerifier::builder_with_provider()`] and
179 /// [`client::WebPkiServerVerifier::builder_with_provider()`].
180 pub signature_verification_algorithms: WebPkiSupportedAlgorithms,
181
182 /// Source of cryptographically secure random numbers.
183 pub secure_random: &'static dyn SecureRandom,
184
185 /// Provider for loading private [SigningKey]s from [PrivateKeyDer].
186 pub key_provider: &'static dyn KeyProvider,
187}
188
189/// A source of cryptographically secure randomness.
190pub trait SecureRandom: Send + Sync + Debug {
191 /// Fill the given buffer with random bytes.
192 ///
193 /// The bytes must be sourced from a cryptographically secure random number
194 /// generator seeded with good quality, secret entropy.
195 ///
196 /// This is used for all randomness required by rustls, but not necessarily
197 /// randomness required by the underlying cryptography library. For example:
198 /// [`SupportedKxGroup::start()`] requires random material to generate
199 /// an ephemeral key exchange key, but this is not included in the interface with
200 /// rustls: it is assumed that the cryptography library provides for this itself.
201 fn fill(&self, buf: &mut [u8]) -> Result<(), GetRandomFailed>;
202}
203
204/// A mechanism for loading private [SigningKey]s from [PrivateKeyDer].
205pub trait KeyProvider: Send + Sync + Debug {
206 /// Decode and validate a private signing key from `key_der`.
207 ///
208 /// This is used by [`ConfigBuilder::with_client_auth_cert()`], [`ConfigBuilder::with_single_cert()`],
209 /// and [`ConfigBuilder::with_single_cert_with_ocsp()`]. The key types and formats supported by this
210 /// function directly defines the key types and formats supported in those APIs.
211 ///
212 /// Return an error if the key type encoding is not supported, or if the key fails validation.
213 fn load_private_key(
214 &self,
215 key_der: PrivateKeyDer<'static>,
216 ) -> Result<Arc<dyn SigningKey>, Error>;
217}
218
219/// A supported key exchange group.
220///
221/// This type carries both configuration and implementation. Specifically,
222/// it has a TLS-level name expressed using the [`NamedGroup`] enum, and
223/// a function which produces a [`ActiveKeyExchange`].
224///
225/// Compare with [`NamedGroup`], which carries solely a protocol identifier.
226pub trait SupportedKxGroup: Send + Sync + Debug {
227 /// Start a key exchange.
228 ///
229 /// This will prepare an ephemeral secret key in the supported group, and a corresponding
230 /// public key. The key exchange can be completed by calling [ActiveKeyExchange#complete]
231 /// or discarded.
232 ///
233 /// # Errors
234 ///
235 /// This can fail if the random source fails during ephemeral key generation.
236 fn start(&self) -> Result<Box<dyn ActiveKeyExchange>, Error>;
237
238 /// Named group the SupportedKxGroup operates in.
239 ///
240 /// If the `NamedGroup` enum does not have a name for the algorithm you are implementing,
241 /// you can use [`NamedGroup::Unknown`].
242 fn name(&self) -> NamedGroup;
243}
244
245/// An in-progress key exchange originating from a [`SupportedKxGroup`].
246pub trait ActiveKeyExchange: Send + Sync {
247 /// Completes the key exchange, given the peer's public key.
248 ///
249 /// This method must return an error if `peer_pub_key` is invalid: either
250 /// mis-encoded, or an invalid public key (such as, but not limited to, being
251 /// in a small order subgroup).
252 ///
253 /// The shared secret is returned as a [`SharedSecret`] which can be constructed
254 /// from a `&[u8]`.
255 ///
256 /// This consumes and so terminates the [`ActiveKeyExchange`].
257 fn complete(self: Box<Self>, peer_pub_key: &[u8]) -> Result<SharedSecret, Error>;
258
259 /// Return the public key being used.
260 ///
261 /// The encoding required is defined in
262 /// [RFC8446 section 4.2.8.2](https://www.rfc-editor.org/rfc/rfc8446#section-4.2.8.2).
263 fn pub_key(&self) -> &[u8];
264
265 /// Return the group being used.
266 fn group(&self) -> NamedGroup;
267}
268
269/// The result from [`ActiveKeyExchange::complete`].
270pub struct SharedSecret(Vec<u8>);
271
272impl SharedSecret {
273 /// Returns the shared secret as a slice of bytes.
274 pub fn secret_bytes(&self) -> &[u8] {
275 &self.0
276 }
277}
278
279impl Drop for SharedSecret {
280 fn drop(&mut self) {
281 self.0.zeroize();
282 }
283}
284
285impl From<&[u8]> for SharedSecret {
286 fn from(source: &[u8]) -> Self {
287 Self(source.to_vec())
288 }
289}
290