From 9a73feb0c278b9e4aa3c94d8bca1707cc4502852 Mon Sep 17 00:00:00 2001 From: Sean Lawlor Date: Sat, 17 Feb 2024 10:12:56 -0500 Subject: [PATCH] Updating rustls dependencies & adjusting for new types/patterns (#204) --- ractor/Cargo.toml | 2 +- ractor_cluster/Cargo.toml | 4 +- ractor_cluster/src/node/client.rs | 5 +- ractor_cluster_derive/Cargo.toml | 2 +- ractor_cluster_integration_tests/Cargo.toml | 4 +- .../envs/encryption.env | 3 +- .../src/tests/encryption.rs | 76 ++++++++++++------- 7 files changed, 61 insertions(+), 35 deletions(-) diff --git a/ractor/Cargo.toml b/ractor/Cargo.toml index 73b8bcb2..ff3bc1a8 100644 --- a/ractor/Cargo.toml +++ b/ractor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ractor" -version = "0.9.5" +version = "0.9.6" authors = ["Sean Lawlor", "Evan Au", "Dillon George"] description = "A actor framework for Rust" documentation = "https://docs.rs/ractor" diff --git a/ractor_cluster/Cargo.toml b/ractor_cluster/Cargo.toml index 66f77c68..534a8677 100644 --- a/ractor_cluster/Cargo.toml +++ b/ractor_cluster/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ractor_cluster" -version = "0.9.5" +version = "0.9.6" authors = ["Sean Lawlor", "Evan Au", "Dillon George"] description = "Distributed cluster environment of Ractor actors" documentation = "https://docs.rs/ractor" @@ -29,7 +29,7 @@ ractor_cluster_derive = { version = "0.9.0", path = "../ractor_cluster_derive" } rand = "0.8" sha2 = "0.10" tokio = { version = "1", features = ["rt", "time", "sync", "macros", "net", "io-util", "tracing"]} -tokio-rustls = { version = "0.24" } +tokio-rustls = { version = "0.25" } tracing = "0.1" [dev-dependencies] diff --git a/ractor_cluster/src/node/client.rs b/ractor_cluster/src/node/client.rs index 63e77a4f..777582b8 100644 --- a/ractor_cluster/src/node/client.rs +++ b/ractor_cluster/src/node/client.rs @@ -9,6 +9,7 @@ use std::fmt::Display; use ractor::{ActorRef, MessagingErr}; use tokio::net::{TcpStream, ToSocketAddrs}; +use tokio_rustls::rustls::pki_types::ServerName; /// A client connection error. Possible issues are Socket connection /// problems or failure to talk to the [super::NodeServer] @@ -90,7 +91,7 @@ where /// * `node_server` - The [super::NodeServer] which will own this new connection session /// * `address` - The network address to send the connection to. Must implement [ToSocketAddrs] /// * `encryption_settings` - The [tokio_rustls::TlsConnector] which is configured to encrypt the socket -/// * `domain` - The server name we're connecting to ([tokio_rustls::rustls::ServerName]) +/// * `domain` - The server name we're connecting to ([ServerName]) /// /// Returns: [Ok(())] if the connection was successful and the [super::NodeSession] was started. Handshake will continue /// automatically. Results in a [Err(ClientConnectError)] if any part of the process failed to initiate @@ -98,7 +99,7 @@ pub async fn connect_enc( node_server: &ActorRef, address: T, encryption_settings: tokio_rustls::TlsConnector, - domain: tokio_rustls::rustls::ServerName, + domain: ServerName<'static>, ) -> Result<(), ClientConnectErr> where T: ToSocketAddrs, diff --git a/ractor_cluster_derive/Cargo.toml b/ractor_cluster_derive/Cargo.toml index e3c88cea..1b4656d9 100644 --- a/ractor_cluster_derive/Cargo.toml +++ b/ractor_cluster_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ractor_cluster_derive" -version = "0.9.5" +version = "0.9.6" authors = ["Sean Lawlor "] description = "Derives for ractor_cluster" license = "MIT" diff --git a/ractor_cluster_integration_tests/Cargo.toml b/ractor_cluster_integration_tests/Cargo.toml index a8569f8a..f7fb56f2 100644 --- a/ractor_cluster_integration_tests/Cargo.toml +++ b/ractor_cluster_integration_tests/Cargo.toml @@ -17,8 +17,8 @@ clap = { version = "4", features = ["derive"] } ractor = { path = "../ractor" } ractor_cluster = { path = "../ractor_cluster" } rand = "0.8" -tokio-rustls = { version = "0.24" } -rustls-pemfile = "1.0" +tokio-rustls = { version = "0.25" } +rustls-pemfile = "2.1" rustyrepl = { version = "0.2", features = ["async"] } tokio = { version = "1", features = ["rt", "time", "sync", "macros", "rt-multi-thread", "signal", "tracing"] } tracing = "0.1" diff --git a/ractor_cluster_integration_tests/envs/encryption.env b/ractor_cluster_integration_tests/envs/encryption.env index 707dc245..14096c8b 100644 --- a/ractor_cluster_integration_tests/envs/encryption.env +++ b/ractor_cluster_integration_tests/envs/encryption.env @@ -1,2 +1,3 @@ A_TEST="encryption 8199" -B_TEST="encryption 8198 8199 node-a" \ No newline at end of file +B_TEST="encryption 8198 8199 node-a" +C_TEST="nan" \ No newline at end of file diff --git a/ractor_cluster_integration_tests/src/tests/encryption.rs b/ractor_cluster_integration_tests/src/tests/encryption.rs index bf0dc694..90d87b4e 100644 --- a/ractor_cluster_integration_tests/src/tests/encryption.rs +++ b/ractor_cluster_integration_tests/src/tests/encryption.rs @@ -10,14 +10,14 @@ use std::convert::TryFrom; use std::fs::File; use std::io::{self, BufReader}; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::sync::Arc; use clap::Args; use ractor::concurrency::{sleep, Duration, Instant}; use ractor::Actor; use rustls_pemfile::{certs, rsa_private_keys}; -use tokio_rustls::rustls::{Certificate, OwnedTrustAnchor, PrivateKey}; +use tokio_rustls::rustls::pki_types::{CertificateDer, PrivateKeyDer, ServerName, TrustAnchor}; use tokio_rustls::{TlsAcceptor, TlsConnector}; const AUTH_TIME_ALLOWANCE_MS: u128 = 1500; @@ -33,16 +33,35 @@ pub struct EncryptionConfig { client_host: Option, } -fn load_certs(path: &Path) -> io::Result> { - certs(&mut BufReader::new(File::open(path)?)) - .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid cert")) - .map(|mut certs| certs.drain(..).map(Certificate).collect()) +fn load_certs(path_str: &'static str) -> io::Result> { + let path = PathBuf::from(path_str); + let certs: Vec<_> = certs(&mut BufReader::new(File::open(path)?)) + .filter_map(|cert| if let Ok(c) = cert { Some(c) } else { None }) + .collect(); + + if certs.is_empty() { + Err(io::Error::new(io::ErrorKind::InvalidData, "invalid cert")) + } else { + Ok(certs) + } } -fn load_keys(path: &Path) -> io::Result> { - rsa_private_keys(&mut BufReader::new(File::open(path)?)) - .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid key")) - .map(|mut keys| keys.drain(..).map(PrivateKey).collect()) +fn load_keys(path_str: &'static str) -> io::Result> { + let path = PathBuf::from(path_str); + let keys: Vec = rsa_private_keys(&mut BufReader::new(File::open(path)?)) + .filter_map(|key| { + if let Ok(k) = key { + Some(k.into()) + } else { + None + } + }) + .collect(); + if keys.is_empty() { + Err(io::Error::new(io::ErrorKind::InvalidData, "invalid key")) + } else { + Ok(keys) + } } pub async fn test(config: EncryptionConfig) -> i32 { @@ -53,13 +72,12 @@ pub async fn test(config: EncryptionConfig) -> i32 { // Example `rustls` command: cargo run --bin tlsserver-mio -- --certs test-ca/rsa/end.fullchain --key test-ca/rsa/end.rsa -p 8443 echo // // combined with source code: https://github.com/tokio-rs/tls/blob/357bc562483dcf04c1f8d08bd1a831b144bf7d4c/tokio-rustls/examples/server/src/main.rs - let cert_path = PathBuf::from("test-ca/rsa/end.fullchain"); - let key_path = PathBuf::from("test-ca/rsa/end.rsa"); - let certs = load_certs(&cert_path).expect("Failed to load encryption certificates"); - let mut keys = load_keys(&key_path).expect("Failed to load encryption keys"); + let cert_path = "test-ca/rsa/end.fullchain"; + let key_path = "test-ca/rsa/end.rsa"; + let certs = load_certs(cert_path).expect("Failed to load encryption certificates"); + let mut keys = load_keys(key_path).expect("Failed to load encryption keys"); let server_config = tokio_rustls::rustls::ServerConfig::builder() - .with_safe_defaults() .with_no_client_auth() .with_single_cert(certs, keys.remove(0)) .expect("Failed to build server configuration"); @@ -69,33 +87,39 @@ pub async fn test(config: EncryptionConfig) -> i32 { let ca_path = PathBuf::from("test-ca/rsa/ca.cert"); let mut ca_pem = BufReader::new(File::open(ca_path).expect("Failed to load CA certificate")); - let ca_certs = rustls_pemfile::certs(&mut ca_pem).expect("Failed to parse CA certificate"); + let ca_certs = rustls_pemfile::certs(&mut ca_pem).filter_map(|cert| { + if let Ok(c) = cert { + Some(c) + } else { + None + } + }); let mut root_cert_store = tokio_rustls::rustls::RootCertStore::empty(); - let trust_anchors = ca_certs.iter().map(|cert| { + let trust_anchors = ca_certs.map(|cert| { let ta = webpki::TrustAnchor::try_from_cert_der(&cert[..]).expect("Failed to build TrustAnchor"); tracing::warn!( "CA Cert SUB={}", String::from_utf8(ta.subject.to_vec()).unwrap_or("n/a".to_string()) ); - OwnedTrustAnchor::from_subject_spki_name_constraints( - ta.subject, - ta.spki, - ta.name_constraints, - ) + TrustAnchor { + subject: ta.subject.into(), + name_constraints: ta.name_constraints.map(|a| a.into()), + subject_public_key_info: ta.spki.into(), + } + .to_owned() }); - root_cert_store.add_trust_anchors(trust_anchors); + root_cert_store.extend(trust_anchors); + // root_cert_store.add_trust_anchors(trust_anchors); let client_config = tokio_rustls::rustls::ClientConfig::builder() - .with_safe_defaults() .with_root_certificates(root_cert_store) .with_no_client_auth(); let connector = TlsConnector::from(Arc::new(client_config)); // NOTE: It's `testserver.com` because that's what's generated by the rustls team. Eventually we should re-generate // our own certs but this is just a temporary hack for the test - let domain = tokio_rustls::rustls::ServerName::try_from("testserver.com") - .expect("Invalid DNS name `node-a`"); + let domain = ServerName::try_from("testserver.com").expect("Invalid DNS name `node-a`"); // ================== Server Creation ================== //