1 | //! # Rustls - a modern TLS library |
2 | //! |
3 | //! Rustls is a TLS library that aims to provide a good level of cryptographic security, |
4 | //! requires no configuration to achieve that security, and provides no unsafe features or |
5 | //! obsolete cryptography by default. |
6 | //! |
7 | //! Rustls implements TLS1.2 and TLS1.3 for both clients and servers. See [the full |
8 | //! list of protocol features](manual::_04_features). |
9 | //! |
10 | //! ### Platform support |
11 | //! |
12 | //! While Rustls itself is platform independent, by default it uses [`aws-lc-rs`] for implementing |
13 | //! the cryptography in TLS. See [the aws-lc-rs FAQ][aws-lc-rs-platforms-faq] for more details of the |
14 | //! platform/architecture support constraints in aws-lc-rs. |
15 | //! |
16 | //! [`ring`] is also available via the `ring` crate feature: see |
17 | //! [the supported `ring` target platforms][ring-target-platforms]. |
18 | //! |
19 | //! By providing a custom instance of the [`crypto::CryptoProvider`] struct, you |
20 | //! can replace all cryptography dependencies of rustls. This is a route to being portable |
21 | //! to a wider set of architectures and environments, or compliance requirements. See the |
22 | //! [`crypto::CryptoProvider`] documentation for more details. |
23 | //! |
24 | //! Specifying `default-features = false` when depending on rustls will remove the implicit |
25 | //! dependency on aws-lc-rs. |
26 | //! |
27 | //! Rustls requires Rust 1.71 or later. It has an optional dependency on zlib-rs which requires 1.75 or later. |
28 | //! |
29 | //! [ring-target-platforms]: https://github.com/briansmith/ring/blob/2e8363b433fa3b3962c877d9ed2e9145612f3160/include/ring-core/target.h#L18-L64 |
30 | //! [`crypto::CryptoProvider`]: crate::crypto::CryptoProvider |
31 | //! [`ring`]: https://crates.io/crates/ring |
32 | //! [aws-lc-rs-platforms-faq]: https://aws.github.io/aws-lc-rs/faq.html#can-i-run-aws-lc-rs-on-x-platform-or-architecture |
33 | //! [`aws-lc-rs`]: https://crates.io/crates/aws-lc-rs |
34 | //! |
35 | //! ### Cryptography providers |
36 | //! |
37 | //! Since Rustls 0.22 it has been possible to choose the provider of the cryptographic primitives |
38 | //! that Rustls uses. This may be appealing if you have specific platform, compliance or feature |
39 | //! requirements that aren't met by the default provider, [`aws-lc-rs`]. |
40 | //! |
41 | //! Users that wish to customize the provider in use can do so when constructing `ClientConfig` |
42 | //! and `ServerConfig` instances using the `with_crypto_provider` method on the respective config |
43 | //! builder types. See the [`crypto::CryptoProvider`] documentation for more details. |
44 | //! |
45 | //! #### Built-in providers |
46 | //! |
47 | //! Rustls ships with two built-in providers controlled by associated crate features: |
48 | //! |
49 | //! * [`aws-lc-rs`] - enabled by default, available with the `aws_lc_rs` crate feature enabled. |
50 | //! * [`ring`] - available with the `ring` crate feature enabled. |
51 | //! |
52 | //! See the documentation for [`crypto::CryptoProvider`] for details on how providers are |
53 | //! selected. |
54 | //! |
55 | //! #### Third-party providers |
56 | //! |
57 | //! The community has also started developing third-party providers for Rustls: |
58 | //! |
59 | //! * [`rustls-mbedtls-provider`] - a provider that uses [`mbedtls`] for cryptography. |
60 | //! * [`rustls-openssl`] - a provider that uses [OpenSSL] for cryptography. |
61 | //! * [`boring-rustls-provider`] - a work-in-progress provider that uses [`boringssl`] for |
62 | //! cryptography. |
63 | //! * [`rustls-rustcrypto`] - an experimental provider that uses the crypto primitives |
64 | //! from [`RustCrypto`] for cryptography. |
65 | //! * [`rustls-symcrypt`] - a provider that uses Microsoft's [SymCrypt] library. |
66 | //! * [`rustls-wolfcrypt-provider`] - a work-in-progress provider that uses [`wolfCrypt`] for cryptography. |
67 | //! |
68 | //! [`rustls-mbedtls-provider`]: https://github.com/fortanix/rustls-mbedtls-provider |
69 | //! [`mbedtls`]: https://github.com/Mbed-TLS/mbedtls |
70 | //! [`rustls-openssl`]: https://github.com/tofay/rustls-openssl |
71 | //! [OpenSSL]: https://openssl-library.org/ |
72 | //! [`rustls-symcrypt`]: https://github.com/microsoft/rustls-symcrypt |
73 | //! [SymCrypt]: https://github.com/microsoft/SymCrypt |
74 | //! [`boring-rustls-provider`]: https://github.com/janrueth/boring-rustls-provider |
75 | //! [`boringssl`]: https://github.com/google/boringssl |
76 | //! [`rustls-rustcrypto`]: https://github.com/RustCrypto/rustls-rustcrypto |
77 | //! [`RustCrypto`]: https://github.com/RustCrypto |
78 | //! [`rustls-wolfcrypt-provider`]: https://github.com/wolfSSL/rustls-wolfcrypt-provider |
79 | //! [`wolfCrypt`]: https://www.wolfssl.com/products/wolfcrypt |
80 | //! |
81 | //! #### Custom provider |
82 | //! |
83 | //! We also provide a simple example of writing your own provider in the [custom provider example]. |
84 | //! This example implements a minimal provider using parts of the [`RustCrypto`] ecosystem. |
85 | //! |
86 | //! See the [Making a custom CryptoProvider] section of the documentation for more information |
87 | //! on this topic. |
88 | //! |
89 | //! [custom provider example]: https://github.com/rustls/rustls/tree/main/provider-example/ |
90 | //! [`RustCrypto`]: https://github.com/RustCrypto |
91 | //! [Making a custom CryptoProvider]: https://docs.rs/rustls/latest/rustls/crypto/struct.CryptoProvider.html#making-a-custom-cryptoprovider |
92 | //! |
93 | //! ## Design overview |
94 | //! |
95 | //! Rustls is a low-level library. If your goal is to make HTTPS connections you may prefer |
96 | //! to use a library built on top of Rustls like [hyper] or [ureq]. |
97 | //! |
98 | //! [hyper]: https://crates.io/crates/hyper |
99 | //! [ureq]: https://crates.io/crates/ureq |
100 | //! |
101 | //! ### Rustls does not take care of network IO |
102 | //! It doesn't make or accept TCP connections, or do DNS, or read or write files. |
103 | //! |
104 | //! Our [examples] directory contains demos that show how to handle I/O using the |
105 | //! [`stream::Stream`] helper, as well as more complex asynchronous I/O using [`mio`]. |
106 | //! If you're already using Tokio for an async runtime you may prefer to use [`tokio-rustls`] instead |
107 | //! of interacting with rustls directly. |
108 | //! |
109 | //! [examples]: https://github.com/rustls/rustls/tree/main/examples |
110 | //! [`tokio-rustls`]: https://github.com/rustls/tokio-rustls |
111 | //! |
112 | //! ### Rustls provides encrypted pipes |
113 | //! These are the [`ServerConnection`] and [`ClientConnection`] types. You supply raw TLS traffic |
114 | //! on the left (via the [`read_tls()`] and [`write_tls()`] methods) and then read/write the |
115 | //! plaintext on the right: |
116 | //! |
117 | //! [`read_tls()`]: Connection::read_tls |
118 | //! [`write_tls()`]: Connection::read_tls |
119 | //! |
120 | //! ```text |
121 | //! TLS Plaintext |
122 | //! === ========= |
123 | //! read_tls() +-----------------------+ reader() as io::Read |
124 | //! | | |
125 | //! +---------> ClientConnection +---------> |
126 | //! | or | |
127 | //! <---------+ ServerConnection <---------+ |
128 | //! | | |
129 | //! write_tls() +-----------------------+ writer() as io::Write |
130 | //! ``` |
131 | //! |
132 | //! ### Rustls takes care of server certificate verification |
133 | //! You do not need to provide anything other than a set of root certificates to trust. |
134 | //! Certificate verification cannot be turned off or disabled in the main API. |
135 | //! |
136 | //! ## Getting started |
137 | //! This is the minimum you need to do to make a TLS client connection. |
138 | //! |
139 | //! First we load some root certificates. These are used to authenticate the server. |
140 | //! The simplest way is to depend on the [`webpki_roots`] crate which contains |
141 | //! the Mozilla set of root certificates. |
142 | //! |
143 | //! ```rust,no_run |
144 | //! # #[cfg (feature = "aws-lc-rs" )] { |
145 | //! let root_store = rustls::RootCertStore::from_iter( |
146 | //! webpki_roots::TLS_SERVER_ROOTS |
147 | //! .iter() |
148 | //! .cloned(), |
149 | //! ); |
150 | //! # } |
151 | //! ``` |
152 | //! |
153 | //! [`webpki_roots`]: https://crates.io/crates/webpki-roots |
154 | //! |
155 | //! Next, we make a `ClientConfig`. You're likely to make one of these per process, |
156 | //! and use it for all connections made by that process. |
157 | //! |
158 | //! ```rust,no_run |
159 | //! # #[cfg (feature = "aws_lc_rs" )] { |
160 | //! # let root_store: rustls::RootCertStore = panic!(); |
161 | //! let config = rustls::ClientConfig::builder() |
162 | //! .with_root_certificates(root_store) |
163 | //! .with_no_client_auth(); |
164 | //! # } |
165 | //! ``` |
166 | //! |
167 | //! Now we can make a connection. You need to provide the server's hostname so we |
168 | //! know what to expect to find in the server's certificate. |
169 | //! |
170 | //! ```rust |
171 | //! # #[cfg (feature = "aws_lc_rs" )] { |
172 | //! # use rustls; |
173 | //! # use webpki; |
174 | //! # use std::sync::Arc; |
175 | //! # rustls::crypto::aws_lc_rs::default_provider().install_default(); |
176 | //! # let root_store = rustls::RootCertStore::from_iter( |
177 | //! # webpki_roots::TLS_SERVER_ROOTS |
178 | //! # .iter() |
179 | //! # .cloned(), |
180 | //! # ); |
181 | //! # let config = rustls::ClientConfig::builder() |
182 | //! # .with_root_certificates(root_store) |
183 | //! # .with_no_client_auth(); |
184 | //! let rc_config = Arc::new(config); |
185 | //! let example_com = "example.com" .try_into().unwrap(); |
186 | //! let mut client = rustls::ClientConnection::new(rc_config, example_com); |
187 | //! # } |
188 | //! ``` |
189 | //! |
190 | //! Now you should do appropriate IO for the `client` object. If `client.wants_read()` yields |
191 | //! true, you should call `client.read_tls()` when the underlying connection has data. |
192 | //! Likewise, if `client.wants_write()` yields true, you should call `client.write_tls()` |
193 | //! when the underlying connection is able to send data. You should continue doing this |
194 | //! as long as the connection is valid. |
195 | //! |
196 | //! The return types of `read_tls()` and `write_tls()` only tell you if the IO worked. No |
197 | //! parsing or processing of the TLS messages is done. After each `read_tls()` you should |
198 | //! therefore call `client.process_new_packets()` which parses and processes the messages. |
199 | //! Any error returned from `process_new_packets` is fatal to the connection, and will tell you |
200 | //! why. For example, if the server's certificate is expired `process_new_packets` will |
201 | //! return `Err(InvalidCertificate(Expired))`. From this point on, |
202 | //! `process_new_packets` will not do any new work and will return that error continually. |
203 | //! |
204 | //! You can extract newly received data by calling `client.reader()` (which implements the |
205 | //! `io::Read` trait). You can send data to the peer by calling `client.writer()` (which |
206 | //! implements `io::Write` trait). Note that `client.writer().write()` buffers data you |
207 | //! send if the TLS connection is not yet established: this is useful for writing (say) a |
208 | //! HTTP request, but this is buffered so avoid large amounts of data. |
209 | //! |
210 | //! The following code uses a fictional socket IO API for illustration, and does not handle |
211 | //! errors. |
212 | //! |
213 | //! ```rust,no_run |
214 | //! # #[cfg (feature = "aws_lc_rs" )] { |
215 | //! # let mut client = rustls::ClientConnection::new(panic!(), panic!()).unwrap(); |
216 | //! # struct Socket { } |
217 | //! # impl Socket { |
218 | //! # fn ready_for_write(&self) -> bool { false } |
219 | //! # fn ready_for_read(&self) -> bool { false } |
220 | //! # fn wait_for_something_to_happen(&self) { } |
221 | //! # } |
222 | //! # |
223 | //! # use std::io::{Read, Write, Result}; |
224 | //! # impl Read for Socket { |
225 | //! # fn read(&mut self, buf: &mut [u8]) -> Result<usize> { panic!() } |
226 | //! # } |
227 | //! # impl Write for Socket { |
228 | //! # fn write(&mut self, buf: &[u8]) -> Result<usize> { panic!() } |
229 | //! # fn flush(&mut self) -> Result<()> { panic!() } |
230 | //! # } |
231 | //! # |
232 | //! # fn connect(_address: &str, _port: u16) -> Socket { |
233 | //! # panic!(); |
234 | //! # } |
235 | //! use std::io; |
236 | //! use rustls::Connection; |
237 | //! |
238 | //! client.writer().write(b"GET / HTTP/1.0 \r\n\r\n" ).unwrap(); |
239 | //! let mut socket = connect("example.com" , 443); |
240 | //! loop { |
241 | //! if client.wants_read() && socket.ready_for_read() { |
242 | //! client.read_tls(&mut socket).unwrap(); |
243 | //! client.process_new_packets().unwrap(); |
244 | //! |
245 | //! let mut plaintext = Vec::new(); |
246 | //! client.reader().read_to_end(&mut plaintext).unwrap(); |
247 | //! io::stdout().write(&plaintext).unwrap(); |
248 | //! } |
249 | //! |
250 | //! if client.wants_write() && socket.ready_for_write() { |
251 | //! client.write_tls(&mut socket).unwrap(); |
252 | //! } |
253 | //! |
254 | //! socket.wait_for_something_to_happen(); |
255 | //! } |
256 | //! # } |
257 | //! ``` |
258 | //! |
259 | //! # Examples |
260 | //! |
261 | //! You can find several client and server examples of varying complexity in the [examples] |
262 | //! directory, including [`tlsserver-mio`](https://github.com/rustls/rustls/blob/main/examples/src/bin/tlsserver-mio.rs) |
263 | //! and [`tlsclient-mio`](https://github.com/rustls/rustls/blob/main/examples/src/bin/tlsclient-mio.rs) |
264 | //! \- full worked examples using [`mio`]. |
265 | //! |
266 | //! [`mio`]: https://docs.rs/mio/latest/mio/ |
267 | //! |
268 | //! # Manual |
269 | //! |
270 | //! The [rustls manual](crate::manual) explains design decisions and includes how-to guidance. |
271 | //! |
272 | //! # Crate features |
273 | //! Here's a list of what features are exposed by the rustls crate and what |
274 | //! they mean. |
275 | //! |
276 | //! - `std` (enabled by default): enable the high-level (buffered) Connection API and other functionality |
277 | //! which relies on the `std` library. |
278 | //! |
279 | //! - `aws_lc_rs` (enabled by default): makes the rustls crate depend on the [`aws-lc-rs`] crate. |
280 | //! Use `rustls::crypto::aws_lc_rs::default_provider().install_default()` to |
281 | //! use it as the default `CryptoProvider`, or provide it explicitly |
282 | //! when making a `ClientConfig` or `ServerConfig`. |
283 | //! |
284 | //! Note that aws-lc-rs has additional build-time dependencies like cmake. |
285 | //! See [the documentation](https://aws.github.io/aws-lc-rs/requirements/index.html) for details. |
286 | //! |
287 | //! - `ring`: makes the rustls crate depend on the *ring* crate for cryptography. |
288 | //! Use `rustls::crypto::ring::default_provider().install_default()` to |
289 | //! use it as the default `CryptoProvider`, or provide it explicitly |
290 | //! when making a `ClientConfig` or `ServerConfig`. |
291 | //! |
292 | //! - `fips`: enable support for FIPS140-3-approved cryptography, via the [`aws-lc-rs`] crate. |
293 | //! This feature enables the `aws_lc_rs` crate feature, which makes the rustls crate depend |
294 | //! on [aws-lc-rs](https://github.com/aws/aws-lc-rs). It also changes the default |
295 | //! for [`ServerConfig::require_ems`] and [`ClientConfig::require_ems`]. |
296 | //! |
297 | //! See [manual::_06_fips] for more details. |
298 | //! |
299 | //! - `prefer-post-quantum`: for the [`aws-lc-rs`]-backed provider, prioritizes post-quantum secure |
300 | //! key exchange by default (using X25519MLKEM768). This feature merely alters the order |
301 | //! of `rustls::crypto::aws_lc_rs::DEFAULT_KX_GROUPS`. We expect to add this feature |
302 | //! to the default set in a future minor release. See [the manual][x25519mlkem768-manual] |
303 | //! for more details. |
304 | //! |
305 | //! - `custom-provider`: disables implicit use of built-in providers (`aws-lc-rs` or `ring`). This forces |
306 | //! applications to manually install one, for instance, when using a custom `CryptoProvider`. |
307 | //! |
308 | //! - `tls12` (enabled by default): enable support for TLS version 1.2. Note that, due to the |
309 | //! additive nature of Cargo features and because it is enabled by default, other crates |
310 | //! in your dependency graph could re-enable it for your application. If you want to disable |
311 | //! TLS 1.2 for security reasons, consider explicitly enabling TLS 1.3 only in the config |
312 | //! builder API. |
313 | //! |
314 | //! - `logging` (enabled by default): make the rustls crate depend on the `log` crate. |
315 | //! rustls outputs interesting protocol-level messages at `trace!` and `debug!` level, |
316 | //! and protocol-level errors at `warn!` and `error!` level. The log messages do not |
317 | //! contain secret key data, and so are safe to archive without affecting session security. |
318 | //! |
319 | //! - `read_buf`: when building with Rust Nightly, adds support for the unstable |
320 | //! `std::io::ReadBuf` and related APIs. This reduces costs from initializing |
321 | //! buffers. Will do nothing on non-Nightly releases. |
322 | //! |
323 | //! - `brotli`: uses the `brotli` crate for RFC8879 certificate compression support. |
324 | //! |
325 | //! - `zlib`: uses the `zlib-rs` crate for RFC8879 certificate compression support. |
326 | //! |
327 | //! [x25519mlkem768-manual]: manual::_05_defaults#about-the-post-quantum-secure-key-exchange-x25519mlkem768 |
328 | |
329 | // Require docs for public APIs, deny unsafe code, etc. |
330 | #![forbid (unsafe_code, unused_must_use)] |
331 | #![cfg_attr (not(any(read_buf, bench, coverage_nightly)), forbid(unstable_features))] |
332 | #![warn ( |
333 | clippy::alloc_instead_of_core, |
334 | clippy::clone_on_ref_ptr, |
335 | clippy::manual_let_else, |
336 | clippy::std_instead_of_core, |
337 | clippy::use_self, |
338 | clippy::upper_case_acronyms, |
339 | elided_lifetimes_in_paths, |
340 | missing_docs, |
341 | trivial_casts, |
342 | trivial_numeric_casts, |
343 | unreachable_pub, |
344 | unused_import_braces, |
345 | unused_extern_crates, |
346 | unused_qualifications |
347 | )] |
348 | // Relax these clippy lints: |
349 | // - ptr_arg: this triggers on references to type aliases that are Vec |
350 | // underneath. |
351 | // - too_many_arguments: some things just need a lot of state, wrapping it |
352 | // doesn't necessarily make it easier to follow what's going on |
353 | // - new_ret_no_self: we sometimes return `Arc<Self>`, which seems fine |
354 | // - single_component_path_imports: our top-level `use log` import causes |
355 | // a false positive, https://github.com/rust-lang/rust-clippy/issues/5210 |
356 | // - new_without_default: for internal constructors, the indirection is not |
357 | // helpful |
358 | #![allow ( |
359 | clippy::too_many_arguments, |
360 | clippy::new_ret_no_self, |
361 | clippy::ptr_arg, |
362 | clippy::single_component_path_imports, |
363 | clippy::new_without_default |
364 | )] |
365 | // Enable documentation for all features on docs.rs |
366 | #![cfg_attr (docsrs, feature(doc_cfg, doc_auto_cfg))] |
367 | // Enable coverage() attr for nightly coverage builds, see |
368 | // <https://github.com/rust-lang/rust/issues/84605> |
369 | // (`coverage_nightly` is a cfg set by `cargo-llvm-cov`) |
370 | #![cfg_attr (coverage_nightly, feature(coverage_attribute))] |
371 | // XXX: Because of https://github.com/rust-lang/rust/issues/54726, we cannot |
372 | // write `#![rustversion::attr(nightly, feature(read_buf))]` here. Instead, |
373 | // build.rs set `read_buf` for (only) Rust Nightly to get the same effect. |
374 | // |
375 | // All the other conditional logic in the crate could use |
376 | // `#[rustversion::nightly]` instead of `#[cfg(read_buf)]`; `#[cfg(read_buf)]` |
377 | // is used to avoid needing `rustversion` to be compiled twice during |
378 | // cross-compiling. |
379 | #![cfg_attr (read_buf, feature(read_buf))] |
380 | #![cfg_attr (read_buf, feature(core_io_borrowed_buf))] |
381 | #![cfg_attr (bench, feature(test))] |
382 | #![no_std ] |
383 | |
384 | extern crate alloc; |
385 | // This `extern crate` plus the `#![no_std]` attribute changes the default prelude from |
386 | // `std::prelude` to `core::prelude`. That forces one to _explicitly_ import (`use`) everything that |
387 | // is in `std::prelude` but not in `core::prelude`. This helps maintain no-std support as even |
388 | // developers that are not interested in, or aware of, no-std support and / or that never run |
389 | // `cargo build --no-default-features` locally will get errors when they rely on `std::prelude` API. |
390 | #[cfg (any(feature = "std" , test))] |
391 | extern crate std; |
392 | |
393 | #[cfg (doc)] |
394 | use crate::crypto::CryptoProvider; |
395 | |
396 | // Import `test` sysroot crate for `Bencher` definitions. |
397 | #[cfg (bench)] |
398 | #[allow (unused_extern_crates)] |
399 | extern crate test; |
400 | |
401 | // log for logging (optional). |
402 | #[cfg (feature = "logging" )] |
403 | use log; |
404 | |
405 | #[cfg (not(feature = "logging" ))] |
406 | mod log { |
407 | macro_rules! trace ( ($($tt:tt)*) => {{}} ); |
408 | macro_rules! debug ( ($($tt:tt)*) => {{}} ); |
409 | macro_rules! error ( ($($tt:tt)*) => {{}} ); |
410 | macro_rules! _warn ( ($($tt:tt)*) => {{}} ); |
411 | pub(crate) use {_warn as warn, debug, error, trace}; |
412 | } |
413 | |
414 | #[cfg (test)] |
415 | #[macro_use ] |
416 | mod test_macros; |
417 | |
418 | /// This internal `sync` module aliases the `Arc` implementation to allow downstream forks |
419 | /// of rustls targeting architectures without atomic pointers to replace the implementation |
420 | /// with another implementation such as `portable_atomic_util::Arc` in one central location. |
421 | mod sync { |
422 | #[allow (clippy::disallowed_types)] |
423 | pub(crate) type Arc<T> = alloc::sync::Arc<T>; |
424 | #[allow (clippy::disallowed_types)] |
425 | pub(crate) type Weak<T> = alloc::sync::Weak<T>; |
426 | } |
427 | |
428 | #[macro_use ] |
429 | mod msgs; |
430 | mod common_state; |
431 | pub mod compress; |
432 | mod conn; |
433 | /// Crypto provider interface. |
434 | pub mod crypto; |
435 | mod error; |
436 | mod hash_hs; |
437 | #[cfg (any(feature = "std" , feature = "hashbrown" ))] |
438 | mod limited_cache; |
439 | mod rand; |
440 | mod record_layer; |
441 | #[cfg (feature = "std" )] |
442 | mod stream; |
443 | #[cfg (feature = "tls12" )] |
444 | mod tls12; |
445 | mod tls13; |
446 | mod vecbuf; |
447 | mod verify; |
448 | #[cfg (test)] |
449 | mod verifybench; |
450 | mod x509; |
451 | #[macro_use ] |
452 | mod check; |
453 | #[cfg (feature = "logging" )] |
454 | mod bs_debug; |
455 | mod builder; |
456 | mod enums; |
457 | mod key_log; |
458 | #[cfg (feature = "std" )] |
459 | mod key_log_file; |
460 | mod suites; |
461 | mod versions; |
462 | mod webpki; |
463 | |
464 | /// Internal classes that are used in integration tests. |
465 | /// The contents of this section DO NOT form part of the stable interface. |
466 | #[allow (missing_docs)] |
467 | #[doc (hidden)] |
468 | pub mod internal { |
469 | /// Low-level TLS message parsing and encoding functions. |
470 | pub mod msgs { |
471 | pub mod base { |
472 | pub use crate::msgs::base::{Payload, PayloadU16}; |
473 | } |
474 | pub mod codec { |
475 | pub use crate::msgs::codec::{Codec, Reader}; |
476 | } |
477 | pub mod enums { |
478 | pub use crate::msgs::enums::{ |
479 | AlertLevel, CertificateType, Compression, EchVersion, ExtensionType, HpkeAead, |
480 | HpkeKdf, HpkeKem, NamedGroup, |
481 | }; |
482 | } |
483 | pub mod fragmenter { |
484 | pub use crate::msgs::fragmenter::MessageFragmenter; |
485 | } |
486 | pub mod handshake { |
487 | pub use crate::msgs::handshake::{ |
488 | CertificateChain, ClientExtension, ClientHelloPayload, DistinguishedName, |
489 | EchConfigContents, EchConfigPayload, HandshakeMessagePayload, HandshakePayload, |
490 | HpkeKeyConfig, HpkeSymmetricCipherSuite, KeyShareEntry, Random, ServerExtension, |
491 | ServerName, SessionId, |
492 | }; |
493 | } |
494 | pub mod message { |
495 | pub use crate::msgs::message::{ |
496 | Message, MessagePayload, OutboundOpaqueMessage, PlainMessage, |
497 | }; |
498 | } |
499 | pub mod persist { |
500 | pub use crate::msgs::persist::ServerSessionValue; |
501 | } |
502 | } |
503 | |
504 | pub use crate::tls13::key_schedule::{derive_traffic_iv, derive_traffic_key}; |
505 | |
506 | pub mod fuzzing { |
507 | pub use crate::msgs::deframer::fuzz_deframer; |
508 | } |
509 | } |
510 | |
511 | /// Unbuffered connection API |
512 | /// |
513 | /// This is an alternative to the [`crate::ConnectionCommon`] API that does not internally buffer |
514 | /// TLS nor plaintext data. Instead those buffers are managed by the API user so they have |
515 | /// control over when and how to allocate, resize and dispose of them. |
516 | /// |
517 | /// This API is lower level than the `ConnectionCommon` API and is built around a state machine |
518 | /// interface where the API user must handle each state to advance and complete the |
519 | /// handshake process. |
520 | /// |
521 | /// Like the `ConnectionCommon` API, no IO happens internally so all IO must be handled by the API |
522 | /// user. Unlike the `ConnectionCommon` API, this API does not make use of the [`std::io::Read`] and |
523 | /// [`std::io::Write`] traits so it's usable in no-std context. |
524 | /// |
525 | /// The entry points into this API are [`crate::client::UnbufferedClientConnection::new`], |
526 | /// [`crate::server::UnbufferedServerConnection::new`] and |
527 | /// [`unbuffered::UnbufferedConnectionCommon::process_tls_records`]. The state machine API is |
528 | /// documented in [`unbuffered::ConnectionState`]. |
529 | /// |
530 | /// # Examples |
531 | /// |
532 | /// [`unbuffered-client`] and [`unbuffered-server`] are examples that fully exercise the API in |
533 | /// std, non-async context. |
534 | /// |
535 | /// [`unbuffered-client`]: https://github.com/rustls/rustls/blob/main/examples/src/bin/unbuffered-client.rs |
536 | /// [`unbuffered-server`]: https://github.com/rustls/rustls/blob/main/examples/src/bin/unbuffered-server.rs |
537 | pub mod unbuffered { |
538 | pub use crate::conn::UnbufferedConnectionCommon; |
539 | pub use crate::conn::unbuffered::{ |
540 | AppDataRecord, ConnectionState, EncodeError, EncodeTlsData, EncryptError, |
541 | InsufficientSizeError, ReadEarlyData, ReadTraffic, TransmitTlsData, UnbufferedStatus, |
542 | WriteTraffic, |
543 | }; |
544 | } |
545 | |
546 | // The public interface is: |
547 | pub use crate::builder::{ConfigBuilder, ConfigSide, WantsVerifier, WantsVersions}; |
548 | pub use crate::common_state::{CommonState, HandshakeKind, IoState, Side}; |
549 | #[cfg (feature = "std" )] |
550 | pub use crate::conn::{Connection, Reader, Writer}; |
551 | pub use crate::conn::{ConnectionCommon, SideData}; |
552 | pub use crate::enums::{ |
553 | AlertDescription, CertificateCompressionAlgorithm, CipherSuite, ContentType, HandshakeType, |
554 | ProtocolVersion, SignatureAlgorithm, SignatureScheme, |
555 | }; |
556 | pub use crate::error::{ |
557 | CertRevocationListError, CertificateError, EncryptedClientHelloError, Error, InconsistentKeys, |
558 | InvalidMessage, OtherError, PeerIncompatible, PeerMisbehaved, |
559 | }; |
560 | pub use crate::key_log::{KeyLog, NoKeyLog}; |
561 | #[cfg (feature = "std" )] |
562 | pub use crate::key_log_file::KeyLogFile; |
563 | pub use crate::msgs::enums::NamedGroup; |
564 | pub use crate::msgs::ffdhe_groups; |
565 | pub use crate::msgs::handshake::DistinguishedName; |
566 | #[cfg (feature = "std" )] |
567 | pub use crate::stream::{Stream, StreamOwned}; |
568 | pub use crate::suites::{ |
569 | CipherSuiteCommon, ConnectionTrafficSecrets, ExtractedSecrets, SupportedCipherSuite, |
570 | }; |
571 | #[cfg (feature = "std" )] |
572 | pub use crate::ticketer::TicketRotator; |
573 | #[cfg (any(feature = "std" , feature = "hashbrown" ))] // < XXX: incorrect feature gate |
574 | pub use crate::ticketer::TicketSwitcher; |
575 | #[cfg (feature = "tls12" )] |
576 | pub use crate::tls12::Tls12CipherSuite; |
577 | pub use crate::tls13::Tls13CipherSuite; |
578 | pub use crate::verify::DigitallySignedStruct; |
579 | pub use crate::versions::{ALL_VERSIONS, DEFAULT_VERSIONS, SupportedProtocolVersion}; |
580 | pub use crate::webpki::RootCertStore; |
581 | |
582 | /// Items for use in a client. |
583 | pub mod client { |
584 | pub(super) mod builder; |
585 | mod client_conn; |
586 | mod common; |
587 | mod ech; |
588 | pub(super) mod handy; |
589 | mod hs; |
590 | #[cfg (feature = "tls12" )] |
591 | mod tls12; |
592 | mod tls13; |
593 | |
594 | pub use builder::WantsClientCert; |
595 | pub use client_conn::{ |
596 | ClientConfig, ClientConnectionData, ClientSessionStore, EarlyDataError, ResolvesClientCert, |
597 | Resumption, Tls12Resumption, UnbufferedClientConnection, |
598 | }; |
599 | #[cfg (feature = "std" )] |
600 | pub use client_conn::{ClientConnection, WriteEarlyData}; |
601 | pub use ech::{EchConfig, EchGreaseConfig, EchMode, EchStatus}; |
602 | pub use handy::AlwaysResolvesClientRawPublicKeys; |
603 | #[cfg (any(feature = "std" , feature = "hashbrown" ))] |
604 | pub use handy::ClientSessionMemoryCache; |
605 | |
606 | /// Dangerous configuration that should be audited and used with extreme care. |
607 | pub mod danger { |
608 | pub use super::builder::danger::DangerousClientConfigBuilder; |
609 | pub use super::client_conn::danger::DangerousClientConfig; |
610 | pub use crate::verify::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier}; |
611 | } |
612 | |
613 | pub use crate::msgs::persist::{Tls12ClientSessionValue, Tls13ClientSessionValue}; |
614 | pub use crate::webpki::{ |
615 | ServerCertVerifierBuilder, VerifierBuilderError, WebPkiServerVerifier, |
616 | verify_server_cert_signed_by_trust_anchor, verify_server_name, |
617 | }; |
618 | } |
619 | |
620 | pub use client::ClientConfig; |
621 | #[cfg (feature = "std" )] |
622 | pub use client::ClientConnection; |
623 | |
624 | /// Items for use in a server. |
625 | pub mod server { |
626 | pub(crate) mod builder; |
627 | mod common; |
628 | pub(crate) mod handy; |
629 | mod hs; |
630 | mod server_conn; |
631 | #[cfg (feature = "tls12" )] |
632 | mod tls12; |
633 | mod tls13; |
634 | |
635 | pub use builder::WantsServerCert; |
636 | #[cfg (any(feature = "std" , feature = "hashbrown" ))] |
637 | pub use handy::ResolvesServerCertUsingSni; |
638 | #[cfg (any(feature = "std" , feature = "hashbrown" ))] |
639 | pub use handy::ServerSessionMemoryCache; |
640 | pub use handy::{AlwaysResolvesServerRawPublicKeys, NoServerSessionStorage}; |
641 | pub use server_conn::{ |
642 | Accepted, ClientHello, ProducesTickets, ResolvesServerCert, ServerConfig, |
643 | ServerConnectionData, StoresServerSessions, UnbufferedServerConnection, |
644 | }; |
645 | #[cfg (feature = "std" )] |
646 | pub use server_conn::{AcceptedAlert, Acceptor, ReadEarlyData, ServerConnection}; |
647 | |
648 | pub use crate::verify::NoClientAuth; |
649 | pub use crate::webpki::{ |
650 | ClientCertVerifierBuilder, ParsedCertificate, VerifierBuilderError, WebPkiClientVerifier, |
651 | }; |
652 | |
653 | /// Dangerous configuration that should be audited and used with extreme care. |
654 | pub mod danger { |
655 | pub use crate::verify::{ClientCertVerified, ClientCertVerifier}; |
656 | } |
657 | } |
658 | |
659 | pub use server::ServerConfig; |
660 | #[cfg (feature = "std" )] |
661 | pub use server::ServerConnection; |
662 | |
663 | /// All defined protocol versions appear in this module. |
664 | /// |
665 | /// ALL_VERSIONS is a provided as an array of all of these values. |
666 | pub mod version { |
667 | #[cfg (feature = "tls12" )] |
668 | pub use crate::versions::TLS12; |
669 | pub use crate::versions::TLS13; |
670 | } |
671 | |
672 | /// Re-exports the contents of the [rustls-pki-types](https://docs.rs/rustls-pki-types) crate for easy access |
673 | pub mod pki_types { |
674 | #[doc (no_inline)] |
675 | pub use pki_types::*; |
676 | } |
677 | |
678 | /// Message signing interfaces. |
679 | pub mod sign { |
680 | pub use crate::crypto::signer::{CertifiedKey, Signer, SigningKey, SingleCertAndKey}; |
681 | } |
682 | |
683 | /// APIs for implementing QUIC TLS |
684 | pub mod quic; |
685 | |
686 | #[cfg (any(feature = "std" , feature = "hashbrown" ))] // < XXX: incorrect feature gate |
687 | /// APIs for implementing TLS tickets |
688 | pub mod ticketer; |
689 | |
690 | /// This is the rustls manual. |
691 | pub mod manual; |
692 | |
693 | pub mod time_provider; |
694 | |
695 | /// APIs abstracting over locking primitives. |
696 | pub mod lock; |
697 | |
698 | /// Polyfills for features that are not yet stabilized or available with current MSRV. |
699 | pub(crate) mod polyfill; |
700 | |
701 | #[cfg (any(feature = "std" , feature = "hashbrown" ))] |
702 | mod hash_map { |
703 | #[cfg (feature = "std" )] |
704 | pub(crate) use std::collections::HashMap; |
705 | #[cfg (feature = "std" )] |
706 | pub(crate) use std::collections::hash_map::Entry; |
707 | |
708 | #[cfg (all(not(feature = "std" ), feature = "hashbrown" ))] |
709 | pub(crate) use hashbrown::HashMap; |
710 | #[cfg (all(not(feature = "std" ), feature = "hashbrown" ))] |
711 | pub(crate) use hashbrown::hash_map::Entry; |
712 | } |
713 | |