diff --git a/async-nats/Cargo.toml b/async-nats/Cargo.toml index 9154af970..6cc71e510 100644 --- a/async-nats/Cargo.toml +++ b/async-nats/Cargo.toml @@ -38,6 +38,7 @@ tryhard = "0.5" ring = "0.17" rand = "0.8" webpki = { package = "rustls-webpki", version = "0.102" } +portable-atomic = "1" [dev-dependencies] criterion = { version = "0.5", features = ["async_tokio"]} diff --git a/async-nats/src/client.rs b/async-nats/src/client.rs index 46b33fe13..b4f1b0f87 100644 --- a/async-nats/src/client.rs +++ b/async-nats/src/client.rs @@ -21,9 +21,10 @@ use bytes::Bytes; use futures::future::TryFutureExt; use futures::StreamExt; use once_cell::sync::Lazy; +use portable_atomic::AtomicU64; use regex::Regex; use std::fmt::Display; -use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering}; +use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; use std::time::Duration; use thiserror::Error; diff --git a/async-nats/src/jetstream/consumer/push.rs b/async-nats/src/jetstream/consumer/push.rs index 1634a3c4e..3d20586af 100644 --- a/async-nats/src/jetstream/consumer/push.rs +++ b/async-nats/src/jetstream/consumer/push.rs @@ -24,18 +24,16 @@ use crate::{ use bytes::Bytes; use futures::{future::BoxFuture, FutureExt}; +use portable_atomic::AtomicU64; use serde::{Deserialize, Serialize}; #[cfg(feature = "server_2_10")] use std::collections::HashMap; +use std::task::{self, Poll}; use std::{ io::{self, ErrorKind}, pin::Pin, sync::Arc, }; -use std::{ - sync::atomic::AtomicU64, - task::{self, Poll}, -}; use std::{sync::atomic::Ordering, time::Duration}; use tokio::{sync::oneshot::error::TryRecvError, task::JoinHandle}; use tracing::{debug, trace}; diff --git a/nats/Cargo.toml b/nats/Cargo.toml index 0e4fb4dd3..4b7a91149 100644 --- a/nats/Cargo.toml +++ b/nats/Cargo.toml @@ -37,11 +37,12 @@ nkeys = "0.3.2" nuid = "0.3.1" once_cell = "1.8.0" parking_lot = "0.12.0" +portable-atomic = "1" regex = { version = "1.5.5", default-features = false, features = ["std", "unicode-perl"] } -rustls = "0.21" -rustls-native-certs = "0.6" -rustls-pemfile = "1.0.2" -webpki = { package = "rustls-webpki", version = "0.100.0", features = ["alloc", "std"] } +rustls = "0.22" +rustls-native-certs = "0.7" +rustls-pemfile = "2" +webpki = { package = "rustls-webpki", version = "0.102"} serde = { version = "1.0.126", features = ["derive"] } serde_json = "1.0.64" serde_nanos = "0.1.1" @@ -49,7 +50,7 @@ serde_repr = "0.1.7" memchr = "2.4.0" url = "2.2.2" time = { version = "0.3.6", features = ["parsing", "formatting", "serde", "serde-well-known"] } -ring = "0.16" +ring = "0.17" [target.'cfg(unix)'.dependencies] libc = "0.2.98" diff --git a/nats/src/auth_utils.rs b/nats/src/auth_utils.rs index b3d5fea04..6a6a19eda 100644 --- a/nats/src/auth_utils.rs +++ b/nats/src/auth_utils.rs @@ -18,7 +18,7 @@ use std::path::Path; use nkeys::KeyPair; use once_cell::sync::Lazy; use regex::Regex; -use rustls::{Certificate, PrivateKey}; +use webpki::types::{CertificateDer, PrivateKeyDer}; use crate::SecureString; @@ -100,36 +100,18 @@ fn parse_decorated_nkey(contents: &str) -> Option { /// If the pem file is found, but does not contain any certificates, it will return /// empty set of Certificates, not error. /// Can be used to parse only client certificates from .pem file containing both client key and certs. -pub(crate) fn load_certs(path: &Path) -> io::Result> { +pub(crate) fn load_certs(path: &Path) -> io::Result>> { let file = std::fs::File::open(path)?; let mut reader = BufReader::new(file); - let certs = rustls_pemfile::certs(&mut reader)? - .iter() - .map(|v| Certificate(v.clone())) - .collect(); - Ok(certs) + rustls_pemfile::certs(&mut reader).collect::>>() } /// Loads client key from a `.pem` file. /// Can be used to parse only client key from .pem file containing both client key and certs. -pub(crate) fn load_key(path: &Path) -> io::Result { +pub(crate) fn load_key(path: &Path) -> io::Result> { let file = std::fs::File::open(path)?; let mut reader = BufReader::new(file); - loop { - let cert = rustls_pemfile::read_one(&mut reader)?; - match cert { - Some(rustls_pemfile::Item::RSAKey(key)) - | Some(rustls_pemfile::Item::PKCS8Key(key)) - | Some(rustls_pemfile::Item::ECKey(key)) => return Ok(PrivateKey(key)), - // if public key is found, don't error, just skip it and hope to find client key next. - Some(rustls_pemfile::Item::X509Certificate(_)) | Some(_) => {} - None => break, - } - } - - Err(io::Error::new( - ErrorKind::NotFound, - "could not find client key in the path", - )) + rustls_pemfile::private_key(&mut reader)? + .ok_or_else(|| io::Error::new(ErrorKind::NotFound, "could not find client key in the path")) } diff --git a/nats/src/connector.rs b/nats/src/connector.rs index 02948d8f6..8d48079a7 100644 --- a/nats/src/connector.rs +++ b/nats/src/connector.rs @@ -51,18 +51,14 @@ fn configure_tls(options: &Arc) -> Result { // load native system certs only if user did not specify them if options.tls_client_config.is_some() || options.certificates.is_empty() { - let native_certs = rustls_native_certs::load_native_certs() - .map_err(|err| { - io::Error::new( - ErrorKind::Other, - format!("could not load platform certs: {err}"), - ) - })? - .into_iter() - .map(|cert| cert.0) - .collect::>>(); + let native_certs = rustls_native_certs::load_native_certs().map_err(|err| { + io::Error::new( + ErrorKind::Other, + format!("could not load platform certs: {err}"), + ) + })?; - root_store.add_parsable_certificates(&native_certs); + root_store.add_parsable_certificates(native_certs); } if let Some(config) = &options.tls_client_config { @@ -71,28 +67,21 @@ fn configure_tls(options: &Arc) -> Result { // Include user-provided certificates for path in &options.certificates { let mut pem = BufReader::new(std::fs::File::open(path)?); - let certs = rustls_pemfile::certs(&mut pem)?; - let trust_anchors = certs.iter().map(|cert| { - let trust_anchor = webpki::TrustAnchor::try_from_cert_der(&cert[..]) - .map_err(|err| { - io::Error::new( - ErrorKind::InvalidInput, - format!("could not load certs: {err}"), - ) - }) - .unwrap(); - rustls::OwnedTrustAnchor::from_subject_spki_name_constraints( - trust_anchor.subject, - trust_anchor.spki, - trust_anchor.name_constraints, - ) - }); - root_store.add_server_trust_anchors(trust_anchors); + let certs = rustls_pemfile::certs(&mut pem).collect::>>()?; + let trust_anchors = certs + .into_iter() + .map(|cert| webpki::anchor_from_trusted_cert(&cert).map(|ta| ta.to_owned())) + .collect::, webpki::Error>>() + .map_err(|err| { + io::Error::new( + ErrorKind::InvalidInput, + format!("could not load certs: {err}"), + ) + })?; + root_store.extend(trust_anchors); } - let builder = rustls::ClientConfig::builder() - .with_safe_defaults() - .with_root_certificates(root_store); + let builder = rustls::ClientConfig::builder().with_root_certificates(root_store); if let Some(cert) = &options.client_cert { if let Some(key) = &options.client_key { @@ -278,8 +267,8 @@ impl Connector { inject_io_failure()?; // Connect using TLS. - let server_name = - rustls::client::ServerName::try_from(server.host()).map_err(|_| { + let server_name = webpki::types::ServerName::try_from(server.host().to_string()) + .map_err(|_| { io::Error::new( io::ErrorKind::InvalidInput, "cannot determine hostname for TLS connection", diff --git a/nats/src/jetstream/mod.rs b/nats/src/jetstream/mod.rs index 364610f6a..6c6615263 100644 --- a/nats/src/jetstream/mod.rs +++ b/nats/src/jetstream/mod.rs @@ -106,7 +106,8 @@ use std::{ }; use parking_lot::Mutex; -use std::sync::atomic::{AtomicU64, Ordering}; +use portable_atomic::AtomicU64; +use std::sync::atomic::Ordering; use std::sync::Arc; use std::thread; diff --git a/nats/src/jetstream/push_subscription.rs b/nats/src/jetstream/push_subscription.rs index 9f36b6640..c467fd166 100644 --- a/nats/src/jetstream/push_subscription.rs +++ b/nats/src/jetstream/push_subscription.rs @@ -11,8 +11,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +use portable_atomic::AtomicU64; use std::io; -use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::atomic::Ordering; use std::sync::Arc; use std::thread; use std::time::{Duration, Instant}; diff --git a/nats/src/options.rs b/nats/src/options.rs index 7527c0c4b..a701c1e72 100644 --- a/nats/src/options.rs +++ b/nats/src/options.rs @@ -343,17 +343,9 @@ impl Options { /// ```no_run /// # fn main() -> std::io::Result<()> { /// let mut root_store = nats::rustls::RootCertStore::empty(); - /// - /// root_store.add_parsable_certificates( - /// rustls_native_certs::load_native_certs()? - /// .into_iter() - /// .map(|cert| cert.0) - /// .collect::>>() - /// .as_ref(), - /// ); + /// root_store.add_parsable_certificates(rustls_native_certs::load_native_certs()?); /// /// let tls_client_config = nats::rustls::ClientConfig::builder() - /// .with_safe_defaults() /// .with_root_certificates(root_store) /// .with_no_client_auth(); ///