diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9fa3e30..fa78177 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,8 +36,9 @@ jobs: - name: clippy run: > cargo hack --feature-powerset - --mutually-exclusive-features tls,tls-openssl - --mutually-exclusive-features tls-roots,tls-openssl clippy + --mutually-exclusive-features tls-ring,tls-aws-lc,tls-openssl + --mutually-exclusive-features tls-native-roots,tls-openssl + --mutually-exclusive-features tls-webpki-roots,tls-openssl clippy --all-targets -- -D warnings diff --git a/Cargo.toml b/Cargo.toml index 2147e1a..541c45a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,10 +13,12 @@ documentation = "https://docs.rs/etcd-client/" keywords = ["etcd", "v3", "api", "client", "async"] [features] -tls = ["tonic/tls-ring"] +tls-ring = ["tonic/tls-ring"] +tls-aws-lc = ["tonic/tls-aws-lc"] tls-openssl = ["openssl", "hyper-openssl", "hyper", "hyper-util"] tls-openssl-vendored = ["tls-openssl", "openssl/vendored"] -tls-roots = ["tls", "tonic/tls-native-roots"] +tls-native-roots = ["tonic/tls-native-roots"] +tls-webpki-roots = ["tonic/tls-webpki-roots"] pub-response-field = ["visible"] build-server = ["pub-response-field"] raw-channel = [] @@ -44,5 +46,5 @@ tonic-build = { version = "0.14", default-features = false } tonic-prost-build = "0.14" [package.metadata.docs.rs] -features = ["tls", "tls-roots"] +features = ["tls-ring", "tls-native-roots"] rustdoc-args = ["--cfg", "docsrs"] diff --git a/README.md b/README.md index 1387051..4c39204 100644 --- a/README.md +++ b/README.md @@ -86,9 +86,12 @@ Examples can be found in [`examples`](./examples). ## Feature Flags -- `tls`: Enables the `rustls`-based TLS connection. Not enabled by default. -- `tls-roots`: Adds system trust roots to `rustls`-based TLS connection using the +- `tls-ring`: Enables the `ring` backed `rustls`-based TLS connection. Not enabled by default. +- `tls-aws-lc`: Enables the `aws-lc-rs` backed `rustls`-based TLS connection. Not enabled by default. +- `tls-native-roots`: Adds system trust roots to `rustls`-based TLS connection using the `rustls-native-certs` crate. Not enabled by default. +- `tls-webpki-roots`: Adds Mozilla's trust roots to `rustls`-based TLS connection using the + `webpki-roots` crate. Not enabled by default. - `pub-response-field`: Exposes structs used to create regular `etcd-client` responses including internal protobuf representations. Useful for mocking. Not enabled by default. - `tls-openssl`: Enables the `openssl`-based TLS connections. This would make your binary diff --git a/src/client.rs b/src/client.rs index 623e82f..759eec0 100644 --- a/src/client.rs +++ b/src/client.rs @@ -39,7 +39,7 @@ use crate::rpc::maintenance::{ use crate::rpc::watch::{WatchClient, WatchOptions, WatchStream}; #[cfg(feature = "tls-openssl")] use crate::OpenSslResult; -#[cfg(feature = "tls")] +#[cfg(any(feature = "tls-ring", feature = "tls-aws-lc"))] use crate::TlsOptions; use http::uri::Uri; use tonic::metadata::{Ascii, MetadataValue}; @@ -159,7 +159,7 @@ impl Client { fn build_endpoint(url: &str, options: &ConnectOptions) -> Result { use tonic::transport::Channel as TonicChannel; let mut endpoint = if url.starts_with(HTTP_PREFIX) { - #[cfg(feature = "tls")] + #[cfg(any(feature = "tls-ring", feature = "tls-aws-lc"))] if options.tls.is_some() { return Err(Error::InvalidArgs(String::from( "TLS options are only supported with HTTPS URLs", @@ -168,23 +168,30 @@ impl Client { TonicChannel::builder(url.parse()?) } else if url.starts_with(HTTPS_PREFIX) { - #[cfg(not(any(feature = "tls", feature = "tls-openssl")))] + #[cfg(not(any( + feature = "tls-ring", + feature = "tls-aws-lc", + feature = "tls-openssl" + )))] return Err(Error::InvalidArgs(String::from( "HTTPS URLs are only supported with the feature \"tls\"", ))); - #[cfg(all(feature = "tls-openssl", not(feature = "tls")))] + #[cfg(all( + feature = "tls-openssl", + not(any(feature = "tls-ring", feature = "tls-aws-lc")) + ))] { TonicChannel::builder(url.parse()?) } - #[cfg(feature = "tls")] + #[cfg(any(feature = "tls-ring", feature = "tls-aws-lc"))] { let tls = options.tls.clone().unwrap_or_default(); TonicChannel::builder(url.parse()?).tls_config(tls)? } } else { - #[cfg(feature = "tls")] + #[cfg(any(feature = "tls-ring", feature = "tls-aws-lc"))] { let tls = options.tls.clone(); @@ -200,7 +207,10 @@ impl Client { } } - #[cfg(all(feature = "tls-openssl", not(feature = "tls")))] + #[cfg(all( + feature = "tls-openssl", + not(any(feature = "tls-ring", feature = "tls-aws-lc")) + ))] { let pfx = if options.otls.as_ref().is_some() { HTTPS_PREFIX @@ -211,7 +221,11 @@ impl Client { TonicChannel::builder(e.parse()?) } - #[cfg(all(not(feature = "tls"), not(feature = "tls-openssl")))] + #[cfg(all( + not(feature = "tls-ring"), + not(feature = "tls-aws-lc"), + not(feature = "tls-openssl") + ))] { let e = HTTP_PREFIX.to_owned() + url; TonicChannel::builder(e.parse()?) @@ -803,7 +817,7 @@ pub struct ConnectOptions { connect_timeout: Option, /// TCP keepalive. tcp_keepalive: Option, - #[cfg(feature = "tls")] + #[cfg(any(feature = "tls-ring", feature = "tls-aws-lc"))] tls: Option, #[cfg(feature = "tls-openssl")] otls: Option>, @@ -822,8 +836,8 @@ impl ConnectOptions { /// Sets TLS options. /// /// Notes that this function have to work with `HTTPS` URLs. - #[cfg_attr(docsrs, doc(cfg(feature = "tls")))] - #[cfg(feature = "tls")] + #[cfg_attr(docsrs, doc(cfg(any(feature = "tls-ring", feature = "tls-aws-lc"))))] + #[cfg(any(feature = "tls-ring", feature = "tls-aws-lc"))] #[inline] pub fn with_tls(mut self, tls: TlsOptions) -> Self { self.tls = Some(tls); @@ -899,7 +913,7 @@ impl ConnectOptions { timeout: None, connect_timeout: None, tcp_keepalive: None, - #[cfg(feature = "tls")] + #[cfg(any(feature = "tls-ring", feature = "tls-aws-lc"))] tls: None, #[cfg(feature = "tls-openssl")] otls: None, diff --git a/src/lib.rs b/src/lib.rs index ecb53f1..f6ed3c1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,8 +48,10 @@ //! //! # Feature Flags //! -//! - `tls`: Enables the `rustls`-based TLS connection. Not enabled by default. -//! - `tls-roots`: Adds system trust roots to `rustls`-based TLS connection using the `rustls-native-certs` crate. Not enabled by default. +//! - `tls-ring`: Enables the `ring` backed `rustls`-based TLS connection. Not enabled by default. +//! - `tls-aws-lc`: Enables the `aws-lc-rs` backed `rustls`-based TLS connection. Not enabled by default. +//! - `tls-native-roots`: Adds system trust roots to `rustls`-based TLS connection using the `rustls-native-certs` crate. Not enabled by default. +//! - `tls-webpki-roots`: Adds Mozilla's trust roots to `rustls`-based TLS connection using the `webpki-roots` crate. Not enabled by default. //! - `pub-response-field`: Exposes structs used to create regular `etcd-client` responses including internal protobuf representations. Useful for mocking. Not enabled by default. //! - `tls-openssl`: Enables the `openssl`-based TLS connections. This would make your binary dynamically link to `libssl`. //! - `tls-openssl-vendored`: Like `tls-openssl`, however compile openssl from source code and statically link to it. @@ -109,8 +111,8 @@ pub use crate::rpc::watch::{ }; pub use crate::rpc::{KeyValue, ResponseHeader}; -#[cfg(feature = "tls")] -#[cfg_attr(docsrs, doc(cfg(feature = "tls")))] +#[cfg(any(feature = "tls-ring", feature = "tls-aws-lc"))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "tls-ring", feature = "tls-aws-lc"))))] pub use tonic::transport::{Certificate, ClientTlsConfig as TlsOptions, Identity}; #[cfg(feature = "tls-openssl")] diff --git a/src/openssl_tls/transport.rs b/src/openssl_tls/transport.rs index f5dd206..4693915 100644 --- a/src/openssl_tls/transport.rs +++ b/src/openssl_tls/transport.rs @@ -45,9 +45,9 @@ impl OpenSslConnector { } } -#[cfg(feature = "tls")] +#[cfg(any(feature = "tls-ring", feature = "tls-aws-lc"))] compile_error!(concat!( - "**You should only enable one of `tls` and `tls-openssl`.** Reason: ", + "**You should only enable one of `tls-ring`, `tls-aws-lc` and `tls-openssl`.** Reason: ", "For now, `tls-openssl` would take over the transport layer (sockets) to implement TLS based connection. ", "As a result, once using with `tonic`'s internal TLS implementation (which based on `rustls`), ", "we may create TLS tunnels over TLS tunnels or directly fail because of some sorts of misconfiguration.")