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 --- p2p/Cargo.toml | 2 +- p2p/src/error.rs | 4 +- p2p/src/tls_config.rs | 139 ++++++++++++++++++++++++++++++++++---------------- 3 files changed, 98 insertions(+), 47 deletions(-) (limited to 'p2p') 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