rustls/
lib.rs

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
384extern 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))]
391extern crate std;
392
393#[cfg(doc)]
394use crate::crypto::CryptoProvider;
395
396// Import `test` sysroot crate for `Bencher` definitions.
397#[cfg(bench)]
398#[allow(unused_extern_crates)]
399extern crate test;
400
401// log for logging (optional).
402#[cfg(feature = "logging")]
403use log;
404
405#[cfg(not(feature = "logging"))]
406mod 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]
416mod test_macros;
417
418/// This internal `sync` module aliases the `Arc` implementation to allow downstream forks
419/// of rustls targetting architectures without atomic pointers to replace the implementation
420/// with another implementation such as `portable_atomic_util::Arc` in one central location.
421mod 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]
429mod msgs;
430mod common_state;
431pub mod compress;
432mod conn;
433/// Crypto provider interface.
434pub mod crypto;
435mod error;
436mod hash_hs;
437#[cfg(any(feature = "std", feature = "hashbrown"))]
438mod limited_cache;
439mod rand;
440mod record_layer;
441#[cfg(feature = "std")]
442mod stream;
443#[cfg(feature = "tls12")]
444mod tls12;
445mod tls13;
446mod vecbuf;
447mod verify;
448#[cfg(test)]
449mod verifybench;
450mod x509;
451#[macro_use]
452mod check;
453#[cfg(feature = "logging")]
454mod bs_debug;
455mod builder;
456mod enums;
457mod key_log;
458#[cfg(feature = "std")]
459mod key_log_file;
460mod suites;
461mod versions;
462mod 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)]
468pub 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, HpkeAead, HpkeKdf, HpkeKem,
480                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
537pub 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:
547pub use crate::builder::{ConfigBuilder, ConfigSide, WantsVerifier, WantsVersions};
548pub use crate::common_state::{CommonState, HandshakeKind, IoState, Side};
549#[cfg(feature = "std")]
550pub use crate::conn::{Connection, Reader, Writer};
551pub use crate::conn::{ConnectionCommon, SideData};
552pub use crate::enums::{
553    AlertDescription, CertificateCompressionAlgorithm, CipherSuite, ContentType, HandshakeType,
554    ProtocolVersion, SignatureAlgorithm, SignatureScheme,
555};
556pub use crate::error::{
557    CertRevocationListError, CertificateError, EncryptedClientHelloError, Error, InconsistentKeys,
558    InvalidMessage, OtherError, PeerIncompatible, PeerMisbehaved,
559};
560pub use crate::key_log::{KeyLog, NoKeyLog};
561#[cfg(feature = "std")]
562pub use crate::key_log_file::KeyLogFile;
563pub use crate::msgs::enums::NamedGroup;
564pub use crate::msgs::ffdhe_groups;
565pub use crate::msgs::handshake::DistinguishedName;
566#[cfg(feature = "std")]
567pub use crate::stream::{Stream, StreamOwned};
568pub use crate::suites::{
569    CipherSuiteCommon, ConnectionTrafficSecrets, ExtractedSecrets, SupportedCipherSuite,
570};
571#[cfg(feature = "std")]
572pub use crate::ticketer::TicketRotator;
573#[cfg(any(feature = "std", feature = "hashbrown"))] // < XXX: incorrect feature gate
574pub use crate::ticketer::TicketSwitcher;
575#[cfg(feature = "tls12")]
576pub use crate::tls12::Tls12CipherSuite;
577pub use crate::tls13::Tls13CipherSuite;
578pub use crate::verify::DigitallySignedStruct;
579pub use crate::versions::{ALL_VERSIONS, DEFAULT_VERSIONS, SupportedProtocolVersion};
580pub use crate::webpki::RootCertStore;
581
582/// Items for use in a client.
583pub 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
620pub use client::ClientConfig;
621#[cfg(feature = "std")]
622pub use client::ClientConnection;
623
624/// Items for use in a server.
625pub 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
659pub use server::ServerConfig;
660#[cfg(feature = "std")]
661pub 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.
666pub 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
673pub mod pki_types {
674    #[doc(no_inline)]
675    pub use pki_types::*;
676}
677
678/// Message signing interfaces.
679pub mod sign {
680    pub use crate::crypto::signer::{CertifiedKey, Signer, SigningKey, SingleCertAndKey};
681}
682
683/// APIs for implementing QUIC TLS
684pub mod quic;
685
686#[cfg(any(feature = "std", feature = "hashbrown"))] // < XXX: incorrect feature gate
687/// APIs for implementing TLS tickets
688pub mod ticketer;
689
690/// This is the rustls manual.
691pub mod manual;
692
693pub mod time_provider;
694
695/// APIs abstracting over locking primitives.
696pub mod lock;
697
698/// Polyfills for features that are not yet stabilized or available with current MSRV.
699pub(crate) mod polyfill;
700
701#[cfg(any(feature = "std", feature = "hashbrown"))]
702mod 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}