| 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 | |