From 1126125d7088253e7a8751ca6ca31aa3af71aaa9 Mon Sep 17 00:00:00 2001 From: hozan23 Date: Tue, 12 Mar 2024 21:54:29 +0100 Subject: upgrade from async-rustls to futures-rustls --- net/Cargo.toml | 2 +- net/src/error.rs | 4 +- net/src/transports/tls.rs | 8 +-- p2p/Cargo.toml | 2 +- p2p/src/error.rs | 4 +- p2p/src/tls_config.rs | 139 +++++++++++++++++++++++++++++++--------------- 6 files changed, 105 insertions(+), 54 deletions(-) diff --git a/net/Cargo.toml b/net/Cargo.toml index 5fecff5..6b816a8 100644 --- a/net/Cargo.toml +++ b/net/Cargo.toml @@ -14,4 +14,4 @@ log = "0.4.20" bincode = { version="2.0.0-rc.3", features = ["derive"]} thiserror = "1.0.47" url = "2.4.1" -async-rustls = { version = "0.4.1", features = ["dangerous_configuration"] } +futures-rustls = "0.25.1" diff --git a/net/src/error.rs b/net/src/error.rs index 0d96d64..be90a03 100644 --- a/net/src/error.rs +++ b/net/src/error.rs @@ -29,10 +29,10 @@ pub enum Error { ChannelRecv(#[from] smol::channel::RecvError), #[error("Tls Error: {0}")] - Rustls(#[from] async_rustls::rustls::Error), + Rustls(#[from] futures_rustls::rustls::Error), #[error("Invalid DNS Name: {0}")] - InvalidDnsNameError(#[from] async_rustls::rustls::client::InvalidDnsNameError), + InvalidDnsNameError(#[from] futures_rustls::pki_types::InvalidDnsNameError), #[error(transparent)] KaryonCore(#[from] karyon_core::error::Error), diff --git a/net/src/transports/tls.rs b/net/src/transports/tls.rs index 8a43d7d..83f7a11 100644 --- a/net/src/transports/tls.rs +++ b/net/src/transports/tls.rs @@ -1,7 +1,7 @@ use std::sync::Arc; -use async_rustls::{rustls, TlsAcceptor, TlsConnector, TlsStream}; use async_trait::async_trait; +use futures_rustls::{pki_types, rustls, TlsAcceptor, TlsConnector, TlsStream}; use smol::{ io::{split, AsyncReadExt, AsyncWriteExt, ReadHalf, WriteHalf}, lock::Mutex, @@ -63,7 +63,7 @@ pub async fn dial_tls( addr: &Addr, port: &Port, config: rustls::ClientConfig, - dns_name: &str, + dns_name: &'static str, ) -> Result { let address = format!("{}:{}", addr, port); @@ -72,7 +72,7 @@ pub async fn dial_tls( let sock = TcpStream::connect(&address).await?; sock.set_nodelay(true)?; - let altname = rustls::ServerName::try_from(dns_name)?; + let altname = pki_types::ServerName::try_from(dns_name)?; let conn = connector.connect(altname, sock.clone()).await?; Ok(TlsConn::new(sock, TlsStream::Client(conn))) } @@ -81,7 +81,7 @@ pub async fn dial_tls( pub async fn dial( endpoint: &Endpoint, config: rustls::ClientConfig, - dns_name: &str, + dns_name: &'static str, ) -> Result> { match endpoint { Endpoint::Tcp(..) | Endpoint::Tls(..) => {} diff --git a/p2p/Cargo.toml b/p2p/Cargo.toml index 441c8f9..0679be8 100644 --- a/p2p/Cargo.toml +++ b/p2p/Cargo.toml @@ -21,7 +21,7 @@ semver = "1.0.20" sha2 = "0.10.8" # tls -async-rustls = { version = "0.4.1", features = ["dangerous_configuration"] } +futures-rustls = { version = "0.25.1", features = ["aws-lc-rs"] } rcgen = "0.11.3" yasna = "0.5.2" x509-parser = "0.15.1" diff --git a/p2p/src/error.rs b/p2p/src/error.rs index 11de0f1..75330a8 100644 --- a/p2p/src/error.rs +++ b/p2p/src/error.rs @@ -63,10 +63,10 @@ pub enum Error { Rcgen(#[from] rcgen::RcgenError), #[error("Tls Error: {0}")] - Rustls(#[from] async_rustls::rustls::Error), + Rustls(#[from] futures_rustls::rustls::Error), #[error("Invalid DNS Name: {0}")] - InvalidDnsNameError(#[from] async_rustls::rustls::client::InvalidDnsNameError), + InvalidDnsNameError(#[from] futures_rustls::pki_types::InvalidDnsNameError), #[error("Channel Send Error: {0}")] ChannelSend(String), diff --git a/p2p/src/tls_config.rs b/p2p/src/tls_config.rs index ebb12f4..893c321 100644 --- a/p2p/src/tls_config.rs +++ b/p2p/src/tls_config.rs @@ -1,10 +1,19 @@ use std::sync::Arc; -use async_rustls::rustls::{ - self, cipher_suite::TLS13_CHACHA20_POLY1305_SHA256, client::ServerCertVerifier, - server::ClientCertVerifier, Certificate, CertificateError, Error::InvalidCertificate, - PrivateKey, SupportedCipherSuite, SupportedKxGroup, SupportedProtocolVersion, +use futures_rustls::rustls::{ + self, + client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier}, + crypto::{ + aws_lc_rs::{self, cipher_suite::TLS13_CHACHA20_POLY1305_SHA256, kx_group}, + CryptoProvider, SupportedKxGroup, + }, + pki_types::{CertificateDer, PrivateKeyDer, ServerName, UnixTime}, + server::danger::{ClientCertVerified, ClientCertVerifier}, + CertificateError, DigitallySignedStruct, DistinguishedName, + Error::InvalidCertificate, + SignatureScheme, SupportedCipherSuite, SupportedProtocolVersion, }; + use log::error; use x509_parser::{certificate::X509Certificate, parse_x509_certificate}; @@ -16,7 +25,8 @@ use crate::{PeerID, Result}; static PROTOCOL_VERSIONS: &[&SupportedProtocolVersion] = &[&rustls::version::TLS13]; static CIPHER_SUITES: &[SupportedCipherSuite] = &[TLS13_CHACHA20_POLY1305_SHA256]; -static KX_GROUPS: &[&SupportedKxGroup] = &[&rustls::kx_group::X25519]; +static KX_GROUPS: &[&dyn SupportedKxGroup] = &[kx_group::X25519]; +static SIGNATURE_SCHEMES: &[SignatureScheme] = &[SignatureScheme::ED25519]; const BAD_SIGNATURE_ERR: rustls::Error = InvalidCertificate(CertificateError::BadSignature); const BAD_ENCODING_ERR: rustls::Error = InvalidCertificate(CertificateError::BadEncoding); @@ -28,12 +38,19 @@ pub fn tls_client_config( ) -> Result { let (cert, private_key) = generate_cert(key_pair)?; let server_verifier = SrvrCertVerifier { peer_id }; - let client_config = rustls::ClientConfig::builder() - .with_cipher_suites(CIPHER_SUITES) - .with_kx_groups(KX_GROUPS) - .with_protocol_versions(PROTOCOL_VERSIONS)? - .with_custom_certificate_verifier(Arc::new(server_verifier)) - .with_client_auth_cert(vec![cert], private_key)?; + + let client_config = rustls::ClientConfig::builder_with_provider( + CryptoProvider { + kx_groups: KX_GROUPS.to_vec(), + cipher_suites: CIPHER_SUITES.to_vec(), + ..aws_lc_rs::default_provider() + } + .into(), + ) + .with_protocol_versions(PROTOCOL_VERSIONS)? + .dangerous() + .with_custom_certificate_verifier(Arc::new(server_verifier)) + .with_client_auth_cert(vec![cert], private_key)?; Ok(client_config) } @@ -42,20 +59,25 @@ pub fn tls_client_config( pub fn tls_server_config(key_pair: &KeyPair) -> Result { let (cert, private_key) = generate_cert(key_pair)?; let client_verifier = CliCertVerifier {}; - let server_config = rustls::ServerConfig::builder() - .with_cipher_suites(CIPHER_SUITES) - .with_kx_groups(KX_GROUPS) - .with_protocol_versions(PROTOCOL_VERSIONS)? - .with_client_cert_verifier(Arc::new(client_verifier)) - .with_single_cert(vec![cert], private_key)?; + let server_config = rustls::ServerConfig::builder_with_provider( + CryptoProvider { + kx_groups: KX_GROUPS.to_vec(), + cipher_suites: CIPHER_SUITES.to_vec(), + ..aws_lc_rs::default_provider() + } + .into(), + ) + .with_protocol_versions(PROTOCOL_VERSIONS)? + .with_client_cert_verifier(Arc::new(client_verifier)) + .with_single_cert(vec![cert], private_key)?; Ok(server_config) } /// Generates a certificate and returns both the certificate and the private key. -fn generate_cert(key_pair: &KeyPair) -> Result<(Certificate, PrivateKey)> { +fn generate_cert<'a>(key_pair: &KeyPair) -> Result<(CertificateDer<'a>, PrivateKeyDer<'a>)> { let cert_key_pair = rcgen::KeyPair::generate(&rcgen::PKCS_ED25519)?; - let private_key = rustls::PrivateKey(cert_key_pair.serialize_der()); + let private_key = PrivateKeyDer::Pkcs8(cert_key_pair.serialize_der().into()); // Add a custom extension to the certificate: // - Sign the certificate's public key with the provided key pair's private key @@ -71,12 +93,12 @@ fn generate_cert(key_pair: &KeyPair) -> Result<(Certificate, PrivateKey)> { params.key_pair = Some(cert_key_pair); params.custom_extensions.push(ext); - let cert = rustls::Certificate(rcgen::Certificate::from_params(params)?.serialize_der()?); + let cert = CertificateDer::from(rcgen::Certificate::from_params(params)?.serialize_der()?); Ok((cert, private_key)) } /// Verifies the given certification. -fn verify_cert(end_entity: &Certificate) -> std::result::Result { +fn verify_cert(end_entity: &CertificateDer<'_>) -> std::result::Result { // Parse the certificate. let cert = parse_cert(end_entity)?; @@ -107,7 +129,9 @@ fn verify_cert(end_entity: &Certificate) -> std::result::Result std::result::Result { +fn parse_cert<'a>( + end_entity: &'a CertificateDer<'a>, +) -> std::result::Result, rustls::Error> { let (_, cert) = parse_x509_certificate(end_entity.as_ref()).map_err(|_| BAD_ENCODING_ERR)?; if !cert.validity().is_valid() { @@ -134,6 +158,7 @@ fn verify_cert_signature( .map_err(|_| BAD_SIGNATURE_ERR) } +#[derive(Debug)] struct SrvrCertVerifier { peer_id: Option, } @@ -141,13 +166,12 @@ struct SrvrCertVerifier { impl ServerCertVerifier for SrvrCertVerifier { fn verify_server_cert( &self, - end_entity: &Certificate, - _intermediates: &[Certificate], - _server_name: &rustls::ServerName, - _scts: &mut dyn Iterator, + end_entity: &CertificateDer<'_>, + _intermediates: &[CertificateDer<'_>], + _server_name: &ServerName, _ocsp_response: &[u8], - _now: std::time::SystemTime, - ) -> std::result::Result { + _now: UnixTime, + ) -> std::result::Result { let peer_id = match verify_cert(end_entity) { Ok(pid) => pid, Err(err) => { @@ -167,49 +191,76 @@ impl ServerCertVerifier for SrvrCertVerifier { } } - Ok(rustls::client::ServerCertVerified::assertion()) + Ok(ServerCertVerified::assertion()) + } + + fn verify_tls12_signature( + &self, + _message: &[u8], + _cert: &CertificateDer<'_>, + _dss: &DigitallySignedStruct, + ) -> std::result::Result { + unreachable!("ONLY SUPPORT tls 13 VERSION") } fn verify_tls13_signature( &self, message: &[u8], - cert: &Certificate, - dss: &rustls::DigitallySignedStruct, - ) -> std::result::Result { + cert: &CertificateDer<'_>, + dss: &DigitallySignedStruct, + ) -> std::result::Result { let cert = parse_cert(cert)?; verify_cert_signature(&cert, message, dss.signature())?; - Ok(rustls::client::HandshakeSignatureValid::assertion()) + Ok(HandshakeSignatureValid::assertion()) + } + + fn supported_verify_schemes(&self) -> Vec { + SIGNATURE_SCHEMES.to_vec() } } +#[derive(Debug)] struct CliCertVerifier {} impl ClientCertVerifier for CliCertVerifier { fn verify_client_cert( &self, - end_entity: &Certificate, - _intermediates: &[Certificate], - _now: std::time::SystemTime, - ) -> std::result::Result { + end_entity: &CertificateDer<'_>, + _intermediates: &[CertificateDer<'_>], + _now: UnixTime, + ) -> std::result::Result { if let Err(err) = verify_cert(end_entity) { error!("Failed to verify cert: {err}"); return Err(err); }; - Ok(rustls::server::ClientCertVerified::assertion()) + Ok(ClientCertVerified::assertion()) + } + + fn root_hint_subjects(&self) -> &[DistinguishedName] { + &[] + } + + fn verify_tls12_signature( + &self, + _message: &[u8], + _cert: &CertificateDer<'_>, + _dss: &DigitallySignedStruct, + ) -> std::result::Result { + unreachable!("ONLY SUPPORT tls 13 VERSION") } fn verify_tls13_signature( &self, message: &[u8], - cert: &Certificate, - dss: &rustls::DigitallySignedStruct, - ) -> std::result::Result { + cert: &CertificateDer<'_>, + dss: &DigitallySignedStruct, + ) -> std::result::Result { let cert = parse_cert(cert)?; verify_cert_signature(&cert, message, dss.signature())?; - Ok(rustls::client::HandshakeSignatureValid::assertion()) + Ok(HandshakeSignatureValid::assertion()) } - fn client_auth_root_subjects(&self) -> &[rustls::DistinguishedName] { - &[] + fn supported_verify_schemes(&self) -> Vec { + SIGNATURE_SCHEMES.to_vec() } } -- cgit v1.2.3