1use crate::util::{AnyTlsError, Result};
4use rustls::pki_types::{CertificateDer, PrivateKeyDer};
5use rustls::server::ServerConfig;
6use rustls::{ClientConfig, RootCertStore};
7use std::sync::Arc;
8use std::{fs::File, io::BufReader, path::Path};
9
10impl From<rustls::Error> for AnyTlsError {
11 fn from(err: rustls::Error) -> Self {
12 AnyTlsError::Tls(format!("rustls error: {}", err))
13 }
14}
15
16impl From<rcgen::Error> for AnyTlsError {
17 fn from(err: rcgen::Error) -> Self {
18 AnyTlsError::Tls(format!("rcgen error: {}", err))
19 }
20}
21
22pub fn generate_key_pair() -> Result<(CertificateDer<'static>, PrivateKeyDer<'static>)> {
30 generate_key_pair_with_name(None)
31}
32
33pub fn generate_key_pair_with_name(
35 server_name: Option<&str>,
36) -> Result<(CertificateDer<'static>, PrivateKeyDer<'static>)> {
37 let name = server_name.unwrap_or("localhost");
39
40 let subject_alt_names = vec![name.to_string(), "localhost".to_string()];
43 let certified_key = rcgen::generate_simple_self_signed(subject_alt_names)?;
44
45 let cert_der = certified_key.cert.der();
47 let key_der = certified_key.signing_key.serialize_der();
48
49 let cert_der_vec: Vec<u8> = cert_der.to_vec();
53 let cert_der: CertificateDer<'static> = cert_der_vec.into();
54 let key_der: PrivateKeyDer<'static> = PrivateKeyDer::Pkcs8(key_der.into());
55
56 Ok((cert_der, key_der))
57}
58
59pub fn create_server_config() -> Result<Arc<ServerConfig>> {
61 let (cert, key) = generate_key_pair()?;
62
63 let config = ServerConfig::builder()
64 .with_no_client_auth()
65 .with_single_cert(vec![cert], key)?;
66
67 Ok(Arc::new(config))
68}
69
70pub fn create_server_config_from_files<P: AsRef<Path>>(
72 cert_path: P,
73 key_path: P,
74) -> Result<Arc<ServerConfig>> {
75 let cert_file = File::open(&cert_path).map_err(AnyTlsError::Io)?;
76 let mut cert_reader = BufReader::new(cert_file);
77 let certs = rustls_pemfile::certs(&mut cert_reader)
78 .collect::<std::result::Result<Vec<_>, _>>()
79 .map_err(|e| AnyTlsError::Tls(format!("failed to parse certificate: {e}")))?;
80 if certs.is_empty() {
81 return Err(AnyTlsError::Tls(format!(
82 "no certificates found in {:?}",
83 cert_path.as_ref()
84 )));
85 }
86
87 let key_file = File::open(&key_path).map_err(AnyTlsError::Io)?;
88 let mut key_reader = BufReader::new(key_file);
89 let key = rustls_pemfile::private_key(&mut key_reader)
90 .map_err(|e| AnyTlsError::Tls(format!("failed to parse private key: {e}")))?
91 .ok_or_else(|| {
92 AnyTlsError::Tls(format!("no private key found in {:?}", key_path.as_ref()))
93 })?;
94
95 let config = ServerConfig::builder()
96 .with_no_client_auth()
97 .with_single_cert(certs, key)?;
98
99 Ok(Arc::new(config))
100}
101
102#[derive(Debug)]
105struct NoCertificateVerification;
106
107impl rustls::client::danger::ServerCertVerifier for NoCertificateVerification {
108 fn verify_server_cert(
109 &self,
110 _end_entity: &rustls::pki_types::CertificateDer<'_>,
111 _intermediates: &[rustls::pki_types::CertificateDer<'_>],
112 _server_name: &rustls::pki_types::ServerName<'_>,
113 _ocsp_response: &[u8],
114 _now: rustls::pki_types::UnixTime,
115 ) -> std::result::Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
116 Ok(rustls::client::danger::ServerCertVerified::assertion())
119 }
120
121 fn verify_tls12_signature(
122 &self,
123 _message: &[u8],
124 _cert: &rustls::pki_types::CertificateDer<'_>,
125 _dss: &rustls::DigitallySignedStruct,
126 ) -> std::result::Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
127 Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
128 }
129
130 fn verify_tls13_signature(
131 &self,
132 _message: &[u8],
133 _cert: &rustls::pki_types::CertificateDer<'_>,
134 _dss: &rustls::DigitallySignedStruct,
135 ) -> std::result::Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
136 Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
137 }
138
139 fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
140 vec![
142 rustls::SignatureScheme::RSA_PKCS1_SHA256,
143 rustls::SignatureScheme::RSA_PKCS1_SHA384,
144 rustls::SignatureScheme::RSA_PKCS1_SHA512,
145 rustls::SignatureScheme::ECDSA_NISTP256_SHA256,
146 rustls::SignatureScheme::ECDSA_NISTP384_SHA384,
147 rustls::SignatureScheme::ECDSA_NISTP521_SHA512,
148 rustls::SignatureScheme::RSA_PSS_SHA256,
149 rustls::SignatureScheme::RSA_PSS_SHA384,
150 rustls::SignatureScheme::RSA_PSS_SHA512,
151 rustls::SignatureScheme::ED25519,
152 rustls::SignatureScheme::ED448,
153 ]
154 }
155}
156
157pub fn create_client_config() -> Result<Arc<ClientConfig>> {
160 let root_store = RootCertStore::empty();
161
162 let mut config = ClientConfig::builder()
166 .with_root_certificates(root_store)
167 .with_no_client_auth();
168
169 config
171 .dangerous()
172 .set_certificate_verifier(Arc::new(NoCertificateVerification));
173
174 Ok(Arc::new(config))
175}
176
177#[cfg(test)]
178mod tests {
179 use super::*;
180
181 #[test]
182 fn test_create_client_config() {
183 let config = create_client_config().unwrap();
184 assert!(Arc::strong_count(&config) >= 1);
186 }
187
188 #[test]
189 fn test_generate_key_pair() {
190 let (cert, key) = generate_key_pair().unwrap();
192 assert!(!cert.as_ref().is_empty());
193 match &key {
194 PrivateKeyDer::Pkcs8(data) => assert!(!data.secret_pkcs8_der().is_empty()),
195 PrivateKeyDer::Pkcs1(data) => assert!(!data.secret_pkcs1_der().is_empty()),
196 PrivateKeyDer::Sec1(data) => assert!(!data.secret_sec1_der().is_empty()),
197 _ => panic!("Unexpected key type"),
198 }
199 }
200
201 #[test]
202 fn test_generate_key_pair_with_name() {
203 let (cert, key) = generate_key_pair_with_name(Some("example.com")).unwrap();
204 assert!(!cert.as_ref().is_empty());
205 match &key {
206 PrivateKeyDer::Pkcs8(data) => assert!(!data.secret_pkcs8_der().is_empty()),
207 PrivateKeyDer::Pkcs1(data) => assert!(!data.secret_pkcs1_der().is_empty()),
208 PrivateKeyDer::Sec1(data) => assert!(!data.secret_sec1_der().is_empty()),
209 _ => panic!("Unexpected key type"),
210 }
211 }
212
213 #[test]
214 fn test_create_server_config() {
215 let config = create_server_config().unwrap();
217 assert!(Arc::strong_count(&config) >= 1);
218 }
219}