pipebuf_rustls/lib.rs
1//! [`PipeBuf`] wrapper around [**Rustls**]
2//!
3//! This offers a single "process" call that takes care of all the
4//! calls required to move data between the encrypted and plain-text
5//! sides of a [**Rustls**] client or server connection structure.
6//! This would typically be used along with other
7//! [`PipeBuf`]-supporting crates such as `pipebuf_mio` or similar to
8//! offer transport, and a [`PipeBuf`]-based implementation of the
9//! wrapped protocol to form a complete solution.
10//!
11//! Internally this uses either the buffered or unbuffered interface
12//! provided by [**Rustls**], depending on which cargo feature is
13//! selected. The default is to use the buffered interface because
14//! that is mature. Whilst the unbuffered interface mostly works as
15//! of 0.23.4, there are some rough corners (some failing tests in
16//! this crate) and it doesn't yet offer any performance advantage due
17//! to the planned [**Rustls**] unbuffered optimisations not yet being
18//! implemented.
19//!
20//! # Versioning
21//!
22//! This crate follows the major/minor version number of the
23//! [**Rustls**] crate it wraps. Rustls is re-exported as
24//! `pipebuf_rustls::rustls`.
25//!
26//! # Selecting [**Rustls**] crate features
27//!
28//! This crate brings in [**Rustls**] with only `std` enabled by
29//! default (for buffered operation). This means that you need to
30//! include the same version of [**Rustls**] in your own dependencies
31//! in order to select the features required, especially the crypto
32//! provider. This approach is necessary in order to allow you to use
33//! `default-features = false` to disable `tls12` if necessary. So
34//! your dependency section may look like this to use the default
35//! crypto provider:
36//!
37//! ```ignore
38//! [dependencies]
39//! pipebuf_rustls = "0.23"
40//! rustls = "0.23"
41//! ```
42//!
43//! Or maybe like this to use `ring`:
44//!
45//! ```ignore
46//! [dependencies]
47//! pipebuf_rustls = "0.23"
48//! rustls = { version = "0.23", features = ["ring"] }
49//! ```
50//!
51//! Or maybe like this to disable `tls12`:
52//!
53//! ```ignore
54//! [dependencies]
55//! pipebuf_rustls = "0.23"
56//! rustls = { version = "0.23", default-features = false,
57//! features = ["aws_lc_rs", "logging"] }
58//! ```
59//!
60//! Check out the [**Rustls**
61//! `Cargo.toml`](https://github.com/rustls/rustls/blob/main/rustls/Cargo.toml)
62//! to see how to control this.
63//!
64//! To use the Rustls unbuffered implementation (not recommended yet),
65//! you'll need something like this:
66//!
67//! ```ignore
68//! [dependencies]
69//! pipebuf_rustls = { version = "0.23", default-features = false, features = ["unbuffered"] }
70//! rustls = "0.23"
71//! ```
72//!
73//! [`PipeBuf`]: https://crates.io/crates/pipebuf
74//! [**Rustls**]: https://crates.io/crates/rustls
75
76#![forbid(unsafe_code)]
77
78pub use rustls;
79
80#[cfg(all(not(feature = "unbuffered"), not(feature = "buffered")))]
81compile_error!("Select a crate feature: either `buffered` or `unbuffered`");
82
83// If they select both `unbuffered` and `buffered`, default to
84// `buffered` for 0.23, since that is more mature
85#[cfg(feature = "buffered")]
86mod client;
87#[cfg(feature = "buffered")]
88mod server;
89#[cfg(feature = "buffered")]
90pub use client::TlsClient;
91#[cfg(feature = "buffered")]
92pub use server::TlsServer;
93
94#[cfg(not(feature = "buffered"))]
95mod unbuf;
96#[cfg(not(feature = "buffered"))]
97pub use unbuf::{TlsClient, TlsServer};
98
99/// Error in TLS processing
100#[derive(Debug)]
101pub struct TlsError(String);
102
103impl std::error::Error for TlsError {}
104
105impl std::fmt::Display for TlsError {
106 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107 write!(f, "{}", self.0)
108 }
109}