Bump to rustls 0.22

This commit is contained in:
mdecimus
2023-12-08 10:46:20 +01:00
parent e4d5bde1ce
commit db564ae0db
19 changed files with 210 additions and 125 deletions

View File

@@ -5,10 +5,11 @@ edition = "2021"
resolver = "2"
[dependencies]
rustls = { version = "0.21", features = ["tls12", "dangerous_configuration"]}
rustls = { version = "0.22", features = ["tls12"]}
rustls-pemfile = "2.0"
rustls-pki-types = { version = "1" }
tokio = { version = "1.23", features = ["net", "macros"] }
tokio-rustls = { version = "0.24.0"}
tokio-rustls = { version = "0.25.0"}
serde = { version = "1.0", features = ["derive"]}
tracing = "0.1"
mail-auth = { git = "https://github.com/stalwartlabs/mail-auth" }

View File

@@ -27,15 +27,17 @@ use rustls::{
server::{ClientHello, ResolvesServerCert, ResolvesServerCertUsingSni},
sign::CertifiedKey,
version::{TLS12, TLS13},
Certificate, PrivateKey, SupportedProtocolVersion,
SupportedProtocolVersion,
};
use rustls_pemfile::{certs, read_one, Item};
use rustls_pki_types::{CertificateDer, PrivateKeyDer};
use super::Config;
pub static TLS13_VERSION: &[&SupportedProtocolVersion] = &[&TLS13];
pub static TLS12_VERSION: &[&SupportedProtocolVersion] = &[&TLS12];
#[derive(Debug)]
pub struct CertificateResolver {
pub resolver: Option<ResolvesServerCertUsingSni>,
pub default_cert: Option<Arc<CertifiedKey>>,
@@ -51,7 +53,7 @@ impl ResolvesServerCert for CertificateResolver {
}
impl Config {
pub fn rustls_certificate(&self, cert_id: &str) -> super::Result<Vec<Certificate>> {
pub fn rustls_certificate(&self, cert_id: &str) -> super::Result<Vec<CertificateDer<'static>>> {
let certs = certs(&mut Cursor::new(self.file_contents((
"certificate",
cert_id,
@@ -63,10 +65,7 @@ impl Config {
})?;
if !certs.is_empty() {
Ok(certs
.into_iter()
.map(|cert| Certificate(cert.as_ref().to_vec()))
.collect())
Ok(certs)
} else {
Err(format!(
"No certificates found in \"certificate.{cert_id}.cert\"."
@@ -74,7 +73,7 @@ impl Config {
}
}
pub fn rustls_private_key(&self, cert_id: &str) -> super::Result<PrivateKey> {
pub fn rustls_private_key(&self, cert_id: &str) -> super::Result<PrivateKeyDer<'static>> {
match read_one(&mut Cursor::new(self.file_contents((
"certificate",
cert_id,
@@ -86,9 +85,9 @@ impl Config {
.into_iter()
.next()
{
Some(Item::Pkcs8Key(key)) => Ok(PrivateKey(key.secret_pkcs8_der().to_vec())),
Some(Item::Pkcs1Key(key)) => Ok(PrivateKey(key.secret_pkcs1_der().to_vec())),
Some(Item::Sec1Key(key)) => Ok(PrivateKey(key.secret_sec1_der().to_vec())),
Some(Item::Pkcs8Key(key)) => Ok(PrivateKeyDer::Pkcs8(key)),
Some(Item::Pkcs1Key(key)) => Ok(PrivateKeyDer::Pkcs1(key)),
Some(Item::Sec1Key(key)) => Ok(PrivateKeyDer::Sec1(key)),
Some(_) => Err(format!(
"Unsupported private keys found in \"certificate.{cert_id}.private-key\".",
)),

View File

@@ -24,15 +24,19 @@
use std::{net::SocketAddr, sync::Arc};
use rustls::{
cipher_suite::{
TLS13_AES_128_GCM_SHA256, TLS13_AES_256_GCM_SHA384, TLS13_CHACHA20_POLY1305_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
crypto::ring::{
cipher_suite::{
TLS13_AES_128_GCM_SHA256, TLS13_AES_256_GCM_SHA384, TLS13_CHACHA20_POLY1305_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
},
default_provider,
sign::any_supported_type,
},
server::{NoClientAuth, ResolvesServerCertUsingSni},
sign::{any_supported_type, CertifiedKey},
ServerConfig, SupportedCipherSuite, ALL_CIPHER_SUITES, ALL_KX_GROUPS, ALL_VERSIONS,
server::ResolvesServerCertUsingSni,
sign::CertifiedKey,
ServerConfig, SupportedCipherSuite, ALL_VERSIONS,
};
use tokio::net::TcpSocket;
@@ -89,7 +93,7 @@ impl Config {
}
// Parse cipher suites
let mut ciphers = Vec::new();
let mut ciphers: Vec<SupportedCipherSuite> = Vec::new();
for (key, protocol) in
self.values_or_default(("server.listener", id, "tls.ciphers"), "server.tls.ciphers")
{
@@ -127,7 +131,6 @@ impl Config {
)
})?,
ocsp: None,
sct_list: None,
},
_ => CertifiedKey {
cert: cert.clone(),
@@ -138,7 +141,6 @@ impl Config {
)
})?,
ocsp: None,
sct_list: None,
},
},
)
@@ -154,17 +156,16 @@ impl Config {
key: any_supported_type(&pki)
.map_err(|err| format!("Failed to sign certificate id {cert_id:?}: {err}"))?,
ocsp: None,
sct_list: None,
}));
// Build cert provider
let mut provider = default_provider();
if !ciphers.is_empty() {
provider.cipher_suites = ciphers;
}
// Build server config
let mut config = ServerConfig::builder()
.with_cipher_suites(if !ciphers.is_empty() {
&ciphers
} else {
ALL_CIPHER_SUITES
})
.with_kx_groups(&ALL_KX_GROUPS)
let mut config = ServerConfig::builder_with_provider(provider.into())
.with_protocol_versions(if tls_v3 == tls_v2 {
ALL_VERSIONS
} else if tls_v3 {
@@ -173,7 +174,7 @@ impl Config {
TLS12_VERSION
})
.map_err(|err| format!("Failed to build TLS config: {err}"))?
.with_client_cert_verifier(NoClientAuth::boxed())
.with_no_client_auth()
.with_cert_resolver(Arc::new(CertificateResolver {
resolver: if has_sni { resolver.into() } else { None },
default_cert,

View File

@@ -41,9 +41,10 @@ use opentelemetry_sdk::{
};
use opentelemetry_semantic_conventions::resource::{SERVICE_NAME, SERVICE_VERSION};
use rustls::{
client::{ServerCertVerified, ServerCertVerifier},
Certificate, ClientConfig, OwnedTrustAnchor, RootCertStore, ServerName,
client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier},
ClientConfig, RootCertStore, SignatureScheme,
};
use rustls_pki_types::TrustAnchor;
use tracing_appender::non_blocking::WorkerGuard;
use tracing_subscriber::{prelude::__tracing_subscriber_SubscriberExt, EnvFilter};
@@ -232,40 +233,76 @@ pub async fn wait_for_shutdown(message: &str) {
}
pub fn rustls_client_config(allow_invalid_certs: bool) -> ClientConfig {
let config = ClientConfig::builder().with_safe_defaults();
let config = ClientConfig::builder();
if !allow_invalid_certs {
let mut root_cert_store = RootCertStore::empty();
root_cert_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| {
OwnedTrustAnchor::from_subject_spki_name_constraints(
ta.subject.as_ref(),
ta.subject_public_key_info.as_ref(),
ta.name_constraints.as_ref().map(|v| v.as_ref()),
)
root_cert_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| TrustAnchor {
subject: ta.subject.clone(),
subject_public_key_info: ta.subject_public_key_info.clone(),
name_constraints: ta.name_constraints.clone(),
}));
config
.with_root_certificates(root_cert_store)
.with_no_client_auth()
} else {
config
.dangerous()
.with_custom_certificate_verifier(Arc::new(DummyVerifier {}))
.with_no_client_auth()
}
}
#[derive(Debug)]
struct DummyVerifier;
impl ServerCertVerifier for DummyVerifier {
fn verify_server_cert(
&self,
_e: &Certificate,
_i: &[Certificate],
_sn: &ServerName,
_sc: &mut dyn Iterator<Item = &[u8]>,
_o: &[u8],
_n: std::time::SystemTime,
_end_entity: &rustls_pki_types::CertificateDer<'_>,
_intermediates: &[rustls_pki_types::CertificateDer<'_>],
_server_name: &rustls_pki_types::ServerName<'_>,
_ocsp_response: &[u8],
_now: rustls_pki_types::UnixTime,
) -> Result<ServerCertVerified, rustls::Error> {
Ok(ServerCertVerified::assertion())
}
fn verify_tls12_signature(
&self,
_message: &[u8],
_cert: &rustls_pki_types::CertificateDer<'_>,
_dss: &rustls::DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, rustls::Error> {
Ok(HandshakeSignatureValid::assertion())
}
fn verify_tls13_signature(
&self,
_message: &[u8],
_cert: &rustls_pki_types::CertificateDer<'_>,
_dss: &rustls::DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, rustls::Error> {
Ok(HandshakeSignatureValid::assertion())
}
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
vec![
SignatureScheme::RSA_PKCS1_SHA1,
SignatureScheme::ECDSA_SHA1_Legacy,
SignatureScheme::RSA_PKCS1_SHA256,
SignatureScheme::ECDSA_NISTP256_SHA256,
SignatureScheme::RSA_PKCS1_SHA384,
SignatureScheme::ECDSA_NISTP384_SHA384,
SignatureScheme::RSA_PKCS1_SHA512,
SignatureScheme::ECDSA_NISTP521_SHA512,
SignatureScheme::RSA_PSS_SHA256,
SignatureScheme::RSA_PSS_SHA384,
SignatureScheme::RSA_PSS_SHA512,
SignatureScheme::ED25519,
SignatureScheme::ED448,
]
}
}

View File

@@ -23,6 +23,7 @@
use std::{net::IpAddr, sync::Arc};
use rustls::crypto::ring::cipher_suite::TLS13_AES_128_GCM_SHA256;
use tokio::{
net::{TcpListener, TcpStream},
sync::watch,
@@ -247,7 +248,7 @@ impl ServerInstance {
context = "tls",
event = "handshake",
version = ?stream.get_ref().1.protocol_version().unwrap_or(rustls::ProtocolVersion::TLSv1_3),
cipher = ?stream.get_ref().1.negotiated_cipher_suite().unwrap_or(rustls::cipher_suite::TLS13_AES_128_GCM_SHA256),
cipher = ?stream.get_ref().1.negotiated_cipher_suite().unwrap_or(TLS13_AES_128_GCM_SHA256),
);
Ok(stream)
}