From 7a22238cad7ffeeb2d48ad60d55a8cadcad450d2 Mon Sep 17 00:00:00 2001 From: Alexei Pastuchov Date: Mon, 17 Feb 2025 15:18:52 +0100 Subject: [PATCH] WIP: Add support for Certificate verification with CRL --- examples/src/tls/server.rs | 2 +- examples/src/tls_client_auth/client.rs | 2 +- examples/src/tls_client_auth/server.rs | 2 +- interop/src/bin/server.rs | 2 +- tonic/Cargo.toml | 3 ++- tonic/src/transport/server/service/tls.rs | 8 ++++++-- tonic/src/transport/tls.rs | 6 ++++-- 7 files changed, 16 insertions(+), 9 deletions(-) diff --git a/examples/src/tls/server.rs b/examples/src/tls/server.rs index 5d2935fd8..23d0b9f6b 100644 --- a/examples/src/tls/server.rs +++ b/examples/src/tls/server.rs @@ -40,7 +40,7 @@ async fn main() -> Result<(), Box> { let cert = std::fs::read_to_string(data_dir.join("tls/server.pem"))?; let key = std::fs::read_to_string(data_dir.join("tls/server.key"))?; - let identity = Identity::from_pem(cert, key); + let identity = Identity::from_pem(cert, key, None); let addr = "[::1]:50051".parse().unwrap(); let server = EchoServer::default(); diff --git a/examples/src/tls_client_auth/client.rs b/examples/src/tls_client_auth/client.rs index 6670c67f5..ac2f243a3 100644 --- a/examples/src/tls_client_auth/client.rs +++ b/examples/src/tls_client_auth/client.rs @@ -12,7 +12,7 @@ async fn main() -> Result<(), Box> { let server_root_ca_cert = Certificate::from_pem(server_root_ca_cert); let client_cert = std::fs::read_to_string(data_dir.join("tls/client1.pem"))?; let client_key = std::fs::read_to_string(data_dir.join("tls/client1.key"))?; - let client_identity = Identity::from_pem(client_cert, client_key); + let client_identity = Identity::from_pem(client_cert, client_key, None); let tls = ClientTlsConfig::new() .domain_name("localhost") diff --git a/examples/src/tls_client_auth/server.rs b/examples/src/tls_client_auth/server.rs index 224620523..56998f25b 100644 --- a/examples/src/tls_client_auth/server.rs +++ b/examples/src/tls_client_auth/server.rs @@ -30,7 +30,7 @@ async fn main() -> Result<(), Box> { let data_dir = std::path::PathBuf::from_iter([std::env!("CARGO_MANIFEST_DIR"), "data"]); let cert = std::fs::read_to_string(data_dir.join("tls/server.pem"))?; let key = std::fs::read_to_string(data_dir.join("tls/server.key"))?; - let server_identity = Identity::from_pem(cert, key); + let server_identity = Identity::from_pem(cert, key, None); let client_ca_cert = std::fs::read_to_string(data_dir.join("tls/client_ca.pem"))?; let client_ca_cert = Certificate::from_pem(client_ca_cert); diff --git a/interop/src/bin/server.rs b/interop/src/bin/server.rs index bbc8f433f..082bed7c8 100644 --- a/interop/src/bin/server.rs +++ b/interop/src/bin/server.rs @@ -29,7 +29,7 @@ async fn main() -> std::result::Result<(), Box> { if matches.use_tls { let cert = std::fs::read_to_string("interop/data/server1.pem")?; let key = std::fs::read_to_string("interop/data/server1.key")?; - let identity = Identity::from_pem(cert, key); + let identity = Identity::from_pem(cert, key, None); builder = builder.tls_config(ServerTlsConfig::new().identity(identity))?; } diff --git a/tonic/Cargo.toml b/tonic/Cargo.toml index 33fe76af1..32b18344a 100644 --- a/tonic/Cargo.toml +++ b/tonic/Cargo.toml @@ -30,7 +30,7 @@ deflate = ["dep:flate2"] zstd = ["dep:zstd"] default = ["router", "transport", "codegen", "prost"] prost = ["dep:prost"] -_tls-any = ["dep:tokio-rustls", "dep:tokio", "tokio?/rt", "tokio?/macros"] # Internal. Please choose one of `tls-ring` or `tls-aws-lc` +_tls-any = ["dep:rustls-pki-types", "dep:tokio-rustls", "dep:tokio", "tokio?/rt", "tokio?/macros"] # Internal. Please choose one of `tls-ring` or `tls-aws-lc` tls-ring = ["_tls-any", "tokio-rustls/ring"] tls-aws-lc = ["_tls-any", "tokio-rustls/aws-lc-rs"] tls-native-roots = ["_tls-any", "channel", "dep:rustls-native-certs"] @@ -89,6 +89,7 @@ axum = {version = "0.8", default-features = false, optional = true} # rustls rustls-native-certs = { version = "0.8", optional = true } +rustls-pki-types = { version = "1.11", optional = true } tokio-rustls = { version = "0.26.1", default-features = false, features = ["logging", "tls12"], optional = true } webpki-roots = { version = "0.26", optional = true } diff --git a/tonic/src/transport/server/service/tls.rs b/tonic/src/transport/server/service/tls.rs index 0a24d9482..8562007dd 100644 --- a/tonic/src/transport/server/service/tls.rs +++ b/tonic/src/transport/server/service/tls.rs @@ -31,10 +31,14 @@ impl TlsAcceptor { Some(cert) => { let mut roots = RootCertStore::empty(); roots.add_parsable_certificates(convert_certificate_to_pki_types(cert)?); + let mut _builder = WebPkiClientVerifier::builder(roots.into()); + if let Some(crls) = &identity.crls { + _builder = _builder.with_crls(crls.clone()); + } let verifier = if client_auth_optional { - WebPkiClientVerifier::builder(roots.into()).allow_unauthenticated() + _builder.allow_unauthenticated() } else { - WebPkiClientVerifier::builder(roots.into()) + _builder } .build()?; builder.with_client_cert_verifier(verifier) diff --git a/tonic/src/transport/tls.rs b/tonic/src/transport/tls.rs index c2b7ef23f..8dd9fcabc 100644 --- a/tonic/src/transport/tls.rs +++ b/tonic/src/transport/tls.rs @@ -1,3 +1,4 @@ +use rustls_pki_types::CertificateRevocationListDer; /// Represents a X509 certificate. #[derive(Debug, Clone)] pub struct Certificate { @@ -9,6 +10,7 @@ pub struct Certificate { pub struct Identity { pub(crate) cert: Certificate, pub(crate) key: Vec, + pub(crate) crls: Option>>, } impl Certificate { @@ -52,9 +54,9 @@ impl Identity { /// Parse a PEM encoded certificate and private key. /// /// The provided cert must contain at least one PEM encoded certificate. - pub fn from_pem(cert: impl AsRef<[u8]>, key: impl AsRef<[u8]>) -> Self { + pub fn from_pem(cert: impl AsRef<[u8]>, key: impl AsRef<[u8]>, crls: Option>>) -> Self { let cert = Certificate::from_pem(cert); let key = key.as_ref().into(); - Self { cert, key } + Self { cert, crls, key } } }