Skip to content

Commit

Permalink
feat(tls): add an option for optional TLS client authentication (#1163)
Browse files Browse the repository at this point in the history
* feat(tls): add an option for optional TLS client authentication

Previously there were only two options for client authentication –
either no authentication or mandatory authentication. With this change,
a server can allow for optional authentication with a given root CA
certificate and enforce client authentication on a per-request basis.

Refs: #687

* Update tonic/src/transport/server/tls.rs

---------

Co-authored-by: Lucio Franco <luciofranco14@gmail.com>
  • Loading branch information
dufkan and LucioFranco committed Feb 16, 2023
1 parent 2378581 commit 773e4e1
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
21 changes: 20 additions & 1 deletion tonic/src/transport/server/tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::fmt;
pub struct ServerTlsConfig {
identity: Option<Identity>,
client_ca_root: Option<Certificate>,
client_auth_optional: bool,
}

#[cfg(feature = "tls")]
Expand All @@ -27,6 +28,7 @@ impl ServerTlsConfig {
ServerTlsConfig {
identity: None,
client_ca_root: None,
client_auth_optional: false,
}
}

Expand All @@ -46,7 +48,24 @@ impl ServerTlsConfig {
}
}

/// Sets whether client certificate verification is optional.
///
/// This option has effect only if CA certificate is set.
///
/// # Default
/// By default, this option is set to `false`.
pub fn client_auth_optional(self, optional: bool) -> Self {
ServerTlsConfig {
client_auth_optional: optional,
..self
}
}

pub(crate) fn tls_acceptor(&self) -> Result<TlsAcceptor, crate::Error> {
TlsAcceptor::new(self.identity.clone().unwrap(), self.client_ca_root.clone())
TlsAcceptor::new(
self.identity.clone().unwrap(),
self.client_ca_root.clone(),
self.client_auth_optional,
)
}
}
14 changes: 11 additions & 3 deletions tonic/src/transport/service/tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,20 @@ impl TlsAcceptor {
pub(crate) fn new(
identity: Identity,
client_ca_root: Option<Certificate>,
client_auth_optional: bool,
) -> Result<Self, crate::Error> {
let builder = ServerConfig::builder().with_safe_defaults();

let builder = match client_ca_root {
None => builder.with_no_client_auth(),
Some(cert) => {
let builder = match (client_ca_root, client_auth_optional) {
(None, _) => builder.with_no_client_auth(),
(Some(cert), true) => {
use tokio_rustls::rustls::server::AllowAnyAnonymousOrAuthenticatedClient;
let mut roots = RootCertStore::empty();
rustls_keys::add_certs_from_pem(std::io::Cursor::new(&cert.pem[..]), &mut roots)?;
builder
.with_client_cert_verifier(AllowAnyAnonymousOrAuthenticatedClient::new(roots))
}
(Some(cert), false) => {
use tokio_rustls::rustls::server::AllowAnyAuthenticatedClient;
let mut roots = RootCertStore::empty();
rustls_keys::add_certs_from_pem(std::io::Cursor::new(&cert.pem[..]), &mut roots)?;
Expand Down

0 comments on commit 773e4e1

Please sign in to comment.