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//! ## Current functionality (with default crate features)
8//!
9//! * TLS1.2 and TLS1.3.
10//! * ECDSA, Ed25519 or RSA server authentication by clients.
11//! * ECDSA, Ed25519 or RSA server authentication by servers.
12//! * Forward secrecy using ECDHE; with curve25519, nistp256 or nistp384 curves.
13//! * AES128-GCM and AES256-GCM bulk encryption, with safe nonces.
14//! * ChaCha20-Poly1305 bulk encryption ([RFC7905](https://tools.ietf.org/html/rfc7905)).
15//! * ALPN support.
16//! * SNI support.
17//! * Tunable fragment size to make TLS messages match size of underlying transport.
18//! * Optional use of vectored IO to minimise system calls.
19//! * TLS1.2 session resumption.
20//! * TLS1.2 resumption via tickets ([RFC5077](https://tools.ietf.org/html/rfc5077)).
21//! * TLS1.3 resumption via tickets or session storage.
22//! * TLS1.3 0-RTT data for clients.
23//! * TLS1.3 0-RTT data for servers.
24//! * Client authentication by clients.
25//! * Client authentication by servers.
26//! * Extended master secret support ([RFC7627](https://tools.ietf.org/html/rfc7627)).
27//! * Exporters ([RFC5705](https://tools.ietf.org/html/rfc5705)).
28//! * OCSP stapling by servers.
29//!
30//! ## Non-features
31//!
32//! For reasons [explained in the manual](manual),
33//! rustls does not and will not support:
34//!
35//! * SSL1, SSL2, SSL3, TLS1 or TLS1.1.
36//! * RC4.
37//! * DES or triple DES.
38//! * EXPORT ciphersuites.
39//! * MAC-then-encrypt ciphersuites.
40//! * Ciphersuites without forward secrecy.
41//! * Renegotiation.
42//! * Kerberos.
43//! * TLS 1.2 protocol compression.
44//! * Discrete-log Diffie-Hellman.
45//! * Automatic protocol version downgrade.
46//! * Using CA certificates directly to authenticate a server/client (often called "self-signed
47//! certificates"). _Rustls' default certificate verifier does not support using a trust anchor as
48//! both a CA certificate and an end-entity certificate in order to limit complexity and risk in
49//! path building. While dangerous, all authentication can be turned off if required --
50//! see the [example code](https://github.com/rustls/rustls/blob/992e2364a006b2e84a8cf6a7c3eaf0bdb773c9de/examples/src/bin/tlsclient-mio.rs#L318)_.
51//!
52//! There are plenty of other libraries that provide these features should you
53//! need them.
54//!
55//! ### Platform support
56//!
57//! While Rustls itself is platform independent, by default it uses
58//! [`ring`](https://crates.io/crates/ring) for implementing the cryptography in
59//! TLS. As a result, rustls only runs on platforms
60//! supported by `ring`. At the time of writing, this means 32-bit ARM, Aarch64 (64-bit ARM),
61//! x86, x86-64, LoongArch64, 32-bit & 64-bit Little Endian MIPS, 32-bit PowerPC (Big Endian),
62//! 64-bit PowerPC (Big and Little Endian), 64-bit RISC-V, and s390x. We do not presently
63//! support WebAssembly.
64//! For more information, see [the supported `ring` target platforms][ring-target-platforms].
65//!
66//! By providing a custom instance of the [`crate::crypto::CryptoProvider`] struct, you
67//! can replace all cryptography dependencies of rustls. This is a route to being portable
68//! to a wider set of architectures and environments, or compliance requirements. See the
69//! [`crate::crypto::CryptoProvider`] documentation for more details.
70//!
71//! Specifying `default-features = false` when depending on rustls will remove the
72//! dependency on *ring*.
73//!
74//! Rustls requires Rust 1.61 or later.
75//!
76//! [ring-target-platforms]: https://github.com/briansmith/ring/blob/2e8363b433fa3b3962c877d9ed2e9145612f3160/include/ring-core/target.h#L18-L64
77//!
78//! ## Design Overview
79//! ### Rustls does not take care of network IO
80//! It doesn't make or accept TCP connections, or do DNS, or read or write files.
81//!
82//! There's example client and server code which uses mio to do all needed network
83//! IO.
84//!
85//! ### Rustls provides encrypted pipes
86//! These are the [`ServerConnection`] and [`ClientConnection`] types. You supply raw TLS traffic
87//! on the left (via the [`read_tls()`] and [`write_tls()`] methods) and then read/write the
88//! plaintext on the right:
89//!
90//! [`read_tls()`]: Connection::read_tls
91//! [`write_tls()`]: Connection::read_tls
92//!
93//! ```text
94//! TLS Plaintext
95//! === =========
96//! read_tls() +-----------------------+ reader() as io::Read
97//! | |
98//! +---------> ClientConnection +--------->
99//! | or |
100//! <---------+ ServerConnection <---------+
101//! | |
102//! write_tls() +-----------------------+ writer() as io::Write
103//! ```
104//!
105//! ### Rustls takes care of server certificate verification
106//! You do not need to provide anything other than a set of root certificates to trust.
107//! Certificate verification cannot be turned off or disabled in the main API.
108//!
109//! ## Getting started
110//! This is the minimum you need to do to make a TLS client connection.
111//!
112//! First we load some root certificates. These are used to authenticate the server.
113//! The simplest way is to depend on the [`webpki_roots`] crate which contains
114//! the Mozilla set of root certificates.
115//!
116//! ```rust,no_run
117//! # #[cfg(feature = "ring")] {
118//! let mut root_store = rustls::RootCertStore::empty();
119//! root_store.extend(
120//! webpki_roots::TLS_SERVER_ROOTS
121//! .iter()
122//! .cloned()
123//! );
124//! # }
125//! ```
126//!
127//! [`webpki_roots`]: https://crates.io/crates/webpki-roots
128//!
129//! Next, we make a `ClientConfig`. You're likely to make one of these per process,
130//! and use it for all connections made by that process.
131//!
132//! ```rust,no_run
133//! # #[cfg(feature = "ring")] {
134//! # let root_store: rustls::RootCertStore = panic!();
135//! let config = rustls::ClientConfig::builder()
136//! .with_root_certificates(root_store)
137//! .with_no_client_auth();
138//! # }
139//! ```
140//!
141//! Now we can make a connection. You need to provide the server's hostname so we
142//! know what to expect to find in the server's certificate.
143//!
144//! ```rust
145//! # #[cfg(feature = "ring")] {
146//! # use rustls;
147//! # use webpki;
148//! # use std::sync::Arc;
149//! # let mut root_store = rustls::RootCertStore::empty();
150//! # root_store.extend(
151//! # webpki_roots::TLS_SERVER_ROOTS
152//! # .iter()
153//! # .cloned()
154//! # );
155//! # let config = rustls::ClientConfig::builder()
156//! # .with_root_certificates(root_store)
157//! # .with_no_client_auth()
158//! # .with_fingerprint(rustls::craft::CHROME_108.builder());
159//! let rc_config = Arc::new(config);
160//! let example_com = "example.com".try_into().unwrap();
161//! let mut client = rustls::ClientConnection::new(rc_config, example_com);
162//! # }
163//! ```
164//!
165//! Now you should do appropriate IO for the `client` object. If `client.wants_read()` yields
166//! true, you should call `client.read_tls()` when the underlying connection has data.
167//! Likewise, if `client.wants_write()` yields true, you should call `client.write_tls()`
168//! when the underlying connection is able to send data. You should continue doing this
169//! as long as the connection is valid.
170//!
171//! The return types of `read_tls()` and `write_tls()` only tell you if the IO worked. No
172//! parsing or processing of the TLS messages is done. After each `read_tls()` you should
173//! therefore call `client.process_new_packets()` which parses and processes the messages.
174//! Any error returned from `process_new_packets` is fatal to the connection, and will tell you
175//! why. For example, if the server's certificate is expired `process_new_packets` will
176//! return `Err(InvalidCertificate(Expired))`. From this point on,
177//! `process_new_packets` will not do any new work and will return that error continually.
178//!
179//! You can extract newly received data by calling `client.reader()` (which implements the
180//! `io::Read` trait). You can send data to the peer by calling `client.writer()` (which
181//! implements `io::Write` trait). Note that `client.writer().write()` buffers data you
182//! send if the TLS connection is not yet established: this is useful for writing (say) a
183//! HTTP request, but this is buffered so avoid large amounts of data.
184//!
185//! The following code uses a fictional socket IO API for illustration, and does not handle
186//! errors.
187//!
188//! ```rust,no_run
189//! # #[cfg(feature = "ring")] {
190//! # let mut client = rustls::ClientConnection::new(panic!(), panic!()).unwrap();
191//! # struct Socket { }
192//! # impl Socket {
193//! # fn ready_for_write(&self) -> bool { false }
194//! # fn ready_for_read(&self) -> bool { false }
195//! # fn wait_for_something_to_happen(&self) { }
196//! # }
197//! #
198//! # use std::io::{Read, Write, Result};
199//! # impl Read for Socket {
200//! # fn read(&mut self, buf: &mut [u8]) -> Result<usize> { panic!() }
201//! # }
202//! # impl Write for Socket {
203//! # fn write(&mut self, buf: &[u8]) -> Result<usize> { panic!() }
204//! # fn flush(&mut self) -> Result<()> { panic!() }
205//! # }
206//! #
207//! # fn connect(_address: &str, _port: u16) -> Socket {
208//! # panic!();
209//! # }
210//! use std::io;
211//! use rustls::Connection;
212//!
213//! client.writer().write(b"GET / HTTP/1.0\r\n\r\n").unwrap();
214//! let mut socket = connect("example.com", 443);
215//! loop {
216//! if client.wants_read() && socket.ready_for_read() {
217//! client.read_tls(&mut socket).unwrap();
218//! client.process_new_packets().unwrap();
219//!
220//! let mut plaintext = Vec::new();
221//! client.reader().read_to_end(&mut plaintext).unwrap();
222//! io::stdout().write(&plaintext).unwrap();
223//! }
224//!
225//! if client.wants_write() && socket.ready_for_write() {
226//! client.write_tls(&mut socket).unwrap();
227//! }
228//!
229//! socket.wait_for_something_to_happen();
230//! }
231//! # }
232//! ```
233//!
234//! # Examples
235//!
236//! [`tlsserver-mio`](https://github.com/rustls/rustls/blob/main/examples/src/bin/tlsserver-mio.rs)
237//! and [`tlsclient-mio`](https://github.com/rustls/rustls/blob/main/examples/src/bin/tlsclient-mio.rs)
238//! are full worked examples using [`mio`].
239//!
240//! [`mio`]: https://docs.rs/mio/latest/mio/
241//!
242//! # Crate features
243//! Here's a list of what features are exposed by the rustls crate and what
244//! they mean.
245//!
246//! - `ring` (enabled by default): makes the rustls crate depend on the *ring* crate, which is
247//! used for cryptography by default. Without this feature, these items must be provided
248//! externally to the core rustls crate: see [`crate::crypto::CryptoProvider`].
249//!
250//! - `aws_lc_rs`: makes the rustls crate depend on the aws-lc-rs crate,
251//! which can be used for cryptography as an alternative to *ring*.
252//! Use `rustls::crypto::aws_lc_rs::default_provider()` as a `CryptoProvider`
253//! when making a `ClientConfig` or `ServerConfig` to use aws-lc-rs
254//!
255//! Note that aws-lc-rs has additional build-time dependencies like cmake.
256//! See [the documentation](https://aws.github.io/aws-lc-rs/requirements/index.html) for details.
257//!
258//! - `tls12` (enabled by default): enable support for TLS version 1.2. Note that, due to the
259//! additive nature of Cargo features and because it is enabled by default, other crates
260//! in your dependency graph could re-enable it for your application. If you want to disable
261//! TLS 1.2 for security reasons, consider explicitly enabling TLS 1.3 only in the config
262//! builder API.
263//!
264//! - `logging` (enabled by default): make the rustls crate depend on the `log` crate.
265//! rustls outputs interesting protocol-level messages at `trace!` and `debug!` level,
266//! and protocol-level errors at `warn!` and `error!` level. The log messages do not
267//! contain secret key data, and so are safe to archive without affecting session security.
268//!
269//! - `read_buf`: when building with Rust Nightly, adds support for the unstable
270//! `std::io::ReadBuf` and related APIs. This reduces costs from initializing
271//! buffers. Will do nothing on non-Nightly releases.
272//!
273
274// Require docs for public APIs, deny unsafe code, etc.
275#![forbid(unsafe_code, unused_must_use)]
276#![cfg_attr(not(any(read_buf, bench)), forbid(unstable_features))]
277#![deny(
278 clippy::alloc_instead_of_core,
279 clippy::clone_on_ref_ptr,
280 clippy::std_instead_of_core,
281 clippy::use_self,
282 clippy::upper_case_acronyms,
283 trivial_casts,
284 trivial_numeric_casts,
285 missing_docs,
286 unreachable_pub,
287 unused_import_braces,
288 unused_extern_crates,
289 unused_qualifications
290)]
291// Relax these clippy lints:
292// - ptr_arg: this triggers on references to type aliases that are Vec
293// underneath.
294// - too_many_arguments: some things just need a lot of state, wrapping it
295// doesn't necessarily make it easier to follow what's going on
296// - new_ret_no_self: we sometimes return `Arc<Self>`, which seems fine
297// - single_component_path_imports: our top-level `use log` import causes
298// a false positive, https://github.com/rust-lang/rust-clippy/issues/5210
299// - new_without_default: for internal constructors, the indirection is not
300// helpful
301#![allow(
302 clippy::too_many_arguments,
303 clippy::new_ret_no_self,
304 clippy::ptr_arg,
305 clippy::single_component_path_imports,
306 clippy::new_without_default
307)]
308// Enable documentation for all features on docs.rs
309#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
310// XXX: Because of https://github.com/rust-lang/rust/issues/54726, we cannot
311// write `#![rustversion::attr(nightly, feature(read_buf))]` here. Instead,
312// build.rs set `read_buf` for (only) Rust Nightly to get the same effect.
313//
314// All the other conditional logic in the crate could use
315// `#[rustversion::nightly]` instead of `#[cfg(read_buf)]`; `#[cfg(read_buf)]`
316// is used to avoid needing `rustversion` to be compiled twice during
317// cross-compiling.
318#![cfg_attr(read_buf, feature(read_buf))]
319#![cfg_attr(read_buf, feature(core_io_borrowed_buf))]
320#![cfg_attr(bench, feature(test))]
321#![cfg_attr(not(test), no_std)]
322
323extern crate alloc;
324// This `extern crate` plus the `#![no_std]` attribute changes the default prelude from
325// `std::prelude` to `core::prelude`. That forces one to _explicitly_ import (`use`) everything that
326// is in `std::prelude` but not in `core::prelude`. This helps maintain no-std support as even
327// developers that are not interested in, or aware of, no-std support and / or that never run
328// `cargo build --no-default-features` locally will get errors when they rely on `std::prelude` API.
329#[cfg(not(test))]
330extern crate std;
331
332// Import `test` sysroot crate for `Bencher` definitions.
333#[cfg(bench)]
334#[allow(unused_extern_crates)]
335extern crate test;
336
337// log for logging (optional).
338#[cfg(feature = "logging")]
339use log;
340
341#[cfg(not(feature = "logging"))]
342#[macro_use]
343mod log {
344 macro_rules! trace ( ($($tt:tt)*) => {{}} );
345 macro_rules! debug ( ($($tt:tt)*) => {{}} );
346 macro_rules! warn ( ($($tt:tt)*) => {{}} );
347}
348
349#[macro_use]
350mod msgs;
351mod common_state;
352mod conn;
353/// Crypto provider interface.
354pub mod crypto;
355mod error;
356mod hash_hs;
357mod limited_cache;
358mod rand;
359mod record_layer;
360mod stream;
361#[cfg(feature = "tls12")]
362mod tls12;
363mod tls13;
364mod vecbuf;
365mod verify;
366#[cfg(test)]
367mod verifybench;
368mod x509;
369#[macro_use]
370mod check;
371mod bs_debug;
372mod builder;
373mod compression;
374mod enums;
375mod key_log;
376mod key_log_file;
377mod suites;
378mod versions;
379mod webpki;
380
381/// Internal classes that are used in integration tests.
382/// The contents of this section DO NOT form part of the stable interface.
383#[allow(missing_docs)]
384pub mod internal {
385 /// Low-level TLS message parsing and encoding functions.
386 pub mod msgs {
387 pub mod base {
388 pub use crate::msgs::base::Payload;
389 }
390 pub mod codec {
391 pub use crate::msgs::codec::{Codec, Reader};
392 }
393 pub mod deframer {
394 pub use crate::msgs::deframer::MessageDeframer;
395 }
396 pub mod enums {
397 pub use crate::msgs::enums::{
398 AlertLevel, Compression, EchVersion, HpkeAead, HpkeKdf, HpkeKem, NamedGroup,
399 };
400 // !craft! begin
401 pub use crate::msgs::enums::{ECPointFormat, ExtensionType, PSKKeyExchangeMode};
402 // !craft! end
403 }
404 pub mod fragmenter {
405 pub use crate::msgs::fragmenter::MessageFragmenter;
406 }
407 pub mod handshake {
408 pub use crate::msgs::handshake::{
409 CertificateChain, ClientExtension, ClientHelloPayload, DistinguishedName,
410 EchConfig, EchConfigContents, HandshakeMessagePayload, HandshakePayload,
411 HpkeKeyConfig, HpkeSymmetricCipherSuite, KeyShareEntry, Random, SessionId,
412 };
413 }
414 pub mod message {
415 pub use crate::msgs::message::{Message, MessagePayload, OpaqueMessage, PlainMessage};
416 }
417 pub mod persist {
418 pub use crate::msgs::persist::ServerSessionValue;
419 }
420 }
421
422 pub mod record_layer {
423 pub use crate::record_layer::RecordLayer;
424 }
425}
426
427// Have a (non-public) "test provider" mod which supplies
428// tests that need part of a *ring*-compatible provider module.
429#[cfg(all(any(test, bench), not(feature = "ring"), feature = "aws_lc_rs"))]
430use crate::crypto::aws_lc_rs as test_provider;
431#[cfg(all(any(test, bench), feature = "ring"))]
432use crate::crypto::ring as test_provider;
433
434// The public interface is:
435pub use crate::builder::{ConfigBuilder, ConfigSide, WantsVerifier, WantsVersions};
436pub use crate::common_state::{CommonState, IoState, Side};
437pub use crate::conn::{Connection, ConnectionCommon, Reader, SideData, Writer};
438pub use crate::enums::{
439 AlertDescription, CipherSuite, ContentType, HandshakeType, ProtocolVersion, SignatureAlgorithm,
440 SignatureScheme,
441};
442pub use crate::error::{
443 CertRevocationListError, CertificateError, Error, InvalidMessage, OtherError, PeerIncompatible,
444 PeerMisbehaved,
445};
446pub use crate::key_log::{KeyLog, NoKeyLog};
447pub use crate::key_log_file::KeyLogFile;
448pub use crate::msgs::enums::NamedGroup;
449pub use crate::msgs::handshake::DistinguishedName;
450pub use crate::stream::{Stream, StreamOwned};
451pub use crate::suites::{ConnectionTrafficSecrets, ExtractedSecrets, SupportedCipherSuite};
452#[cfg(feature = "tls12")]
453pub use crate::tls12::Tls12CipherSuite;
454pub use crate::tls13::Tls13CipherSuite;
455pub use crate::verify::DigitallySignedStruct;
456pub use crate::versions::{SupportedProtocolVersion, ALL_VERSIONS, DEFAULT_VERSIONS};
457pub use crate::webpki::RootCertStore;
458
459/// Items for use in a client.
460pub mod client {
461 pub(super) mod builder;
462 mod client_conn;
463 mod common;
464 pub(super) mod handy;
465 mod hs;
466 #[cfg(feature = "tls12")]
467 mod tls12;
468 mod tls13;
469
470 pub use builder::WantsClientCert;
471 pub use client_conn::{
472 ClientConfig, ClientConnection, ClientConnectionData, ClientSessionStore,
473 ResolvesClientCert, Resumption, Tls12Resumption, WriteEarlyData,
474 };
475 pub use handy::ClientSessionMemoryCache;
476
477 /// Dangerous configuration that should be audited and used with extreme care.
478 pub mod danger {
479 pub use super::builder::danger::DangerousClientConfigBuilder;
480 pub use super::client_conn::danger::DangerousClientConfig;
481 pub use crate::verify::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier};
482 }
483
484 pub use crate::webpki::{
485 verify_server_cert_signed_by_trust_anchor, verify_server_name, ServerCertVerifierBuilder,
486 VerifierBuilderError, WebPkiServerVerifier,
487 };
488
489 pub use crate::msgs::persist::Tls12ClientSessionValue;
490 pub use crate::msgs::persist::Tls13ClientSessionValue;
491}
492
493pub use crate::compression::{
494 BrotliParams, CertificateCompression, CompressionProvider, ZlibParams, ZstdParams,
495 BROTLI_DEFAULT, ZLIB_DEFAULT, ZSTD_DEFAULT,
496};
497pub use client::{ClientConfig, ClientConnection};
498pub use msgs::enums::CertificateCompressionAlgorithm;
499
500/// Items for use in a server.
501pub mod server {
502 pub(crate) mod builder;
503 mod common;
504 pub(crate) mod handy;
505 mod hs;
506 mod server_conn;
507 #[cfg(feature = "tls12")]
508 mod tls12;
509 mod tls13;
510
511 pub use crate::verify::NoClientAuth;
512 pub use crate::webpki::{
513 ClientCertVerifierBuilder, ParsedCertificate, VerifierBuilderError, WebPkiClientVerifier,
514 };
515 pub use builder::WantsServerCert;
516 pub use handy::ResolvesServerCertUsingSni;
517 pub use handy::{NoServerSessionStorage, ServerSessionMemoryCache};
518 pub use server_conn::StoresServerSessions;
519 pub use server_conn::{
520 Accepted, Acceptor, ReadEarlyData, ServerConfig, ServerConnection, ServerConnectionData,
521 };
522 pub use server_conn::{ClientHello, ProducesTickets, ResolvesServerCert};
523
524 /// Dangerous configuration that should be audited and used with extreme care.
525 pub mod danger {
526 pub use crate::verify::{ClientCertVerified, ClientCertVerifier};
527 }
528}
529
530pub use server::{ServerConfig, ServerConnection};
531
532/// All defined protocol versions appear in this module.
533///
534/// ALL_VERSIONS is a provided as an array of all of these values.
535pub mod version {
536 #[cfg(feature = "tls12")]
537 pub use crate::versions::TLS12;
538 pub use crate::versions::TLS13;
539}
540
541/// Message signing interfaces.
542pub mod sign {
543 pub use crate::crypto::signer::{CertifiedKey, Signer, SigningKey};
544}
545
546/// APIs for implementing QUIC TLS
547pub mod quic;
548
549/// APIs for implementing TLS tickets
550pub mod ticketer;
551
552/// This is the rustls manual.
553pub mod manual;
554
555/// Core craft functionality
556pub mod craft;