diff --git a/Cargo.lock b/Cargo.lock index 4f21d8fd91..f2255ee1e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -318,18 +318,6 @@ dependencies = [ "event-listener 2.5.3", ] -[[package]] -name = "async-native-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9343dc5acf07e79ff82d0c37899f079db3534d99f189a1837c8e549c99405bec" -dependencies = [ - "native-tls", - "thiserror", - "tokio", - "url", -] - [[package]] name = "async-recursion" version = "1.1.1" @@ -1315,7 +1303,6 @@ dependencies = [ "async-broadcast", "async-channel 2.3.1", "async-imap", - "async-native-tls", "async-smtp", "async_zip", "base64 0.22.1", @@ -2183,21 +2170,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.1" @@ -3569,24 +3541,6 @@ dependencies = [ "getrandom 0.2.12", ] -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "netdev" version = "0.30.0" @@ -3931,32 +3885,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" -[[package]] -name = "openssl" -version = "0.10.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" -dependencies = [ - "bitflags 2.6.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.86", -] - [[package]] name = "openssl-probe" version = "0.1.5" diff --git a/Cargo.toml b/Cargo.toml index b22863e063..0e49218d32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,6 @@ anyhow = { workspace = true } async-broadcast = "0.7.1" async-channel = { workspace = true } async-imap = { version = "0.10.2", default-features = false, features = ["runtime-tokio", "compress"] } -async-native-tls = { version = "0.5", default-features = false, features = ["runtime-tokio"] } async-smtp = { version = "0.9", default-features = false, features = ["runtime-tokio"] } async_zip = { version = "0.0.17", default-features = false, features = ["deflate", "tokio-fs"] } base64 = { workspace = true } diff --git a/src/net.rs b/src/net.rs index 1ad85a3ea5..ad540deebe 100644 --- a/src/net.rs +++ b/src/net.rs @@ -5,7 +5,7 @@ use std::pin::Pin; use std::time::Duration; use anyhow::{format_err, Context as _, Result}; -use async_native_tls::TlsStream; +use tokio_rustls::client::TlsStream; use tokio::net::TcpStream; use tokio::task::JoinSet; use tokio::time::timeout; diff --git a/src/net/http.rs b/src/net/http.rs index 94e85f68c1..6b7721d596 100644 --- a/src/net/http.rs +++ b/src/net/http.rs @@ -10,7 +10,7 @@ use serde::Serialize; use crate::context::Context; use crate::net::proxy::ProxyConfig; use crate::net::session::SessionStream; -use crate::net::tls::wrap_rustls; +use crate::net::tls::wrap_tls; /// HTTP(S) GET response. #[derive(Debug)] @@ -72,11 +72,11 @@ where let proxy_stream = proxy_config .connect(context, host, port, load_cache) .await?; - let tls_stream = wrap_rustls(host, &[], proxy_stream).await?; + let tls_stream = wrap_tls(true, host, &[], proxy_stream).await?; Box::new(tls_stream) } else { let tcp_stream = crate::net::connect_tcp(context, host, port, load_cache).await?; - let tls_stream = wrap_rustls(host, &[], tcp_stream).await?; + let tls_stream = wrap_tls(true, host, &[], tcp_stream).await?; Box::new(tls_stream) } } diff --git a/src/net/proxy.rs b/src/net/proxy.rs index f0a9c32c42..05f3d4b5c8 100644 --- a/src/net/proxy.rs +++ b/src/net/proxy.rs @@ -23,7 +23,7 @@ use crate::constants::NON_ALPHANUMERIC_WITHOUT_DOT; use crate::context::Context; use crate::net::connect_tcp; use crate::net::session::SessionStream; -use crate::net::tls::wrap_rustls; +use crate::net::tls::wrap_tls; use crate::sql::Sql; /// Default SOCKS5 port according to [RFC 1928](https://tools.ietf.org/html/rfc1928). @@ -425,7 +425,7 @@ impl ProxyConfig { load_cache, ) .await?; - let tls_stream = wrap_rustls(&https_config.host, &[], tcp_stream).await?; + let tls_stream = wrap_tls(true, &https_config.host, &[], tcp_stream).await?; let auth = if let Some((username, password)) = &https_config.user_password { Some((username.as_str(), password.as_str())) } else { diff --git a/src/net/session.rs b/src/net/session.rs index 8c56f2bbcf..083e137407 100644 --- a/src/net/session.rs +++ b/src/net/session.rs @@ -16,11 +16,6 @@ impl SessionStream for Box { self.as_mut().set_read_timeout(timeout); } } -impl SessionStream for async_native_tls::TlsStream { - fn set_read_timeout(&mut self, timeout: Option) { - self.get_mut().set_read_timeout(timeout); - } -} impl SessionStream for tokio_rustls::client::TlsStream { fn set_read_timeout(&mut self, timeout: Option) { self.get_mut().0.set_read_timeout(timeout); diff --git a/src/net/tls.rs b/src/net/tls.rs index f30ed5cfd8..c95da5c039 100644 --- a/src/net/tls.rs +++ b/src/net/tls.rs @@ -2,41 +2,17 @@ use std::sync::Arc; use anyhow::Result; -use async_native_tls::{Certificate, Protocol, TlsConnector, TlsStream}; use once_cell::sync::Lazy; use tokio::io::{AsyncRead, AsyncWrite}; +use rustls::client::ClientSessionStore; -// this certificate is missing on older android devices (eg. lg with android6 from 2017) -// certificate downloaded from https://letsencrypt.org/certificates/ -static LETSENCRYPT_ROOT: Lazy = Lazy::new(|| { - Certificate::from_der(include_bytes!( - "../../assets/root-certificates/letsencrypt/isrgrootx1.der" - )) - .unwrap() +// This is the default as of version 0.23.16, but make it shared between clients. +static RESUMPTION_STORE: Lazy> = Lazy::new(|| { + Arc::new(rustls::client::ClientSessionMemoryCache::new(256)) }); pub async fn wrap_tls( - strict_tls: bool, - hostname: &str, - alpn: &[&str], - stream: T, -) -> Result> { - let tls_builder = TlsConnector::new() - .min_protocol_version(Some(Protocol::Tlsv12)) - .request_alpns(alpn) - .add_root_certificate(LETSENCRYPT_ROOT.clone()); - let tls = if strict_tls { - tls_builder - } else { - tls_builder - .danger_accept_invalid_hostnames(true) - .danger_accept_invalid_certs(true) - }; - let tls_stream = tls.connect(hostname, stream).await?; - Ok(tls_stream) -} - -pub async fn wrap_rustls( + _strict_tls: bool, hostname: &str, alpn: &[&str], stream: T, @@ -49,6 +25,9 @@ pub async fn wrap_rustls( .with_no_client_auth(); config.alpn_protocols = alpn.iter().map(|s| s.as_bytes().to_vec()).collect(); + let resumption = rustls::client::Resumption::store(Arc::clone(&RESUMPTION_STORE)); + config.resumption = resumption; + let tls = tokio_rustls::TlsConnector::from(Arc::new(config)); let name = rustls_pki_types::ServerName::try_from(hostname)?.to_owned(); let tls_stream = tls.connect(name, stream).await?;