mirror of
https://github.com/chatmail/core.git
synced 2026-05-01 20:36:31 +03:00
feat: use Rustls for connections with strict TLS (#6186)
This commit is contained in:
Binary file not shown.
@@ -5,13 +5,13 @@ use std::pin::Pin;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use anyhow::{format_err, Context as _, Result};
|
use anyhow::{format_err, Context as _, Result};
|
||||||
use async_native_tls::TlsStream;
|
|
||||||
use tokio::net::TcpStream;
|
use tokio::net::TcpStream;
|
||||||
use tokio::task::JoinSet;
|
use tokio::task::JoinSet;
|
||||||
use tokio::time::timeout;
|
use tokio::time::timeout;
|
||||||
use tokio_io_timeout::TimeoutStream;
|
use tokio_io_timeout::TimeoutStream;
|
||||||
|
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
|
use crate::net::session::SessionStream;
|
||||||
use crate::sql::Sql;
|
use crate::sql::Sql;
|
||||||
use crate::tools::time;
|
use crate::tools::time;
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ pub(crate) async fn connect_tls_inner(
|
|||||||
host: &str,
|
host: &str,
|
||||||
strict_tls: bool,
|
strict_tls: bool,
|
||||||
alpn: &[&str],
|
alpn: &[&str],
|
||||||
) -> Result<TlsStream<Pin<Box<TimeoutStream<TcpStream>>>>> {
|
) -> Result<impl SessionStream> {
|
||||||
let tcp_stream = connect_tcp_inner(addr).await?;
|
let tcp_stream = connect_tcp_inner(addr).await?;
|
||||||
let tls_stream = wrap_tls(strict_tls, host, alpn, tcp_stream).await?;
|
let tls_stream = wrap_tls(strict_tls, host, alpn, tcp_stream).await?;
|
||||||
Ok(tls_stream)
|
Ok(tls_stream)
|
||||||
|
|||||||
@@ -2,45 +2,39 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use async_native_tls::{Certificate, Protocol, TlsConnector, TlsStream};
|
|
||||||
use once_cell::sync::Lazy;
|
|
||||||
use tokio::io::{AsyncRead, AsyncWrite};
|
|
||||||
|
|
||||||
// this certificate is missing on older android devices (eg. lg with android6 from 2017)
|
use crate::net::session::SessionStream;
|
||||||
// certificate downloaded from https://letsencrypt.org/certificates/
|
|
||||||
static LETSENCRYPT_ROOT: Lazy<Certificate> = Lazy::new(|| {
|
|
||||||
Certificate::from_der(include_bytes!(
|
|
||||||
"../../assets/root-certificates/letsencrypt/isrgrootx1.der"
|
|
||||||
))
|
|
||||||
.unwrap()
|
|
||||||
});
|
|
||||||
|
|
||||||
pub async fn wrap_tls<T: AsyncRead + AsyncWrite + Unpin>(
|
pub async fn wrap_tls(
|
||||||
strict_tls: bool,
|
strict_tls: bool,
|
||||||
hostname: &str,
|
hostname: &str,
|
||||||
alpn: &[&str],
|
alpn: &[&str],
|
||||||
stream: T,
|
stream: impl SessionStream + 'static,
|
||||||
) -> Result<TlsStream<T>> {
|
) -> Result<impl SessionStream> {
|
||||||
let tls_builder = TlsConnector::new()
|
if strict_tls {
|
||||||
.min_protocol_version(Some(Protocol::Tlsv12))
|
let tls_stream = wrap_rustls(hostname, alpn, stream).await?;
|
||||||
.request_alpns(alpn)
|
let boxed_stream: Box<dyn SessionStream> = Box::new(tls_stream);
|
||||||
.add_root_certificate(LETSENCRYPT_ROOT.clone());
|
Ok(boxed_stream)
|
||||||
let tls = if strict_tls {
|
|
||||||
tls_builder
|
|
||||||
} else {
|
} else {
|
||||||
tls_builder
|
// We use native_tls because it accepts 1024-bit RSA keys.
|
||||||
|
// Rustls does not support them even if
|
||||||
|
// certificate checks are disabled: <https://github.com/rustls/rustls/issues/234>.
|
||||||
|
let tls = async_native_tls::TlsConnector::new()
|
||||||
|
.min_protocol_version(Some(async_native_tls::Protocol::Tlsv12))
|
||||||
|
.request_alpns(alpn)
|
||||||
.danger_accept_invalid_hostnames(true)
|
.danger_accept_invalid_hostnames(true)
|
||||||
.danger_accept_invalid_certs(true)
|
.danger_accept_invalid_certs(true);
|
||||||
};
|
|
||||||
let tls_stream = tls.connect(hostname, stream).await?;
|
let tls_stream = tls.connect(hostname, stream).await?;
|
||||||
Ok(tls_stream)
|
let boxed_stream: Box<dyn SessionStream> = Box::new(tls_stream);
|
||||||
|
Ok(boxed_stream)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn wrap_rustls<T: AsyncRead + AsyncWrite + Unpin>(
|
pub async fn wrap_rustls(
|
||||||
hostname: &str,
|
hostname: &str,
|
||||||
alpn: &[&str],
|
alpn: &[&str],
|
||||||
stream: T,
|
stream: impl SessionStream,
|
||||||
) -> Result<tokio_rustls::client::TlsStream<T>> {
|
) -> Result<impl SessionStream> {
|
||||||
let mut root_cert_store = rustls::RootCertStore::empty();
|
let mut root_cert_store = rustls::RootCertStore::empty();
|
||||||
root_cert_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
|
root_cert_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user