tonic/transport/channel/
tls.rs

1use crate::transport::{
2    service::TlsConnector,
3    tls::{Certificate, Identity},
4    Error,
5};
6use http::Uri;
7use std::fmt;
8
9/// Configures TLS settings for endpoints.
10#[cfg(feature = "tls")]
11#[cfg_attr(docsrs, doc(cfg(feature = "tls")))]
12#[derive(Clone, Default)]
13pub struct ClientTlsConfig {
14    domain: Option<String>,
15    cert: Option<Certificate>,
16    identity: Option<Identity>,
17    rustls_raw: Option<tokio_rustls::rustls::ClientConfig>,
18}
19
20#[cfg(feature = "tls")]
21impl fmt::Debug for ClientTlsConfig {
22    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23        f.debug_struct("ClientTlsConfig")
24            .field("domain", &self.domain)
25            .field("cert", &self.cert)
26            .field("identity", &self.identity)
27            .finish()
28    }
29}
30
31#[cfg(feature = "tls")]
32impl ClientTlsConfig {
33    /// Creates a new `ClientTlsConfig` using Rustls.
34    pub fn new() -> Self {
35        ClientTlsConfig {
36            domain: None,
37            cert: None,
38            identity: None,
39            rustls_raw: None,
40        }
41    }
42
43    /// Sets the domain name against which to verify the server's TLS certificate.
44    pub fn domain_name(self, domain_name: impl Into<String>) -> Self {
45        ClientTlsConfig {
46            domain: Some(domain_name.into()),
47            ..self
48        }
49    }
50
51    /// Sets the CA Certificate against which to verify the server's TLS certificate.
52    ///
53    /// This has no effect if `rustls_client_config` is used to configure Rustls.
54    pub fn ca_certificate(self, ca_certificate: Certificate) -> Self {
55        ClientTlsConfig {
56            cert: Some(ca_certificate),
57            ..self
58        }
59    }
60
61    /// Sets the client identity to present to the server.
62    ///
63    /// This has no effect if `rustls_client_config` is used to configure Rustls.
64    pub fn identity(self, identity: Identity) -> Self {
65        ClientTlsConfig {
66            identity: Some(identity),
67            ..self
68        }
69    }
70
71    /// Use options specified by the given `ClientConfig` to configure TLS.
72    ///
73    /// This overrides all other TLS options set via other means.
74    pub fn rustls_client_config(self, config: tokio_rustls::rustls::ClientConfig) -> Self {
75        ClientTlsConfig {
76            rustls_raw: Some(config),
77            ..self
78        }
79    }
80
81    pub(crate) fn tls_connector(&self, uri: Uri) -> Result<TlsConnector, crate::Error> {
82        let domain = match &self.domain {
83            None => uri.host().ok_or_else(Error::new_invalid_uri)?.to_string(),
84            Some(domain) => domain.clone(),
85        };
86        match &self.rustls_raw {
87            None => {
88                TlsConnector::new_with_rustls_cert(self.cert.clone(), self.identity.clone(), domain)
89            }
90            Some(c) => TlsConnector::new_with_rustls_raw(c.clone(), domain),
91        }
92    }
93}