Skip to content

Commit ede2a09

Browse files
committed
Port tokio-rustls to rustls 0.24
1 parent da533d2 commit ede2a09

14 files changed

Lines changed: 355 additions & 515 deletions

File tree

Cargo.lock

Lines changed: 218 additions & 438 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,32 @@ readme = "README.md"
99
description = "Asynchronous TLS/SSL streams for Tokio using Rustls."
1010
categories = ["asynchronous", "cryptography", "network-programming"]
1111
edition = "2021"
12-
rust-version = "1.71"
12+
rust-version = "1.85"
1313
exclude = ["/.github", "/examples", "/scripts", "/tests/"]
1414

1515
[dependencies]
16-
rustls = { version = "0.23.27", default-features = false, features = ["std"] }
16+
rustls = { git = "https://github.com/rustls/rustls.git", branch = "main", package = "rustls", version = "0.24.0-dev.0", default-features = false, features = ["webpki"] }
17+
rustls-aws-lc-rs = { git = "https://github.com/rustls/rustls.git", branch = "main", package = "rustls-aws-lc-rs", version = "0.1.0-dev.0", default-features = false, features = ["aws-lc-sys", "std"], optional = true }
18+
rustls-ring = { git = "https://github.com/rustls/rustls.git", branch = "main", package = "rustls-ring", version = "0.1.0-dev.0", default-features = false, features = ["std"], optional = true }
1719
tokio = "1.0"
1820

1921
[features]
2022
default = ["logging", "tls12", "aws_lc_rs"]
21-
aws_lc_rs = ["rustls/aws_lc_rs"]
23+
aws_lc_rs = ["dep:rustls-aws-lc-rs"]
2224
aws-lc-rs = ["aws_lc_rs"] # Alias because Cargo features commonly use `-`
2325
brotli = ["rustls/brotli"]
2426
early-data = []
25-
fips = ["rustls/fips"]
26-
logging = ["rustls/logging"]
27-
ring = ["rustls/ring"]
28-
tls12 = ["rustls/tls12"]
27+
fips = ["aws_lc_rs", "rustls-aws-lc-rs/fips"]
28+
logging = ["rustls/log"]
29+
ring = ["dep:rustls-ring"]
30+
tls12 = []
2931
zlib = ["rustls/zlib"]
3032

3133
[dev-dependencies]
3234
argh = "0.1.1"
3335
futures-util = "0.3.1"
3436
lazy_static = "1.1"
3537
rcgen = { version = "0.14", features = ["pem"] }
38+
rustls-util = { git = "https://github.com/rustls/rustls.git", branch = "main", package = "rustls-util", version = "0.1.0", default-features = false }
3639
tokio = { version = "1.0", features = ["full"] }
3740
webpki-roots = "1"

examples/client.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ async fn main() -> Result<(), Box<dyn StdError + Send + Sync + 'static>> {
5151
root_cert_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
5252
}
5353

54-
let config = rustls::ClientConfig::builder()
54+
let config = rustls::ClientConfig::builder(provider())
5555
.with_root_certificates(root_cert_store)
56-
.with_no_client_auth(); // i guess this was previously the default?
56+
.with_no_client_auth()?; // i guess this was previously the default?
5757
let connector = TlsConnector::from(Arc::new(config));
5858

5959
let stream = TcpStream::connect(&addr).await?;
@@ -78,3 +78,15 @@ async fn main() -> Result<(), Box<dyn StdError + Send + Sync + 'static>> {
7878

7979
Ok(())
8080
}
81+
82+
fn provider() -> Arc<rustls::crypto::CryptoProvider> {
83+
#[cfg(feature = "aws_lc_rs")]
84+
{
85+
return Arc::new(rustls_aws_lc_rs::DEFAULT_PROVIDER.clone());
86+
}
87+
88+
#[cfg(all(not(feature = "aws_lc_rs"), feature = "ring"))]
89+
{
90+
return Arc::new(rustls_ring::DEFAULT_PROVIDER.clone());
91+
}
92+
}

examples/server.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::error::Error as StdError;
66
use std::sync::Arc;
77

88
use argh::FromArgs;
9+
use rustls::crypto::Identity;
910
use rustls::pki_types::pem::PemObject;
1011
use rustls::pki_types::{CertificateDer, PrivateKeyDer};
1112
use tokio::io::{copy, sink, split, AsyncWriteExt};
@@ -45,9 +46,10 @@ async fn main() -> Result<(), Box<dyn StdError + Send + Sync + 'static>> {
4546
let key = PrivateKeyDer::from_pem_file(&options.key)?;
4647
let flag_echo = options.echo_mode;
4748

