diff --git a/tonic/Cargo.toml b/tonic/Cargo.toml index b400375ae..43c8fd83a 100644 --- a/tonic/Cargo.toml +++ b/tonic/Cargo.toml @@ -32,6 +32,7 @@ tls = ["dep:rustls-pemfile", "dep:tokio-rustls", "dep:tokio", "tokio?/rt", "toki tls-roots = ["tls-native-roots"] # Deprecated. Please use `tls-native-roots` instead. tls-native-roots = ["tls", "channel", "dep:rustls-native-certs"] tls-webpki-roots = ["tls", "channel", "dep:webpki-roots"] +tls-platform-verifier = ["tls", "channel", "dep:rustls-platform-verifier"] router = ["dep:axum", "dep:tower", "tower?/util"] server = [ "router", @@ -90,6 +91,7 @@ axum = {version = "0.7", default-features = false, optional = true} # rustls rustls-pemfile = { version = "2.0", optional = true } rustls-native-certs = { version = "0.8", optional = true } +rustls-platform-verifier = { version = "0.3", optional = true } tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "tls12", "ring"], optional = true } webpki-roots = { version = "0.26", optional = true } diff --git a/tonic/src/lib.rs b/tonic/src/lib.rs index 2ed0d220e..8d3ec8e37 100644 --- a/tonic/src/lib.rs +++ b/tonic/src/lib.rs @@ -31,6 +31,9 @@ //! [`rustls-native-certs`] crate. Not enabled by default. //! - `tls-webpki-roots`: Add the standard trust roots from the [`webpki-roots`] crate to //! `rustls`-based gRPC clients. Not enabled by default. +//! - `tls-platform-verifier`: Uses the operating system’s certificate facilities to verify +//! the validity of TLS certificates using the [`rustls-platform-verifier`] crate. Not +//! enabled by default. //! - `prost`: Enables the [`prost`] based gRPC [`Codec`] implementation. Enabled by default. //! - `gzip`: Enables compressing requests, responses, and streams. Depends on [`flate2`]. //! Not enabled by default. @@ -80,6 +83,7 @@ //! [`transport`]: transport/index.html //! [`rustls-native-certs`]: https://docs.rs/rustls-native-certs //! [`webpki-roots`]: https://docs.rs/webpki-roots +//! [`rustls-platform-verifier`]: https://docs.rs/rustls-platform-verifier //! [`flate2`]: https://docs.rs/flate2 //! [`zstd`]: https://docs.rs/zstd diff --git a/tonic/src/transport/channel/service/tls.rs b/tonic/src/transport/channel/service/tls.rs index efdd8dc91..c130243f2 100644 --- a/tonic/src/transport/channel/service/tls.rs +++ b/tonic/src/transport/channel/service/tls.rs @@ -32,6 +32,7 @@ impl TlsConnector { assume_http2: bool, #[cfg(feature = "tls-native-roots")] with_native_roots: bool, #[cfg(feature = "tls-webpki-roots")] with_webpki_roots: bool, + #[cfg(feature = "tls-platform-verifier")] with_platform_verifier: bool, ) -> Result { let builder = ClientConfig::builder(); let mut roots = RootCertStore::from_iter(trust_anchors); @@ -58,7 +59,20 @@ impl TlsConnector { add_certs_from_pem(&mut Cursor::new(cert), &mut roots)?; } + #[cfg(feature = "tls-platform-verifier")] + let builder = if with_platform_verifier { + builder + .dangerous() + .with_custom_certificate_verifier(Arc::new( + rustls_platform_verifier::Verifier::new_with_extra_roots(roots.roots), + )) + } else { + builder.with_root_certificates(roots) + }; + + #[cfg(not(feature = "tls-platform-verifier"))] let builder = builder.with_root_certificates(roots); + let mut config = match identity { Some(identity) => { let (client_cert, client_key) = load_identity(identity)?; diff --git a/tonic/src/transport/channel/tls.rs b/tonic/src/transport/channel/tls.rs index 03dd3b742..19afc608c 100644 --- a/tonic/src/transport/channel/tls.rs +++ b/tonic/src/transport/channel/tls.rs @@ -18,6 +18,8 @@ pub struct ClientTlsConfig { with_native_roots: bool, #[cfg(feature = "tls-webpki-roots")] with_webpki_roots: bool, + #[cfg(feature = "tls-platform-verifier")] + with_platform_verifier: bool, } impl ClientTlsConfig { @@ -102,6 +104,15 @@ impl ClientTlsConfig { } } + /// Enables the platform verifier. + #[cfg(feature = "tls-platform-verifier")] + pub fn with_platform_verifier(self) -> Self { + ClientTlsConfig { + with_platform_verifier: true, + ..self + } + } + /// Activates all TLS roots enabled through `tls-*-roots` feature flags pub fn with_enabled_roots(self) -> Self { let config = ClientTlsConfig::new(); @@ -127,6 +138,8 @@ impl ClientTlsConfig { self.with_native_roots, #[cfg(feature = "tls-webpki-roots")] self.with_webpki_roots, + #[cfg(feature = "tls-platform-verifier")] + self.with_platform_verifier, ) } }