rough integration of async-tls CertChecks (strict and automatic but not more finegrained work)

This commit is contained in:
holger krekel
2019-11-11 23:22:02 +01:00
parent b13ca0d077
commit a867452927
4 changed files with 49 additions and 26 deletions

1
Cargo.lock generated
View File

@@ -658,6 +658,7 @@ dependencies = [
"strum_macros 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"thread-local-object 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
"webpki-roots 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

View File

@@ -53,6 +53,7 @@ sanitize-filename = "0.2.1"
stop-token = { version = "0.1.1", features = ["unstable"] }
rustls = "0.16.0"
webpki-roots = "0.18.0"
webpki = "0.21.0"
[dev-dependencies]
tempfile = "3.0"

View File

@@ -8,7 +8,7 @@ use async_std::net::{self, TcpStream};
use async_std::prelude::*;
use async_tls::client::TlsStream;
use crate::login_param::CertificateChecks;
use crate::login_param::{dc_build_tls, CertificateChecks};
const DCC_IMAP_DEBUG: &str = "DCC_IMAP_DEBUG";
@@ -34,11 +34,10 @@ impl Client {
pub async fn connect_secure<A: net::ToSocketAddrs, S: AsRef<str>>(
addr: A,
domain: S,
_certificate_checks: CertificateChecks,
certificate_checks: CertificateChecks,
) -> ImapResult<Self> {
let stream = TcpStream::connect(addr).await?;
let tls = async_tls::TlsConnector::new();
let tls = dc_build_tls(certificate_checks);
let tls_stream = tls.connect(domain.as_ref(), stream)?.await?;
let mut client = ImapClient::new(tls_stream);

View File

@@ -3,6 +3,10 @@ use std::fmt;
use crate::context::Context;
use crate::error::Error;
use async_std::sync::Arc;
use async_tls;
use rustls;
use webpki;
#[derive(Copy, Clone, Debug, Display, FromPrimitive)]
#[repr(i32)]
@@ -251,28 +255,46 @@ fn get_readable_flags(flags: i32) -> String {
res
}
// pub fn dc_build_tls(
// certificate_checks: CertificateChecks,
// ) -> Result<native_tls::TlsConnector, native_tls::Error> {
// let mut tls_builder = native_tls::TlsConnector::builder();
// match certificate_checks {
// CertificateChecks::Automatic => {
// // Same as AcceptInvalidCertificates for now.
// // TODO: use provider database when it becomes available
// tls_builder
// .danger_accept_invalid_hostnames(true)
// .danger_accept_invalid_certs(true)
// }
// CertificateChecks::Strict => &mut tls_builder,
// CertificateChecks::AcceptInvalidHostnames => {
// tls_builder.danger_accept_invalid_hostnames(true)
// }
// CertificateChecks::AcceptInvalidCertificates => tls_builder
// .danger_accept_invalid_hostnames(true)
// .danger_accept_invalid_certs(true),
// }
// .build()
// }
pub struct NoCertificateVerification {}
impl rustls::ServerCertVerifier for NoCertificateVerification {
fn verify_server_cert(
&self,
_roots: &rustls::RootCertStore,
_presented_certs: &[rustls::Certificate],
_dns_name: webpki::DNSNameRef<'_>,
_ocsp: &[u8],
) -> Result<rustls::ServerCertVerified, rustls::TLSError> {
Ok(rustls::ServerCertVerified::assertion())
}
}
pub fn dc_build_tls(certificate_checks: CertificateChecks) -> async_tls::TlsConnector {
let mut config = rustls::ClientConfig::new();
match certificate_checks {
CertificateChecks::Strict => {}
CertificateChecks::Automatic => {
// Same as AcceptInvalidCertificates for now.
// TODO: use provider database when it becomes available
config
.dangerous()
.set_certificate_verifier(Arc::new(NoCertificateVerification {}));
}
CertificateChecks::AcceptInvalidCertificates => {
// TODO: only accept invalid certs
config
.dangerous()
.set_certificate_verifier(Arc::new(NoCertificateVerification {}));
}
CertificateChecks::AcceptInvalidHostnames => {
// TODO: only accept invalid hostnames
config
.dangerous()
.set_certificate_verifier(Arc::new(NoCertificateVerification {}));
}
}
Arc::new(config).into()
}
#[cfg(test)]
mod tests {