tonic/transport/channel/
tls.rs

1use super::service::TlsConnector;
2use crate::transport::{
3    tls::{Certificate, Identity},
4    Error,
5};
6use http::Uri;
7use tokio_rustls::rustls::pki_types::TrustAnchor;
8
9/// Configures TLS settings for endpoints.
10#[derive(Debug, Clone, Default)]
11pub struct ClientTlsConfig {
12    domain: Option<String>,
13    certs: Vec<Certificate>,
14    trust_anchors: Vec<TrustAnchor<'static>>,
15    identity: Option<Identity>,
16    assume_http2: bool,
17    #[cfg(feature = "tls-native-roots")]
18    with_native_roots: bool,
19    #[cfg(feature = "tls-webpki-roots")]
20    with_webpki_roots: bool,
21}
22
23impl ClientTlsConfig {
24    /// Creates a new `ClientTlsConfig` using Rustls.
25    pub fn new() -> Self {
26        Self::default()
27    }
28
29    /// Sets the domain name against which to verify the server's TLS certificate.
30    pub fn domain_name(self, domain_name: impl Into<String>) -> Self {
31        ClientTlsConfig {
32            domain: Some(domain_name.into()),
33            ..self
34        }
35    }
36
37    /// Adds the CA Certificate against which to verify the server's TLS certificate.
38    pub fn ca_certificate(self, ca_certificate: Certificate) -> Self {
39        let mut certs = self.certs;
40        certs.push(ca_certificate);
41        ClientTlsConfig { certs, ..self }
42    }
43
44    /// Adds the multiple CA Certificates against which to verify the server's TLS certificate.
45    pub fn ca_certificates(self, ca_certificates: impl IntoIterator<Item = Certificate>) -> Self {
46        let mut certs = self.certs;
47        certs.extend(ca_certificates);
48        ClientTlsConfig { certs, ..self }
49    }
50
51    /// Adds the trust anchor which to verify the server's TLS certificate.
52    pub fn trust_anchor(self, trust_anchor: TrustAnchor<'static>) -> Self {
53        let mut trust_anchors = self.trust_anchors;
54        trust_anchors.push(trust_anchor);
55        ClientTlsConfig {
56            trust_anchors,
57            ..self
58        }
59    }
60
61    /// Adds the multiple trust anchors which to verify the server's TLS certificate.
62    pub fn trust_anchors(
63        mut self,
64        trust_anchors: impl IntoIterator<Item = TrustAnchor<'static>>,
65    ) -> Self {
66        self.trust_anchors.extend(trust_anchors);
67        self
68    }
69
70    /// Sets the client identity to present to the server.
71    pub fn identity(self, identity: Identity) -> Self {
72        ClientTlsConfig {
73            identity: Some(identity),
74            ..self
75        }
76    }
77
78    /// If true, the connector should assume that the server supports HTTP/2,
79    /// even if it doesn't provide protocol negotiation via ALPN.
80    pub fn assume_http2(self, assume_http2: bool) -> Self {
81        ClientTlsConfig {
82            assume_http2,
83            ..self
84        }
85    }
86
87    /// Enables the platform's trusted certs.
88    #[cfg(feature = "tls-native-roots")]
89    pub fn with_native_roots(self) -> Self {
90        ClientTlsConfig {
91            with_native_roots: true,
92            ..self
93        }
94    }
95
96    /// Enables the webpki roots.
97    #[cfg(feature = "tls-webpki-roots")]
98    pub fn with_webpki_roots(self) -> Self {
99        ClientTlsConfig {
100            with_webpki_roots: true,
101            ..self
102        }
103    }
104
105    /// Activates all TLS roots enabled through `tls-*-roots` feature flags
106    pub fn with_enabled_roots(self) -> Self {
107        let config = ClientTlsConfig::new();
108        #[cfg(feature = "tls-native-roots")]
109        let config = config.with_native_roots();
110        #[cfg(feature = "tls-webpki-roots")]
111        let config = config.with_webpki_roots();
112        config
113    }
114
115    pub(crate) fn into_tls_connector(self, uri: &Uri) -> Result<TlsConnector, crate::Error> {
116        let domain = match &self.domain {
117            Some(domain) => domain,
118            None => uri.host().ok_or_else(Error::new_invalid_uri)?,
119        };
120        TlsConnector::new(
121            self.certs,
122            self.trust_anchors,
123            self.identity,
124            domain,
125            self.assume_http2,
126            #[cfg(feature = "tls-native-roots")]
127            self.with_native_roots,
128            #[cfg(feature = "tls-webpki-roots")]
129            self.with_webpki_roots,
130        )
131    }
132}