1 | use crate::sign::SigningKey; |
2 | use crate::suites; |
3 | use crate::{Error, NamedGroup}; |
4 | |
5 | use alloc::boxed::Box; |
6 | use alloc::sync::Arc; |
7 | use alloc::vec::Vec; |
8 | use core::fmt::Debug; |
9 | |
10 | use pki_types::PrivateKeyDer; |
11 | use zeroize::Zeroize; |
12 | |
13 | #[cfg (all(doc, feature = "tls12" ))] |
14 | use crate::Tls12CipherSuite; |
15 | #[cfg (doc)] |
16 | use crate::{ |
17 | client, crypto, server, sign, ClientConfig, ConfigBuilder, ServerConfig, SupportedCipherSuite, |
18 | Tls13CipherSuite, |
19 | }; |
20 | |
21 | pub use crate::webpki::{ |
22 | verify_tls12_signature, verify_tls13_signature, WebPkiSupportedAlgorithms, |
23 | }; |
24 | |
25 | /// *ring* based CryptoProvider. |
26 | #[cfg (feature = "ring" )] |
27 | pub mod ring; |
28 | |
29 | /// aws-lc-rs-based CryptoProvider. |
30 | #[cfg (feature = "aws_lc_rs" )] |
31 | pub mod aws_lc_rs; |
32 | |
33 | /// TLS message encryption/decryption interfaces. |
34 | pub mod cipher; |
35 | |
36 | /// Hashing interfaces. |
37 | pub mod hash; |
38 | |
39 | /// HMAC interfaces. |
40 | pub mod hmac; |
41 | |
42 | /// Cryptography specific to TLS1.2. |
43 | pub mod tls12; |
44 | |
45 | /// Cryptography specific to TLS1.3. |
46 | pub mod tls13; |
47 | |
48 | /// Hybrid public key encryption (RFC 9180). |
49 | #[doc (hidden)] |
50 | pub 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. |
54 | pub(crate) mod signer; |
55 | |
56 | pub use crate::rand::GetRandomFailed; |
57 | |
58 | pub use crate::suites::CipherSuiteCommon; |
59 | |
60 | pub 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)] |
157 | pub 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. |
190 | pub 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]. |
205 | pub 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. |
226 | pub 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`]. |
246 | pub 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`]. |
270 | pub struct SharedSecret(Vec<u8>); |
271 | |
272 | impl SharedSecret { |
273 | /// Returns the shared secret as a slice of bytes. |
274 | pub fn secret_bytes(&self) -> &[u8] { |
275 | &self.0 |
276 | } |
277 | } |
278 | |
279 | impl Drop for SharedSecret { |
280 | fn drop(&mut self) { |
281 | self.0.zeroize(); |
282 | } |
283 | } |
284 | |
285 | impl From<&[u8]> for SharedSecret { |
286 | fn from(source: &[u8]) -> Self { |
287 | Self(source.to_vec()) |
288 | } |
289 | } |
290 | |