48-
let config = rustls::ServerConfig::builder()
49+
let identity = Arc::new(Identity::from_cert_chain(certs)?);
50+
let config = rustls::ServerConfig::builder(provider())
4951
.with_no_client_auth()
50-
.with_single_cert(certs, key)?;
52+
.with_single_cert(identity, key)?;
5153
let acceptor = TlsAcceptor::from(Arc::new(config));
5254

5355
let listener = TcpListener::bind(&addr).await?;
@@ -90,3 +92,15 @@ async fn main() -> Result<(), Box<dyn StdError + Send + Sync + 'static>> {
9092
});
9193
}
9294
}
95+
96+
fn provider() -> Arc<rustls::crypto::CryptoProvider> {
97+
#[cfg(feature = "aws_lc_rs")]
98+
{
99+
return Arc::new(rustls_aws_lc_rs::DEFAULT_PROVIDER.clone());
100+
}
101+
102+
#[cfg(all(not(feature = "aws_lc_rs"), feature = "ring"))]
103+
{
104+
return Arc::new(rustls_ring::DEFAULT_PROVIDER.clone());
105+
}
106+
}

src/client.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ use std::{
1212
sync::Arc,
1313
};
1414

15-
use rustls::{pki_types::ServerName, ClientConfig, ClientConnection};
15+
use rustls::{
16+
enums::ApplicationProtocol, pki_types::ServerName, ClientConfig, ClientConnection,
17+
Connection as _,
18+
};
1619
use tokio::io::{AsyncBufRead, AsyncRead, AsyncWrite, ReadBuf};
1720

