1use crate::cert::CertificateAuthority;
2use crate::error::{ProxyError, Result};
3use rustls::pki_types::{CertificateDer, PrivatePkcs8KeyDer};
4use rustls::server::WebPkiClientVerifier;
5use rustls::ServerConfig;
6use std::sync::Arc;
7use tokio::net::TcpStream;
8use tokio_rustls::TlsAcceptor;
9
10pub async fn make_tls_acceptor(
12 ca: &CertificateAuthority,
13 domain: &str,
14) -> Result<TlsAcceptor> {
15 let ck = ca.get_or_create_cert(domain).await?;
16
17 let config = ServerConfig::builder()
18 .with_no_client_auth()
19 .with_single_cert(
20 vec![ck.cert_der.clone()],
21 rustls::pki_types::PrivateKeyDer::Pkcs8(ck.key_der.clone_key()),
22 )?;
23
24 Ok(TlsAcceptor::from(Arc::new(config)))
25}
26
27pub async fn connect_tls_upstream(
29 host: &str,
30 addr: &str,
31) -> Result<tokio_rustls::client::TlsStream<TcpStream>> {
32 let tcp = TcpStream::connect(addr).await?;
33
34 let mut root_store = rustls::RootCertStore::empty();
35 root_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
36
37 let config = rustls::ClientConfig::builder()
38 .with_root_certificates(root_store)
39 .with_no_client_auth();
40
41 let connector = tokio_rustls::TlsConnector::from(Arc::new(config));
42 let server_name = rustls::pki_types::ServerName::try_from(host.to_string())
43 .map_err(|e| crate::error::ProxyError::Other(e.to_string()))?;
44
45 let tls_stream = connector.connect(server_name, tcp).await?;
46 Ok(tls_stream)
47}
48
49pub fn make_mtls_server_config(
51 server_cert_der: CertificateDer<'static>,
52 server_key_der: PrivatePkcs8KeyDer<'static>,
53 ca_cert_der: CertificateDer<'static>,
54) -> Result<Arc<ServerConfig>> {
55 let mut root_store = rustls::RootCertStore::empty();
56 root_store
57 .add(ca_cert_der)
58 .map_err(|e| ProxyError::Other(format!("Failed to add CA cert to root store: {e}")))?;
59
60 let client_verifier = WebPkiClientVerifier::builder(Arc::new(root_store))
61 .build()
62 .map_err(|e| ProxyError::Other(format!("Failed to build client verifier: {e}")))?;
63
64 let config = ServerConfig::builder()
65 .with_client_cert_verifier(client_verifier)
66 .with_single_cert(
67 vec![server_cert_der],
68 rustls::pki_types::PrivateKeyDer::Pkcs8(server_key_der),
69 )?;
70
71 Ok(Arc::new(config))
72}
73
74pub fn make_mtls_client_config(
76 client_cert_der: CertificateDer<'static>,
77 client_key_der: PrivatePkcs8KeyDer<'static>,
78 ca_cert_der: CertificateDer<'static>,
79) -> Result<Arc<rustls::ClientConfig>> {
80 let mut root_store = rustls::RootCertStore::empty();
81 root_store
82 .add(ca_cert_der)
83 .map_err(|e| ProxyError::Other(format!("Failed to add CA cert to root store: {e}")))?;
84
85 let config = rustls::ClientConfig::builder()
86 .with_root_certificates(root_store)
87 .with_client_auth_cert(
88 vec![client_cert_der],
89 rustls::pki_types::PrivateKeyDer::Pkcs8(client_key_der),
90 )
91 .map_err(ProxyError::Tls)?;
92
93 Ok(Arc::new(config))
94}