1use std::{
2 net::{SocketAddr, ToSocketAddrs},
3 sync::Arc,
4};
5
6use rustls::{server::AllowAnyAuthenticatedClient, RootCertStore};
7
8#[derive(Debug, Clone, Default)]
9pub struct Load {
10 pub ca: String,
11 pub client_cert: String,
12 pub client_key: String,
13 pub server_cert: String,
14 pub server_key: String,
15}
16impl Load {
17 pub fn new() -> Self {
18 Self::default()
19 }
20
21 pub fn from_str(
22 ca: &str,
23 client_cert: &str,
24 client_key: &str,
25 server_cert: &str,
26 server_key: &str,
27 ) -> Self {
28 Self {
29 ca: ca.to_string(),
30 client_cert: client_cert.to_string(),
31 client_key: client_key.to_string(),
32 server_cert: server_cert.to_string(),
33 server_key: server_key.to_string(),
34 }
35 }
36
37 pub fn to_str(&self) -> (&str, &str, &str, &str, &str) {
38 (
39 &self.ca,
40 &self.client_cert,
41 &self.client_key,
42 &self.server_cert,
43 &self.server_key,
44 )
45 }
46
47 pub fn to_vec(&self) -> (&[u8], &[u8], &[u8], &[u8], &[u8]) {
48 let ca = self.ca.as_bytes();
49 let client_cert = self.client_cert.as_bytes();
50 let client_key = self.client_key.as_bytes();
51 let server_cert = self.server_cert.as_bytes();
52 let server_key = self.server_key.as_bytes();
53 (ca, client_cert, client_key, server_cert, server_key)
54 }
55
56 pub fn lookup_ipv4(host: &str, port: u16) -> SocketAddr {
60 let addrs = (host, port).to_socket_addrs().unwrap();
61 for addr in addrs {
62 if let SocketAddr::V4(_) = addr {
63 return addr;
64 }
65 }
66 unreachable!("Cannot lookup address");
67 }
68
69 fn load_certs(&self, load: &str) -> Vec<rustls::Certificate> {
70 vec![rustls::Certificate(load.as_bytes().to_vec())]
78 }
79
80 fn load_private_key(&self, load: &str) -> rustls::PrivateKey {
81 let buf = load.as_bytes().to_vec();
82 rustls::PrivateKey(buf)
83 }
84
85 pub fn to_ca(&self) -> Vec<rustls::Certificate> {
89 self.load_certs(self.ca.as_str())
90 }
91
92 pub fn to_ca_vec(&self) -> Vec<u8> {
93
94 self.ca.clone().into_bytes()
95 }
96
97 pub fn to_client_cert(&self) -> Vec<rustls::Certificate> {
98 self.load_certs(self.client_cert.as_str())
99 }
100
101 pub fn to_client_private_key(&self) -> rustls::PrivateKey {
102 self.load_private_key(self.client_key.as_str())
103 }
104
105 pub fn to_server_cert(&self) -> Vec<rustls::Certificate> {
106 self.load_certs(self.server_cert.as_str())
107 }
108
109 pub fn to_server_private_key(&self) -> rustls::PrivateKey {
110 self.load_private_key(self.server_key.as_str())
111 }
112
113 pub fn configure_server(
114 &self,
115 server_session_memory_cache: Option<usize>,
116 ) -> Arc<rustls::ServerConfig> {
117 let roots = self.to_server_cert();
118 let certs = roots;
119 let mut client_auth_roots = RootCertStore::empty();
120
121 client_auth_roots.add_parsable_certificates(&[self.server_cert.as_str().as_bytes().to_vec()]);
122
123 let client_auth = AllowAnyAuthenticatedClient::new(client_auth_roots);
124 let privkey = self.to_server_private_key();
125 let suites = rustls::ALL_CIPHER_SUITES.to_vec();
126 let versions = rustls::ALL_VERSIONS.to_vec();
127 let mut config = rustls::ServerConfig::builder()
128 .with_cipher_suites(&suites)
129 .with_safe_default_kx_groups()
130 .with_protocol_versions(&versions)
131 .expect("inconsistent cipher-suites/versions specified")
132 .with_client_cert_verifier(client_auth)
133 .with_single_cert_with_ocsp_and_sct(certs, privkey, vec![], vec![])
134 .expect("bad certificates/private key");
135
136 config.key_log = Arc::new(rustls::KeyLogFile::new());
137 if server_session_memory_cache.is_none() {
138 config.session_storage = rustls::server::ServerSessionMemoryCache::new(256);
139 } else {
140 config.session_storage =
141 rustls::server::ServerSessionMemoryCache::new(server_session_memory_cache.unwrap());
142 }
143 Arc::new(config)
144 }
145
146 pub fn configure_client(&self) -> Arc<rustls::ClientConfig> {
147 let cert_file = self.to_ca_vec();
148 let mut root_store = RootCertStore::empty();
149 root_store.add_parsable_certificates(&[cert_file]);
150
151 let suites = rustls::DEFAULT_CIPHER_SUITES.to_vec();
152 let versions = rustls::DEFAULT_VERSIONS.to_vec();
153
154 let certs = self.to_client_cert();
155 let key = self.to_client_private_key();
156
157 let config = rustls::ClientConfig::builder()
158 .with_cipher_suites(&suites)
159 .with_safe_default_kx_groups()
160 .with_protocol_versions(&versions)
161 .expect("inconsistent cipher-suite/versions selected")
162 .with_root_certificates(root_store)
163 .with_single_cert(certs, key)
164 .expect("invalid client auth certs/key");
165 Arc::new(config)
166 }
167}