1821
use crate::common::{IoSession, MidHandshake, Stream, TlsState};
@@ -64,15 +67,25 @@ impl TlsConnector {
6467
IO: AsyncRead + AsyncWrite + Unpin,
6568
F: FnOnce(&mut ClientConnection),
6669
{
67-
let alpn = alpn_protocols.unwrap_or_else(|| self.inner.alpn_protocols.clone());
68-
let mut session = match ClientConnection::new_with_alpn(self.inner.clone(), domain, alpn) {
70+
let builder = self.inner.connect(domain);
71+
let builder = if let Some(alpn_protocols) = alpn_protocols {
72+
builder.with_alpn(
73+
alpn_protocols
74+
.into_iter()
75+
.map(ApplicationProtocol::from)
76+
.collect(),
77+
)
78+
} else {
79+
builder
80+
};
81+
let mut session = match builder.build() {
6982
Ok(session) => session,
7083
Err(error) => {
7184
return Connect(MidHandshake::Error {
7285
io: stream,
7386
// TODO(eliza): should this really return an `io::Error`?
7487
// Probably not...
75-
error: io::Error::new(io::ErrorKind::Other, error),
88+
error: io::Error::other(error),
7689
});
7790
}
7891
};

src/common/handshake.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use std::future::Future;
2-
use std::ops::{Deref, DerefMut};
32
use std::pin::Pin;
43
use std::task::{Context, Poll};
54
use std::{io, mem};
65

76
use rustls::server::AcceptedAlert;
8-
use rustls::{ConnectionCommon, SideData};
7+
use rustls::Connection as RustlsConnection;
98
use tokio::io::{AsyncRead, AsyncWrite};
109

1110
use crate::common::{Stream, SyncWriteAdapter, TlsState};
@@ -33,12 +32,11 @@ pub(crate) enum MidHandshake<IS: IoSession> {
3332
},
3433
}
3534

36-
impl<IS, SD> Future for MidHandshake<IS>
35+
impl<IS> Future for MidHandshake<IS>
3736
where
3837
IS: IoSession + Unpin,
3938
IS::Io: AsyncRead + AsyncWrite + Unpin,
40-
IS::Session: DerefMut + Deref<Target = ConnectionCommon<SD>> + Unpin,
41-
SD: SideData,
39+
IS::Session: RustlsConnection + Unpin,
4240
{
4341
type Output = Result<IS, (io::Error, IS::Io)>;
4442

src/common/mod.rs

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use std::io::{self, BufRead as _, IoSlice, Read, Write};
2-
use std::ops::{Deref, DerefMut};
32
use std::pin::Pin;
43
use std::task::{Context, Poll};
54

6-
use rustls::{ConnectionCommon, SideData};
5+
use rustls::Connection as RustlsConnection;
76
use tokio::io::{AsyncBufRead, AsyncRead, AsyncWrite, ReadBuf};
87

98
mod handshake;
@@ -66,10 +65,9 @@ pub(crate) struct Stream<'a, IO, C> {
6665
pub(crate) need_flush: bool,
6766
}
6867

69-
impl<'a, IO: AsyncRead + AsyncWrite + Unpin, C, SD> Stream<'a, IO, C>
68+
impl<'a, IO: AsyncRead + AsyncWrite + Unpin, C> Stream<'a, IO, C>
7069
where
71-
C: DerefMut + Deref<Target = ConnectionCommon<SD>>,
72-
SD: SideData,
70+
C: RustlsConnection,
7371
{
7472
pub(crate) fn new(io: &'a mut IO, session: &'a mut C) -> Self {
7573
Stream {
@@ -188,10 +186,7 @@ where
188186
}
189187
}
190188

191-
pub(crate) fn poll_fill_buf(mut self, cx: &mut Context<'_>) -> Poll<io::Result<&'a [u8]>>
192-
where
193-
SD: 'a,
194-
{
189+
pub(crate) fn poll_fill_buf(mut self, cx: &mut Context<'_>) -> Poll<io::Result<&'a [u8]>> {
195190
let mut io_pending = false;
196191

197192
// read a packet
@@ -231,10 +226,9 @@ where
231226
}
232227
}
233228

234-
impl<'a, IO: AsyncRead + AsyncWrite + Unpin, C, SD> AsyncRead for Stream<'a, IO, C>
229+
impl<'a, IO: AsyncRead + AsyncWrite + Unpin, C> AsyncRead for Stream<'a, IO, C>
235230
where
236-
C: DerefMut + Deref<Target = ConnectionCommon<SD>>,
237-
SD: SideData + 'a,
231+
C: RustlsConnection + 'a,
238232
{
239233
fn poll_read(
240234
mut self: Pin<&mut Self>,
@@ -249,10 +243,9 @@ where
249243
}
250244
}
251245

252-
impl<'a, IO: AsyncRead + AsyncWrite + Unpin, C, SD> AsyncBufRead for Stream<'a, IO, C>
246+
impl<'a, IO: AsyncRead + AsyncWrite + Unpin, C> AsyncBufRead for Stream<'a, IO, C>
253247
where
254-
C: DerefMut + Deref<Target = ConnectionCommon<SD>>,
255-
SD: SideData + 'a,
248+
C: RustlsConnection + 'a,
256249
{
257250
fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
258251
let this = self.get_mut();
@@ -270,10 +263,9 @@ where
270263
}
271264
}
272265

273-
impl<IO: AsyncRead + AsyncWrite + Unpin, C, SD> AsyncWrite for Stream<'_, IO, C>
266+
impl<IO: AsyncRead + AsyncWrite + Unpin, C> AsyncWrite for Stream<'_, IO, C>
274267
where
275-
C: DerefMut + Deref<Target = ConnectionCommon<SD>>,
276-
SD: SideData,
268+
C: RustlsConnection,
277269
{
278270
fn poll_write(
279271
mut self: Pin<&mut Self>,

src/common/test_stream.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ use std::task::{Context, Poll};
88
use futures_util::future::poll_fn;
99
use futures_util::task::noop_waker_ref;
1010
use rustls::pki_types::ServerName;
11-
use rustls::{ClientConnection, Connection, ServerConnection};
11+
use rustls::{ClientConnection, Connection as _, ServerConnection};
1212
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, ReadBuf};
1313

1414
use super::Stream;
1515

16-
struct Good<'a>(&'a mut Connection);
16+
struct Good<'a>(&'a mut ServerConnection);
1717

1818
impl AsyncRead for Good<'_> {
1919
fn poll_read(
@@ -172,8 +172,7 @@ async fn stream_good_bufread() -> io::Result<()> {
172172
async fn stream_good_impl(vectored: bool, bufread: bool) -> io::Result<()> {
173173
const FILE: &[u8] = include_bytes!("../../README.md");
174174

175-
let (server, mut client) = make_pair();
176-
let mut server = Connection::from(server);
175+
let (mut server, mut client) = make_pair();
177176
poll_fn(|cx| do_handshake(&mut client, &mut server, cx)).await?;
178177

179178
io::copy(&mut Cursor::new(FILE), &mut server.writer())?;
@@ -207,8 +206,7 @@ async fn stream_good_impl(vectored: bool, bufread: bool) -> io::Result<()> {
207206

208207
#[tokio::test]
209208
async fn stream_bad() -> io::Result<()> {
210-
let (server, mut client) = make_pair();
211-
let mut server = Connection::from(server);
209+
let (mut server, mut client) = make_pair();
212210
poll_fn(|cx| do_handshake(&mut client, &mut server, cx)).await?;
213211
client.set_buffer_limit(Some(1024));
214212

@@ -234,8 +232,7 @@ async fn stream_bad() -> io::Result<()> {
234232

235233
#[tokio::test]
236234
async fn stream_handshake() -> io::Result<()> {
237-
let (server, mut client) = make_pair();
238-
let mut server = Connection::from(server);
235+
let (mut server, mut client) = make_pair();
239236

240237
{
241238
let mut good = Good(&mut server);
@@ -258,8 +255,7 @@ async fn stream_handshake() -> io::Result<()> {
258255
async fn stream_buffered_handshake() -> io::Result<()> {
259256
use tokio::io::BufWriter;
260257

261-
let (server, mut client) = make_pair();
262-
let mut server = Connection::from(server);
258+
let (mut server, mut client) = make_pair();
263259

264260
{
265261
let mut good = BufWriter::new(Good(&mut server));
@@ -332,8 +328,7 @@ async fn stream_handshake_regression_issues_77() -> io::Result<()> {
332328

333329
#[tokio::test]
334330
async fn stream_eof() -> io::Result<()> {
335-
let (server, mut client) = make_pair();
336-
let mut server = Connection::from(server);
331+
let (mut server, mut client) = make_pair();
337332
poll_fn(|cx| do_handshake(&mut client, &mut server, cx)).await?;
338333

339334
let mut bad = Expected(Cursor::new(Vec::new()));
@@ -351,8 +346,7 @@ async fn stream_eof() -> io::Result<()> {
351346

352347
#[tokio::test]
353348
async fn stream_write_zero() -> io::Result<()> {
354-
let (server, mut client) = make_pair();
355-
let mut server = Connection::from(server);
349+
let (mut server, mut client) = make_pair();
356350
poll_fn(|cx| do_handshake(&mut client, &mut server, cx)).await?;
357351

358352
let mut io = Eof;
@@ -372,15 +366,15 @@ fn make_pair() -> (ServerConnection, ClientConnection) {
372366
let (sconfig, cconfig) = utils::make_configs();
373367
let server = ServerConnection::new(Arc::new(sconfig)).unwrap();
374368

375-
let domain = ServerName::try_from("foobar.com").unwrap();
376-
let client = ClientConnection::new(Arc::new(cconfig), domain).unwrap();
369+
let domain = ServerName::try_from("foobar.com").unwrap().to_owned();
370+
let client = Arc::new(cconfig).connect(domain).build().unwrap();
377371

378372
(server, client)
379373
}
380374

381375
fn do_handshake(
382376
client: &mut ClientConnection,
383-
server: &mut Connection,
377+
server: &mut ServerConnection,
384378
cx: &mut Context<'_>,
385379
) -> Poll<io::Result<()>> {
386380
let mut good = Good(server);

src/lib.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ use std::task::{Context, Poll};
4848

4949
pub use rustls;
5050

51-
use rustls::CommonState;
51+
use rustls::ConnectionOutputs;
5252
use tokio::io::{AsyncBufRead, AsyncRead, AsyncWrite, ReadBuf};
5353

5454
macro_rules! ready {
@@ -78,7 +78,7 @@ pub enum TlsStream<T> {
7878
}
7979

8080
impl<T> TlsStream<T> {
81-
pub fn get_ref(&self) -> (&T, &CommonState) {
81+
pub fn get_ref(&self) -> (&T, &ConnectionOutputs) {
8282
use TlsStream::*;
8383
match self {
8484
Client(io) => {
@@ -92,21 +92,28 @@ impl<T> TlsStream<T> {
9292
}
9393
}
9494

95-
pub fn get_mut(&mut self) -> (&mut T, &mut CommonState) {
95+
pub fn get_mut(&mut self) -> (&mut T, TlsConnectionMut<'_>) {
9696
use TlsStream::*;
9797
match self {
9898
Client(io) => {
9999
let (io, session) = io.get_mut();
100-
(io, &mut *session)
100+
(io, TlsConnectionMut::Client(session))
101101
}
102102
Server(io) => {
103103
let (io, session) = io.get_mut();
104-
(io, &mut *session)
104+
(io, TlsConnectionMut::Server(session))
105105
}
106106
}
107107
}
108108
}
109109

110+
/// Mutable access to either side's rustls connection.
111+
#[derive(Debug)]
112+
pub enum TlsConnectionMut<'a> {
113+
Client(&'a mut rustls::ClientConnection),
114+
Server(&'a mut rustls::ServerConnection),
115+
}
116+
110117
impl<T> From<client::TlsStream<T>> for TlsStream<T> {
111118
fn from(s: client::TlsStream<T>) -> Self {
112119
Self::Client(s)

0 commit comments

Comments
 (0)