Skip to content

Commit 3b2f18f

Browse files
authored
feat: use Rustls for connections with strict TLS (#6186)
1 parent c9cf2b7 commit 3b2f18f

File tree

3 files changed

+24
-30
lines changed

3 files changed

+24
-30
lines changed
Binary file not shown.

src/net.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ use std::pin::Pin;
55
use std::time::Duration;
66

77
use anyhow::{format_err, Context as _, Result};
8-
use async_native_tls::TlsStream;
98
use tokio::net::TcpStream;
109
use tokio::task::JoinSet;
1110
use tokio::time::timeout;
1211
use tokio_io_timeout::TimeoutStream;
1312

1413
use crate::context::Context;
14+
use crate::net::session::SessionStream;
1515
use crate::sql::Sql;
1616
use crate::tools::time;
1717

@@ -128,7 +128,7 @@ pub(crate) async fn connect_tls_inner(
128128
host: &str,
129129
strict_tls: bool,
130130
alpn: &[&str],
131-
) -> Result<TlsStream<Pin<Box<TimeoutStream<TcpStream>>>>> {
131+
) -> Result<impl SessionStream> {
132132
let tcp_stream = connect_tcp_inner(addr).await?;
133133
let tls_stream = wrap_tls(strict_tls, host, alpn, tcp_stream).await?;
134134
Ok(tls_stream)

src/net/tls.rs

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,39 @@
22
use std::sync::Arc;
33

44
use anyhow::Result;
5-
use async_native_tls::{Certificate, Protocol, TlsConnector, TlsStream};
6-
use once_cell::sync::Lazy;
7-
use tokio::io::{AsyncRead, AsyncWrite};
85

9-
// this certificate is missing on older android devices (eg. lg with android6 from 2017)
10-
// certificate downloaded from https://letsencrypt.org/certificates/
11-
static LETSENCRYPT_ROOT: Lazy<Certificate> = Lazy::new(|| {
12-
Certificate::from_der(include_bytes!(
13-
"../../assets/root-certificates/letsencrypt/isrgrootx1.der"
14-
))
15-
.unwrap()
16-
});
6+
use crate::net::session::SessionStream;
177

18-
pub async fn wrap_tls<T: AsyncRead + AsyncWrite + Unpin>(
8+
pub async fn wrap_tls(
199
strict_tls: bool,
2010
hostname: &str,
2111
alpn: &[&str],
22-
stream: T,
23-
) -> Result<TlsStream<T>> {
24-
let tls_builder = TlsConnector::new()
25-
.min_protocol_version(Some(Protocol::Tlsv12))
26-
.request_alpns(alpn)
27-
.add_root_certificate(LETSENCRYPT_ROOT.clone());
28-
let tls = if strict_tls {
29-
tls_builder
12+
stream: impl SessionStream + 'static,
13+
) -> Result<impl SessionStream> {
14+
if strict_tls {
15+
let tls_stream = wrap_rustls(hostname, alpn, stream).await?;
16+
let boxed_stream: Box<dyn SessionStream> = Box::new(tls_stream);
17+
Ok(boxed_stream)
3018
} else {
31-
tls_builder
19+
// We use native_tls because it accepts 1024-bit RSA keys.
20+
// Rustls does not support them even if
21+
// certificate checks are disabled: <https://github.com/rustls/rustls/issues/234>.
22+
let tls = async_native_tls::TlsConnector::new()
23+
.min_protocol_version(Some(async_native_tls::Protocol::Tlsv12))
24+
.request_alpns(alpn)
3225
.danger_accept_invalid_hostnames(true)
33-
.danger_accept_invalid_certs(true)
34-
};
35-
let tls_stream = tls.connect(hostname, stream).await?;
36-
Ok(tls_stream)
26+
.danger_accept_invalid_certs(true);
27+
let tls_stream = tls.connect(hostname, stream).await?;
28+
let boxed_stream: Box<dyn SessionStream> = Box::new(tls_stream);
29+
Ok(boxed_stream)
30+
}
3731
}
3832

39-
pub async fn wrap_rustls<T: AsyncRead + AsyncWrite + Unpin>(
33+
pub async fn wrap_rustls(
4034
hostname: &str,
4135
alpn: &[&str],
42-
stream: T,
43-
) -> Result<tokio_rustls::client::TlsStream<T>> {
36+
stream: impl SessionStream,
37+
) -> Result<impl SessionStream> {
4438
let mut root_cert_store = rustls::RootCertStore::empty();
4539
root_cert_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
4640

0 commit comments

Comments
 (0)