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