1use std::path::{Path, PathBuf};
4
5use tonic::transport::{Certificate, ClientTlsConfig, Identity, ServerTlsConfig};
6
7use crate::Error;
8
9#[derive(Clone, Debug)]
11pub struct TlsConfig {
12 pub cert: PathBuf,
14 pub key: PathBuf,
16 pub client_ca: Option<PathBuf>,
19}
20
21pub async fn server_tls(cfg: &TlsConfig) -> Result<ServerTlsConfig, Error> {
24 let (cert, key) = tokio::try_join!(tokio::fs::read(&cfg.cert), tokio::fs::read(&cfg.key))?;
25 let mut tls = ServerTlsConfig::new().identity(Identity::from_pem(cert, key));
26 if let Some(client_ca) = &cfg.client_ca {
27 let pem = tokio::fs::read(client_ca).await?;
28 tls = tls
29 .client_ca_root(Certificate::from_pem(pem))
30 .client_auth_optional(false);
31 }
32 Ok(tls)
33}
34
35pub async fn client_tls(
38 ca: &Path,
39 domain: &str,
40 identity: Option<(&Path, &Path)>,
41) -> Result<ClientTlsConfig, Error> {
42 let ca = Certificate::from_pem(tokio::fs::read(ca).await?);
43 let mut tls = ClientTlsConfig::new()
44 .ca_certificate(ca)
45 .domain_name(domain);
46 if let Some((cert, key)) = identity {
47 let (cert, key) = tokio::try_join!(tokio::fs::read(cert), tokio::fs::read(key))?;
48 tls = tls.identity(Identity::from_pem(cert, key));
49 }
50 Ok(tls)
51}