From 743f0ddf1bb479d9fc37e645f706a8fc60ffb84e Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Wed, 20 Oct 2021 17:22:55 +0100 Subject: [PATCH] fix last remaining rustls upgrade --- .cargo/config.toml | 2 + .github/workflows/ci.yml | 33 +++++++++++++- Cargo.toml | 4 +- actix-http-test/Cargo.toml | 2 +- actix-http/Cargo.toml | 5 +-- actix-http/src/client/connector.rs | 71 ++++++++++++++++++------------ actix-http/tests/test_rustls.rs | 15 +------ awc/Cargo.toml | 4 +- awc/tests/test_rustls_client.rs | 15 +------ 9 files changed, 86 insertions(+), 65 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index f417a7053..64f303d42 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -7,3 +7,5 @@ ci-default = "check --workspace --bins --tests --examples" ci-full = "check --workspace --all-features --bins --tests --examples" ci-test = "test --workspace --all-features --lib --tests --no-fail-fast -- --nocapture" ci-doctest = "test --workspace --all-features --doc --no-fail-fast -- --nocapture" +ci-feature-powerset-check-openssl="hack --workspace --feature-powerset --skip=__compress,rustls check" +ci-feature-powerset-check-rustls="hack --workspace --feature-powerset --skip=__compress,openssl check" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index faf734e47..d2680524c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -88,6 +88,38 @@ jobs: cargo install cargo-cache --version 0.6.3 --no-default-features --features ci-autoclean cargo-cache + ci_feature_powerset_check: + name: coverage + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Install stable + uses: actions-rs/toolchain@v1 + with: + toolchain: stable-x86_64-unknown-linux-gnu + profile: minimal + override: true + + - name: Generate Cargo.lock + uses: actions-rs/cargo@v1 + with: { command: generate-lockfile } + - name: Cache Dependencies + uses: Swatinem/rust-cache@v1.2.0 + + - name: Install cargo-hack + uses: actions-rs/cargo@v1 + with: + command: install + args: cargo-hack + + - name: check feature combinations + # if: github.ref == 'refs/heads/master' + uses: actions-rs/cargo@v1 + run: | + cargo ci-feature-powerset-check-openssl + cargo ci-feature-powerset-check-rustls + coverage: name: coverage runs-on: ubuntu-latest @@ -117,7 +149,6 @@ jobs: uses: codecov/codecov-action@v1 with: { file: cobertura.xml } - rustdoc: name: rustdoc runs-on: ubuntu-latest diff --git a/Cargo.toml b/Cargo.toml index 09882e14c..0b4c8dcf4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,7 +73,7 @@ actix-rt = "2.2" actix-server = "2.0.0-beta.3" actix-service = "2.0.0" actix-utils = "3.0.0" -actix-tls = { version = "3.0.0-beta.6", default-features = false, optional = true } +actix-tls = { version = "3.0.0-beta.7", default-features = false, optional = true } actix-web-codegen = "0.5.0-beta.5" actix-http = "3.0.0-beta.11" @@ -117,8 +117,6 @@ rcgen = "0.8" rustls-pemfile = "0.2" tls-openssl = { package = "openssl", version = "0.10.9" } tls-rustls = { package = "rustls", version = "0.20.0" } -webpki = "0.22" -webpki-roots = "0.22" zstd = "0.7" [profile.dev] diff --git a/actix-http-test/Cargo.toml b/actix-http-test/Cargo.toml index 36b08c653..d3fc8a47f 100644 --- a/actix-http-test/Cargo.toml +++ b/actix-http-test/Cargo.toml @@ -31,7 +31,7 @@ openssl = ["tls-openssl", "awc/openssl"] [dependencies] actix-service = "2.0.0" actix-codec = "0.4.0" -actix-tls = "3.0.0-beta.6" +actix-tls = "3.0.0-beta.7" actix-utils = "3.0.0" actix-rt = "2.2" actix-server = "2.0.0-beta.3" diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index f12c2a0d9..3abf537fa 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -49,7 +49,7 @@ actix-service = "2.0.0" actix-codec = "0.4.0" actix-utils = "3.0.0" actix-rt = "2.2" -actix-tls = { version = "3.0.0-beta.6", features = ["accept", "connect"] } +actix-tls = { version = "3.0.0-beta.7", features = ["accept", "connect"] } ahash = "0.7" base64 = "0.13" @@ -88,7 +88,7 @@ trust-dns-resolver = { version = "0.20.0", optional = true } [dev-dependencies] actix-server = "2.0.0-beta.3" actix-http-test = { version = "3.0.0-beta.5", features = ["openssl"] } -actix-tls = { version = "3.0.0-beta.6", features = ["openssl"] } +actix-tls = { version = "3.0.0-beta.7", features = ["openssl"] } async-stream = "0.3" criterion = { version = "0.3", features = ["html_reports"] } env_logger = "0.8" @@ -99,7 +99,6 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" tls-openssl = { package = "openssl", version = "0.10.9" } tls-rustls = { package = "rustls", version = "0.20.0" } -webpki = { version = "0.22" } [[example]] name = "ws" diff --git a/actix-http/src/client/connector.rs b/actix-http/src/client/connector.rs index bde5e4853..eda98e55a 100644 --- a/actix-http/src/client/connector.rs +++ b/actix-http/src/client/connector.rs @@ -28,18 +28,13 @@ use super::pool::ConnectionPool; use super::Connect; use super::Protocol; -#[cfg(feature = "openssl")] -use actix_tls::connect::ssl::openssl::SslConnector as OpensslConnector; -#[cfg(feature = "rustls")] -use actix_tls::connect::ssl::rustls::ClientConfig; - enum SslConnector { #[allow(dead_code)] None, #[cfg(feature = "openssl")] - Openssl(OpensslConnector), + Openssl(actix_tls::connect::ssl::openssl::SslConnector), #[cfg(feature = "rustls")] - Rustls(std::sync::Arc), + Rustls(std::sync::Arc), } /// Manages HTTP client network connectivity. @@ -78,10 +73,25 @@ impl Connector<()> { } } - // Build Ssl connector with openssl, based on supplied alpn protocols - #[cfg(feature = "openssl")] + /// Provides an empty TLS connector when no TLS feature is enabled. + #[cfg(not(any(feature = "openssl", feature = "rustls")))] + fn build_ssl(_: Vec>) -> SslConnector { + SslConnector::None + } + + /// Provides an empty TLS connector when no TLS feature is enabled. + #[cfg(all(feature = "openssl", feature = "rustls"))] + fn build_ssl(_: Vec>) -> SslConnector { + compile_error!("openssl and rustls features are mutually exclusive"); + panic!("openssl and rustls features are mutually exclusive"); + } + + // Build TLS connector with openssl, based on supplied alpn protocols + #[cfg(all(feature = "openssl", not(feature = "rustls")))] fn build_ssl(protocols: Vec>) -> SslConnector { - use actix_tls::connect::ssl::openssl::SslMethod; + use actix_tls::connect::tls::openssl::{ + SslConnector as OpensslConnector, SslMethod, + }; use bytes::{BufMut, BytesMut}; let mut alpn = BytesMut::with_capacity(20); @@ -91,27 +101,26 @@ impl Connector<()> { } let mut ssl = OpensslConnector::builder(SslMethod::tls()).unwrap(); - let _ = ssl - .set_alpn_protos(&alpn) - .map_err(|e| error!("Can not set alpn protocol: {:?}", e)); + if let Err(err) = ssl.set_alpn_protos(&alpn) { + error!("Can not set ALPN protocol: {:?}", err); + } + SslConnector::Openssl(ssl.build()) } - // Build Ssl connector with rustls, based on supplied alpn protocols - #[cfg(all(not(feature = "openssl"), feature = "rustls"))] + // Build TLS connector with rustls, based on supplied alpn protocols + #[cfg(all(feature = "rustls", not(feature = "openssl")))] fn build_ssl(protocols: Vec>) -> SslConnector { - let mut config = ClientConfig::new(); - config.set_protocols(&protocols); - config.root_store.add_server_trust_anchors( - &actix_tls::connect::ssl::rustls::TLS_SERVER_ROOTS, - ); - SslConnector::Rustls(std::sync::Arc::new(config)) - } + use actix_tls::connect::tls::rustls::{webpki_roots_cert_store, ClientConfig}; - // ssl turned off, provides empty ssl connector - #[cfg(not(any(feature = "openssl", feature = "rustls")))] - fn build_ssl(_: Vec>) -> SslConnector { - SslConnector::None + let mut config = ClientConfig::builder() + .with_safe_defaults() + .with_root_certificates(webpki_roots_cert_store()) + .with_no_client_auth(); + + config.alpn_protocols = protocols; + + SslConnector::Rustls(std::sync::Arc::new(config)) } } @@ -167,14 +176,20 @@ where #[cfg(feature = "openssl")] /// Use custom `SslConnector` instance. - pub fn ssl(mut self, connector: OpensslConnector) -> Self { + pub fn ssl( + mut self, + connector: actix_tls::connect::ssl::openssl::SslConnector, + ) -> Self { self.ssl = SslConnector::Openssl(connector); self } #[cfg(feature = "rustls")] /// Use custom `SslConnector` instance. - pub fn rustls(mut self, connector: std::sync::Arc) -> Self { + pub fn rustls( + mut self, + connector: std::sync::Arc, + ) -> Self { self.ssl = SslConnector::Rustls(connector); self } diff --git a/actix-http/tests/test_rustls.rs b/actix-http/tests/test_rustls.rs index 69c7db74d..924ef49ad 100644 --- a/actix-http/tests/test_rustls.rs +++ b/actix-http/tests/test_rustls.rs @@ -20,7 +20,7 @@ use actix_http::{ }; use actix_http_test::test_server; use actix_service::{fn_factory_with_config, fn_service}; -use actix_tls::connect::ssl::rustls::TLS_SERVER_ROOTS; +use actix_tls::connect::tls::rustls::webpki_roots_cert_store; use actix_utils::future::{err, ok}; use bytes::{Bytes, BytesMut}; use derive_more::{Display, Error}; @@ -74,20 +74,9 @@ pub fn get_negotiated_alpn_protocol( addr: SocketAddr, client_alpn_protocol: &[u8], ) -> Option> { - let mut root_certs = RootCertStore::empty(); - for cert in TLS_SERVER_ROOTS.0 { - let cert = OwnedTrustAnchor::from_subject_spki_name_constraints( - cert.subject, - cert.spki, - cert.name_constraints, - ); - let certs = vec![cert].into_iter(); - root_certs.add_server_trust_anchors(certs); - } - let mut config = rustls::ClientConfig::builder() .with_safe_defaults() - .with_root_certificates(root_certs) + .with_root_certificates(webpki_roots_cert_store()) .with_no_client_auth(); config.alpn_protocols.push(client_alpn_protocol.to_vec()); diff --git a/awc/Cargo.toml b/awc/Cargo.toml index 60672c973..5a8235336 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -82,7 +82,7 @@ actix-http = { version = "3.0.0-beta.11", features = ["openssl"] } actix-http-test = { version = "3.0.0-beta.5", features = ["openssl"] } actix-utils = "3.0.0" actix-server = "2.0.0-beta.3" -actix-tls = { version = "3.0.0-beta.6", features = ["openssl", "rustls"] } +actix-tls = { version = "3.0.0-beta.7", features = ["openssl", "rustls"] } actix-test = { version = "0.1.0-beta.5", features = ["openssl", "rustls"] } brotli2 = "0.3.2" @@ -91,8 +91,6 @@ flate2 = "1.0.13" futures-util = { version = "0.3.7", default-features = false } rcgen = "0.8" rustls-pemfile = "0.2" -webpki = "0.22" -webpki-roots = "0.22" [[example]] name = "client" diff --git a/awc/tests/test_rustls_client.rs b/awc/tests/test_rustls_client.rs index 95f2d0616..c075a6090 100644 --- a/awc/tests/test_rustls_client.rs +++ b/awc/tests/test_rustls_client.rs @@ -14,6 +14,7 @@ use std::{ use actix_http::HttpService; use actix_http_test::test_server; use actix_service::{fn_service, map_config, ServiceFactoryExt}; +use actix_tls::connect::tls::rustls::webpki_roots_cert_store; use actix_utils::future::ok; use actix_web::{dev::AppConfig, http::Version, web, App, HttpResponse}; use rustls::{ @@ -22,7 +23,6 @@ use rustls::{ ServerName, }; use rustls_pemfile::{certs, pkcs8_private_keys}; -use webpki_roots::TLS_SERVER_ROOTS; fn tls_config() -> ServerConfig { let cert = rcgen::generate_simple_self_signed(vec!["localhost".to_owned()]).unwrap(); @@ -89,20 +89,9 @@ async fn test_connection_reuse_h2() { }) .await; - let mut root_certs = RootCertStore::empty(); - for cert in TLS_SERVER_ROOTS.0 { - let cert = OwnedTrustAnchor::from_subject_spki_name_constraints( - cert.subject, - cert.spki, - cert.name_constraints, - ); - let certs = vec![cert].into_iter(); - root_certs.add_server_trust_anchors(certs); - } - let mut config = ClientConfig::builder() .with_safe_defaults() - .with_root_certificates(root_certs) + .with_root_certificates(webpki_roots_cert_store()) .with_no_client_auth(); let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];