1use std::fs::File;
19use std::io::{self, BufReader, Seek, Write};
20use std::net::SocketAddr;
21use std::path::Path;
22use std::sync::Arc;
23
24use rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier};
25use rustls::client::WebPkiServerVerifier;
26use rustls::crypto::{CryptoProvider, WebPkiSupportedAlgorithms};
27use rustls::pki_types::pem::PemObject;
28use rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer, ServerName, UnixTime};
29use rustls::{ClientConfig, DigitallySignedStruct, RootCertStore, ServerConfig};
30use tokio::net::{TcpListener, TcpStream};
31use tokio_rustls::client::TlsStream as ClientTlsStream;
32use tokio_rustls::server::TlsStream as ServerTlsStream;
33use tokio_rustls::{TlsAcceptor, TlsConnector};
34use tokio_util::codec::Framed;
35use tracing::{debug, error, info, instrument, warn};
36
37use crate::core::codec::PacketCodec;
38use crate::core::packet::Packet;
39use crate::error::{ProtocolError, Result};
40use crate::utils::timeout::HANDSHAKE_TIMEOUT;
41use futures::{SinkExt, StreamExt};
42
43#[derive(Debug)]
53struct CertificateFingerprint {
54 fingerprint: Vec<u8>,
55 supported_algs: WebPkiSupportedAlgorithms,
56}
57
58impl ServerCertVerifier for CertificateFingerprint {
59 fn verify_server_cert(
60 &self,
61 end_entity: &CertificateDer<'_>,
62 _intermediates: &[CertificateDer<'_>],
63 _server_name: &ServerName,
64 _ocsp_response: &[u8],
65 _now: UnixTime,
66 ) -> std::result::Result<ServerCertVerified, rustls::Error> {
67 use sha2::{Digest, Sha256};
68
69 let mut hasher = Sha256::new();
70 hasher.update(end_entity);
71 let hash = hasher.finalize();
72
73 if hash.as_slice() == self.fingerprint.as_slice() {
74 Ok(ServerCertVerified::assertion())
75 } else {
76 Err(rustls::Error::General(
77 "Pinned certificate hash mismatch".into(),
78 ))
79 }
80 }
81
82 fn verify_tls12_signature(
83 &self,
84 message: &[u8],
85 cert: &CertificateDer<'_>,
86 dss: &DigitallySignedStruct,
87 ) -> std::result::Result<HandshakeSignatureValid, rustls::Error> {
88 rustls::crypto::verify_tls12_signature(message, cert, dss, &self.supported_algs)
89 }
90
91 fn verify_tls13_signature(
92 &self,
93 message: &[u8],
94 cert: &CertificateDer<'_>,
95 dss: &DigitallySignedStruct,
96 ) -> std::result::Result<HandshakeSignatureValid, rustls::Error> {
97 rustls::crypto::verify_tls13_signature(message, cert, dss, &self.supported_algs)
98 }
99
100 fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
101 self.supported_algs.supported_schemes()
102 }
103}
104
105#[derive(Debug)]
109struct PinnedWebPkiVerifier {
110 inner: Arc<WebPkiServerVerifier>,
111 fingerprint: Vec<u8>,
112}
113
114impl ServerCertVerifier for PinnedWebPkiVerifier {
115 fn verify_server_cert(
116 &self,
117 end_entity: &CertificateDer<'_>,
118 intermediates: &[CertificateDer<'_>],
119 server_name: &ServerName,
120 ocsp_response: &[u8],
121 now: UnixTime,
122 ) -> std::result::Result<ServerCertVerified, rustls::Error> {
123 self.inner.verify_server_cert(
124 end_entity,
125 intermediates,
126 server_name,
127 ocsp_response,
128 now,
129 )?;
130 if TlsServerConfig::calculate_cert_hash(end_entity) == self.fingerprint {
131 Ok(ServerCertVerified::assertion())
132 } else {
133 Err(rustls::Error::General(
134 "Pinned certificate hash mismatch".into(),
135 ))
136 }
137 }
138
139 fn verify_tls12_signature(
140 &self,
141 message: &[u8],
142 cert: &CertificateDer<'_>,
143 dss: &DigitallySignedStruct,
144 ) -> std::result::Result<HandshakeSignatureValid, rustls::Error> {
145 self.inner.verify_tls12_signature(message, cert, dss)
146 }
147
148 fn verify_tls13_signature(
149 &self,
150 message: &[u8],
151 cert: &CertificateDer<'_>,
152 dss: &DigitallySignedStruct,
153 ) -> std::result::Result<HandshakeSignatureValid, rustls::Error> {
154 self.inner.verify_tls13_signature(message, cert, dss)
155 }
156
157 fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
158 self.inner.supported_verify_schemes()
159 }
160}
161
162#[derive(Debug)]
165struct AcceptAnyServerCert {
166 supported_algs: WebPkiSupportedAlgorithms,
167}
168
169impl ServerCertVerifier for AcceptAnyServerCert {
170 fn verify_server_cert(
171 &self,
172 _end_entity: &CertificateDer<'_>,
173 _intermediates: &[CertificateDer<'_>],
174 _server_name: &ServerName,
175 _ocsp_response: &[u8],
176 _now: UnixTime,
177 ) -> std::result::Result<ServerCertVerified, rustls::Error> {
178 Ok(ServerCertVerified::assertion())
179 }
180
181 fn verify_tls12_signature(
182 &self,
183 message: &[u8],
184 cert: &CertificateDer<'_>,
185 dss: &DigitallySignedStruct,
186 ) -> std::result::Result<HandshakeSignatureValid, rustls::Error> {
187 rustls::crypto::verify_tls12_signature(message, cert, dss, &self.supported_algs)
188 }
189
190 fn verify_tls13_signature(
191 &self,
192 message: &[u8],
193 cert: &CertificateDer<'_>,
194 dss: &DigitallySignedStruct,
195 ) -> std::result::Result<HandshakeSignatureValid, rustls::Error> {
196 rustls::crypto::verify_tls13_signature(message, cert, dss, &self.supported_algs)
197 }
198
199 fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
200 self.supported_algs.supported_schemes()
201 }
202}
203
204fn crypto_provider() -> Arc<CryptoProvider> {
210 Arc::new(rustls::crypto::ring::default_provider())
211}
212
213fn resolve_protocol_settings(
222 tls_versions: Option<&[TlsVersion]>,
223 cipher_suites: Option<&[rustls::SupportedCipherSuite]>,
224) -> Result<(
225 Arc<CryptoProvider>,
226 Vec<&'static rustls::SupportedProtocolVersion>,
227)> {
228 let versions: Vec<&'static rustls::SupportedProtocolVersion> = match tls_versions {
229 None => rustls::DEFAULT_VERSIONS.to_vec(),
230 Some(requested) => {
231 let mut has_tls13 = false;
232 let mut has_tls12 = false;
233 for v in requested {
234 match v {
235 TlsVersion::TLS12 => has_tls12 = true,
236 TlsVersion::TLS13 => has_tls13 = true,
237 TlsVersion::All => {
238 has_tls13 = true;
239 has_tls12 = true;
240 }
241 }
242 }
243 debug!(
244 "TLS versions requested: TLS1.2={}, TLS1.3={}",
245 has_tls12, has_tls13
246 );
247
248 let mut versions = Vec::with_capacity(2);
249 if has_tls13 {
250 versions.push(&rustls::version::TLS13);
251 }
252 if has_tls12 {
253 versions.push(&rustls::version::TLS12);
254 }
255 if versions.is_empty() {
256 return Err(ProtocolError::TlsError(
257 "No TLS protocol versions configured: with_tls_versions() was given an empty list"
258 .into(),
259 ));
260 }
261 versions
262 }
263 };
264
265 let mut provider = CryptoProvider::clone(&crypto_provider());
266 if let Some(requested) = cipher_suites {
267 for suite in requested {
268 if !provider
269 .cipher_suites
270 .iter()
271 .any(|s| s.suite() == suite.suite())
272 {
273 warn!(suite = ?suite.suite(), "Requested cipher suite is not supported and was ignored");
274 }
275 }
276 provider
277 .cipher_suites
278 .retain(|s| requested.iter().any(|r| r.suite() == s.suite()));
279 if provider.cipher_suites.is_empty() {
280 return Err(ProtocolError::TlsError(
281 "No supported cipher suites configured: none of the suites given to with_cipher_suites() are available"
282 .into(),
283 ));
284 }
285 debug!(
286 suites = ?provider.cipher_suites.iter().map(|s| s.suite()).collect::<Vec<_>>(),
287 "TLS cipher suites restricted"
288 );
289 }
290
291 if !provider
292 .cipher_suites
293 .iter()
294 .any(|s| versions.contains(&s.version()))
295 {
296 return Err(ProtocolError::TlsError(
297 "None of the configured cipher suites can be used with the configured TLS versions"
298 .into(),
299 ));
300 }
301
302 Ok((Arc::new(provider), versions))
303}
304
305fn load_private_key(reader: &mut BufReader<File>) -> Result<PrivateKeyDer<'static>> {
307 reader
310 .seek(std::io::SeekFrom::Start(0))
311 .map_err(ProtocolError::Io)?;
312
313 let keys: std::result::Result<Vec<_>, _> =
315 PrivatePkcs8KeyDer::pem_reader_iter(reader).collect();
316 let keys =
317 keys.map_err(|_| ProtocolError::TlsError("Failed to parse PKCS8 private key".into()))?;
318
319 if !keys.is_empty() {
320 return Ok(PrivateKeyDer::Pkcs8(keys[0].clone_key()));
321 }
322
323 Err(ProtocolError::TlsError(
326 "No supported private key found: the key file must hold a PEM \"PRIVATE KEY\" (PKCS#8) block"
327 .into(),
328 ))
329}
330
331pub enum TlsVersion {
333 TLS12,
335 TLS13,
337 All,
339}
340
341pub struct TlsServerConfig {
343 cert_path: String,
344 key_path: String,
345 client_ca_path: Option<String>,
347 require_client_auth: bool,
349 tls_versions: Option<Vec<TlsVersion>>,
351 cipher_suites: Option<Vec<rustls::SupportedCipherSuite>>,
353 alpn_protocols: Option<Vec<Vec<u8>>>,
355}
356
357impl TlsServerConfig {
358 pub fn new<P: AsRef<std::path::Path>>(cert_path: P, key_path: P) -> Self {
360 Self {
361 cert_path: cert_path.as_ref().to_string_lossy().to_string(),
362 key_path: key_path.as_ref().to_string_lossy().to_string(),
363 client_ca_path: None,
364 require_client_auth: false,
365 tls_versions: None,
366 cipher_suites: None,
367 alpn_protocols: Some(vec![b"h2".to_vec(), b"http/1.1".to_vec()]),
368 }
369 }
370
371 pub fn with_tls_versions(mut self, versions: Vec<TlsVersion>) -> Self {
376 self.tls_versions = Some(versions);
377 self
378 }
379
380 pub fn with_cipher_suites(mut self, cipher_suites: Vec<rustls::SupportedCipherSuite>) -> Self {
386 self.cipher_suites = Some(cipher_suites);
387 self
388 }
389
390 pub fn with_client_auth<S: Into<String>>(mut self, client_ca_path: S) -> Self {
392 self.client_ca_path = Some(client_ca_path.into());
393 self.require_client_auth = true;
394 self
395 }
396
397 pub fn require_client_auth(mut self, required: bool) -> Self {
408 self.require_client_auth = required;
409 self
410 }
411
412 pub fn with_alpn_protocols(mut self, protocols: Vec<Vec<u8>>) -> Self {
414 self.alpn_protocols = Some(protocols);
415 self
416 }
417
418 pub fn generate_self_signed<P: AsRef<Path>>(cert_path: P, key_path: P) -> io::Result<Self> {
420 let cert = rcgen::generate_simple_self_signed(vec!["localhost".into()])
421 .map_err(|e| io::Error::other(format!("Certificate generation error: {e}")))?;
422
423 let mut cert_file = File::create(&cert_path)?;
425 let pem = cert.cert.pem();
426 cert_file.write_all(pem.as_bytes())?;
427
428 let mut key_file = create_private_key_file(key_path.as_ref())?;
430 key_file.write_all(cert.signing_key.serialize_pem().as_bytes())?;
431
432 Ok(Self {
433 cert_path: cert_path.as_ref().to_string_lossy().to_string(),
434 key_path: key_path.as_ref().to_string_lossy().to_string(),
435 client_ca_path: None,
436 require_client_auth: false,
437 tls_versions: None,
438 cipher_suites: None,
439 alpn_protocols: Some(vec![b"h2".to_vec(), b"http/1.1".to_vec()]),
440 })
441 }
442
443 pub fn load_server_config(&self) -> Result<ServerConfig> {
450 if self.require_client_auth && self.client_ca_path.is_none() {
454 return Err(ProtocolError::TlsError(
455 "client authentication is required but no client CA is configured: call \
456 with_client_auth(\"<client-ca.pem>\") with the CA that signs client \
457 certificates, or drop require_client_auth(true)"
458 .into(),
459 ));
460 }
461
462 let cert_file = File::open(&self.cert_path)
464 .map_err(|e| ProtocolError::TlsError(format!("Failed to open cert file: {e}")))?;
465 let mut cert_reader = BufReader::new(cert_file);
466 let cert_chain: std::result::Result<Vec<_>, _> =
467 CertificateDer::pem_reader_iter(&mut cert_reader).collect();
468 let cert_chain: Vec<CertificateDer<'static>> = cert_chain
469 .map_err(|_| ProtocolError::TlsError("Failed to parse certificate".into()))?;
470
471 if cert_chain.is_empty() {
472 return Err(ProtocolError::TlsError("No certificates found".into()));
473 }
474
475 let key_file = File::open(&self.key_path)
477 .map_err(|e| ProtocolError::TlsError(format!("Failed to open key file: {e}")))?;
478 let mut key_reader = BufReader::new(key_file);
479 let private_key = load_private_key(&mut key_reader)?;
480
481 let (provider, versions) =
482 resolve_protocol_settings(self.tls_versions.as_deref(), self.cipher_suites.as_deref())?;
483 let config_builder = ServerConfig::builder_with_provider(provider.clone())
484 .with_protocol_versions(&versions)
485 .map_err(|e| {
486 ProtocolError::TlsError(format!("Failed to configure TLS protocol versions: {e}"))
487 })?;
488
489 let cert_builder = if let Some(client_ca_path) = &self.client_ca_path {
491 let client_ca_file = File::open(client_ca_path).map_err(|e| {
493 ProtocolError::TlsError(format!("Failed to open client CA file: {e}"))
494 })?;
495 let mut client_ca_reader = BufReader::new(client_ca_file);
496 let client_ca_certs: std::result::Result<Vec<_>, _> =
497 CertificateDer::pem_reader_iter(&mut client_ca_reader).collect();
498 let client_ca_certs: Vec<CertificateDer<'static>> = client_ca_certs.map_err(|_| {
499 ProtocolError::TlsError("Failed to parse client CA certificate".into())
500 })?;
501
502 if client_ca_certs.is_empty() {
503 return Err(ProtocolError::TlsError(
504 "No client CA certificates found".into(),
505 ));
506 }
507
508 let mut client_root_store = RootCertStore::empty();
510 for cert in client_ca_certs {
511 client_root_store.add(cert).map_err(|e| {
512 ProtocolError::TlsError(format!("Failed to add client CA cert: {e}"))
513 })?;
514 }
515
516 let mut verifier_builder = rustls::server::WebPkiClientVerifier::builder_with_provider(
520 Arc::new(client_root_store),
521 provider,
522 );
523 if !self.require_client_auth {
524 verifier_builder = verifier_builder.allow_unauthenticated();
527 }
528 let client_auth = verifier_builder.build().map_err(|e| {
529 ProtocolError::TlsError(format!("Failed to build client verifier: {e}"))
530 })?;
531
532 if self.require_client_auth {
533 debug!("mTLS enabled with client certificate verification required");
534 } else {
535 debug!("mTLS enabled with optional client certificate verification");
536 }
537 config_builder.with_client_cert_verifier(client_auth)
538 } else {
539 config_builder.with_no_client_auth()
540 };
541
542 let mut config = cert_builder
544 .with_single_cert(cert_chain, private_key)
545 .map_err(|e| ProtocolError::TlsError(format!("TLS error: {e}")))?;
546
547 if let Some(protocols) = &self.alpn_protocols {
549 config.alpn_protocols = protocols.clone();
550 debug!(
551 protocol_count = protocols.len(),
552 "ALPN protocols configured"
553 );
554 }
555
556 Ok(config)
557 }
558
559 pub fn calculate_cert_hash(cert: &CertificateDer<'_>) -> Vec<u8> {
561 use sha2::{Digest, Sha256};
562 let mut hasher = Sha256::new();
563 hasher.update(cert.as_ref());
564 hasher.finalize().to_vec()
565 }
566}
567
568pub struct TlsClientConfig {
570 server_name: String,
571 insecure: bool,
572 pinned_cert_hash: Option<Vec<u8>>,
574 client_cert_path: Option<String>,
576 client_key_path: Option<String>,
578 root_ca_path: Option<String>,
580 tls_versions: Option<Vec<TlsVersion>>,
582 cipher_suites: Option<Vec<rustls::SupportedCipherSuite>>,
584}
585
586const PIN_LEN: usize = 32;
588
589impl TlsClientConfig {
590 pub fn new<S: Into<String>>(server_name: S) -> Self {
592 Self {
593 server_name: server_name.into(),
594 insecure: false,
595 pinned_cert_hash: None,
596 client_cert_path: None,
597 client_key_path: None,
598 root_ca_path: None,
599 tls_versions: None,
600 cipher_suites: None,
601 }
602 }
603
604 pub fn with_tls_versions(mut self, versions: Vec<TlsVersion>) -> Self {
609 self.tls_versions = Some(versions);
610 self
611 }
612
613 pub fn with_cipher_suites(mut self, cipher_suites: Vec<rustls::SupportedCipherSuite>) -> Self {
619 self.cipher_suites = Some(cipher_suites);
620 self
621 }
622
623 pub fn with_root_ca<S: Into<String>>(mut self, ca_path: S) -> Self {
632 self.root_ca_path = Some(ca_path.into());
633 self
634 }
635
636 pub fn with_client_certificate<S: Into<String>>(mut self, cert_path: S, key_path: S) -> Self {
638 self.client_cert_path = Some(cert_path.into());
639 self.client_key_path = Some(key_path.into());
640 self
641 }
642
643 pub fn insecure(mut self) -> Self {
657 warn!("INSECURE MODE ENABLED: Certificate verification is disabled. This should only be used for development/testing.");
658 self.insecure = true;
659 self
660 }
661
662 pub fn with_pinned_cert_hash(mut self, hash: Vec<u8>) -> Self {
677 self.pinned_cert_hash = Some(hash);
678 self
679 }
680
681 pub fn load_client_config(&self) -> Result<ClientConfig> {
689 if let Some(hash) = &self.pinned_cert_hash {
690 if hash.len() != PIN_LEN {
691 return Err(ProtocolError::TlsError(format!(
692 "pinned certificate hash must be {PIN_LEN} bytes (the SHA-256 digest of the \
693 DER certificate), got {} bytes: compute it with \
694 TlsServerConfig::calculate_cert_hash(&cert)",
695 hash.len()
696 )));
697 }
698 }
699 if self.insecure && self.root_ca_path.is_some() {
700 return Err(ProtocolError::TlsError(
701 "with_root_ca() has no effect with insecure(), which skips CA validation: \
702 remove insecure() to validate against the CA, or remove with_root_ca()"
703 .into(),
704 ));
705 }
706 if self.insecure {
707 self.build_insecure_client_config()
708 } else {
709 self.build_secure_client_config()
710 }
711 }
712
713 fn client_config_builder(
715 &self,
716 ) -> Result<(
717 Arc<CryptoProvider>,
718 rustls::ConfigBuilder<ClientConfig, rustls::WantsVerifier>,
719 )> {
720 let (provider, versions) =
721 resolve_protocol_settings(self.tls_versions.as_deref(), self.cipher_suites.as_deref())?;
722 let builder = ClientConfig::builder_with_provider(provider.clone())
723 .with_protocol_versions(&versions)
724 .map_err(|e| {
725 ProtocolError::TlsError(format!("Failed to configure TLS protocol versions: {e}"))
726 })?;
727 Ok((provider, builder))
728 }
729
730 fn build_secure_client_config(&self) -> Result<ClientConfig> {
732 let (provider, builder) = self.client_config_builder()?;
733 let root_store = match &self.root_ca_path {
734 Some(path) => load_root_ca(path)?,
735 None => self.load_system_root_certificates()?,
736 };
737 let builder = match &self.pinned_cert_hash {
738 Some(hash) => {
741 let inner =
742 WebPkiServerVerifier::builder_with_provider(Arc::new(root_store), provider)
743 .build()
744 .map_err(|e| {
745 ProtocolError::TlsError(format!(
746 "Failed to build server certificate verifier: {e}"
747 ))
748 })?;
749 builder
750 .dangerous()
751 .with_custom_certificate_verifier(Arc::new(PinnedWebPkiVerifier {
752 inner,
753 fingerprint: hash.clone(),
754 }))
755 }
756 None => builder.with_root_certificates(root_store),
757 };
758
759 if let (Some(client_cert_path), Some(client_key_path)) =
761 (&self.client_cert_path, &self.client_key_path)
762 {
763 let (cert_chain, key) =
764 self.load_client_credentials(client_cert_path, client_key_path)?;
765 builder.with_client_auth_cert(cert_chain, key).map_err(|e| {
766 ProtocolError::TlsError(format!("Failed to set client certificate: {e}"))
767 })
768 } else {
769 Ok(builder.with_no_client_auth())
770 }
771 }
772
773 fn build_insecure_client_config(&self) -> Result<ClientConfig> {
775 let (provider, builder) = self.client_config_builder()?;
776 let verifier = self.create_custom_verifier(&provider);
777 let custom_builder = builder
778 .dangerous()
779 .with_custom_certificate_verifier(verifier);
780
781 if let (Some(client_cert_path), Some(client_key_path)) =
783 (&self.client_cert_path, &self.client_key_path)
784 {
785 let (cert_chain, key) =
786 self.load_client_credentials(client_cert_path, client_key_path)?;
787 custom_builder
788 .with_client_auth_cert(cert_chain, key)
789 .map_err(|e| {
790 ProtocolError::TlsError(format!("Failed to set client certificate: {e}"))
791 })
792 } else {
793 Ok(custom_builder.with_no_client_auth())
794 }
795 }
796
797 fn load_system_root_certificates(&self) -> Result<RootCertStore> {
799 let mut root_store = RootCertStore::empty();
800 let native_certs = rustls_native_certs::load_native_certs();
801 if let Some(e) = native_certs.errors.first() {
802 return Err(ProtocolError::TlsError(format!(
803 "Failed to load native certs: {e}"
804 )));
805 }
806
807 for cert in native_certs.certs {
808 root_store.add(cert).map_err(|e| {
809 ProtocolError::TlsError(format!("Failed to add cert to root store: {e}"))
810 })?;
811 }
812
813 if root_store.is_empty() {
814 return Err(ProtocolError::TlsError(
815 "No trusted root certificates found in the system store: install the system \
816 CA bundle, or trust a CA explicitly with with_root_ca(\"<ca.pem>\")"
817 .into(),
818 ));
819 }
820
821 Ok(root_store)
822 }
823
824 fn create_custom_verifier(&self, provider: &CryptoProvider) -> Arc<dyn ServerCertVerifier> {
828 let supported_algs = provider.signature_verification_algorithms;
829 if let Some(hash) = &self.pinned_cert_hash {
830 Arc::new(CertificateFingerprint {
831 fingerprint: hash.clone(),
832 supported_algs,
833 })
834 } else {
835 Arc::new(AcceptAnyServerCert { supported_algs })
836 }
837 }
838
839 fn load_client_credentials(
841 &self,
842 cert_path: &str,
843 key_path: &str,
844 ) -> Result<(Vec<CertificateDer<'static>>, PrivateKeyDer<'static>)> {
845 let cert_file = File::open(cert_path).map_err(ProtocolError::Io)?;
847 let mut cert_reader = BufReader::new(cert_file);
848 let certs_result: std::result::Result<Vec<_>, _> =
849 CertificateDer::pem_reader_iter(&mut cert_reader).collect();
850 let certs: Vec<CertificateDer<'static>> = certs_result
851 .map_err(|_| ProtocolError::TlsError("Failed to parse client certificate".into()))?;
852
853 if certs.is_empty() {
854 return Err(ProtocolError::TlsError(
855 "No client certificates found".into(),
856 ));
857 }
858
859 let key_file = File::open(key_path).map_err(ProtocolError::Io)?;
861 let mut key_reader = BufReader::new(key_file);
862 let key = load_private_key(&mut key_reader)?;
863
864 Ok((certs, key))
865 }
866
867 pub fn server_name(&self) -> Result<ServerName<'_>> {
869 ServerName::try_from(self.server_name.as_str())
870 .map_err(|_| ProtocolError::TlsError("Invalid server name".into()))
871 }
872
873 pub fn server_name_string(&self) -> String {
875 self.server_name.clone()
876 }
877
878 pub(crate) fn resumption_key(&self) -> String {
882 let versions = self.tls_versions.as_ref().map(|versions| {
883 versions
884 .iter()
885 .map(|v| match v {
886 TlsVersion::TLS12 => "1.2",
887 TlsVersion::TLS13 => "1.3",
888 TlsVersion::All => "all",
889 })
890 .collect::<Vec<_>>()
891 });
892 let suites = self
893 .cipher_suites
894 .as_ref()
895 .map(|suites| suites.iter().map(|s| s.suite()).collect::<Vec<_>>());
896 format!(
897 "{:?}|{}|{:?}|{:?}|{:?}|{:?}|{:?}|{:?}",
898 self.server_name,
899 self.insecure,
900 self.pinned_cert_hash,
901 self.client_cert_path,
902 self.client_key_path,
903 self.root_ca_path,
904 versions,
905 suites
906 )
907 }
908
909 pub(crate) fn owned_server_name(&self) -> Result<ServerName<'static>> {
912 ServerName::try_from(self.server_name.clone())
913 .map_err(|_| ProtocolError::TlsError("Invalid server name".into()))
914 }
915}
916
917fn load_root_ca(path: &str) -> Result<RootCertStore> {
919 let file = File::open(path)
920 .map_err(|e| ProtocolError::TlsError(format!("Failed to open root CA file: {e}")))?;
921 let mut reader = BufReader::new(file);
922 let certs: std::result::Result<Vec<_>, _> =
923 CertificateDer::pem_reader_iter(&mut reader).collect();
924 let certs =
925 certs.map_err(|_| ProtocolError::TlsError("Failed to parse root CA certificate".into()))?;
926 if certs.is_empty() {
927 return Err(ProtocolError::TlsError(
928 "No root CA certificates found".into(),
929 ));
930 }
931 let mut store = RootCertStore::empty();
932 for cert in certs {
933 store
934 .add(cert)
935 .map_err(|e| ProtocolError::TlsError(format!("Failed to add root CA cert: {e}")))?;
936 }
937 Ok(store)
938}
939
940fn create_private_key_file(path: &Path) -> io::Result<File> {
943 let mut options = std::fs::OpenOptions::new();
944 options.write(true).create(true).truncate(true);
945 #[cfg(unix)]
946 {
947 use std::os::unix::fs::OpenOptionsExt;
948 options.mode(0o600);
949 }
950 options.open(path)
951}
952
953#[instrument(skip(config))]
955pub async fn start_server(addr: &str, config: TlsServerConfig) -> Result<()> {
956 let tls_config = config.load_server_config()?;
957 let acceptor = TlsAcceptor::from(Arc::new(tls_config));
958 let listener = TcpListener::bind(addr).await?;
959
960 info!(address=%addr, "TLS server listening");
961
962 loop {
963 let (stream, peer) = listener.accept().await?;
964 let acceptor = acceptor.clone();
965
966 tokio::spawn(async move {
967 match tokio::time::timeout(HANDSHAKE_TIMEOUT, acceptor.accept(stream)).await {
970 Ok(Ok(tls_stream)) => {
971 if let Err(e) = handle_tls_connection(tls_stream, peer).await {
972 error!(%peer, error=%e, "Connection error");
973 }
974 }
975 Ok(Err(e)) => {
976 error!(%peer, error=%e, "TLS handshake failed");
977 }
978 Err(_) => {
979 warn!(%peer, "TLS handshake timed out");
980 }
981 }
982 });
983 }
984}
985
986#[instrument(skip(tls_stream), fields(peer=%peer))]
988async fn handle_tls_connection(
989 tls_stream: ServerTlsStream<TcpStream>,
990 peer: SocketAddr,
991) -> Result<()> {
992 let mut framed = Framed::new(tls_stream, PacketCodec);
993
994 info!("TLS connection established");
995
996 while let Some(packet) = framed.next().await {
997 match packet {
998 Ok(pkt) => {
999 debug!(bytes = pkt.payload.len(), "Received data");
1000 on_packet(pkt, &mut framed).await?;
1001 }
1002 Err(e) => {
1003 error!(error=%e, "Protocol error");
1004 break;
1005 }
1006 }
1007 }
1008
1009 info!("TLS connection closed");
1010 Ok(())
1011}
1012
1013#[instrument(skip(framed), fields(packet_version=pkt.version, payload_size=pkt.payload.len()))]
1015async fn on_packet<T>(pkt: Packet, framed: &mut Framed<T, PacketCodec>) -> Result<()>
1016where
1017 T: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin,
1018{
1019 let response = Packet {
1021 version: pkt.version,
1022 payload: pkt.payload,
1023 };
1024
1025 framed.send(response).await?;
1026 Ok(())
1027}
1028
1029pub async fn connect(
1031 addr: &str,
1032 config: TlsClientConfig,
1033) -> Result<Framed<ClientTlsStream<TcpStream>, PacketCodec>> {
1034 let tls_config = Arc::new(config.load_client_config()?);
1035 let connector = TlsConnector::from(tls_config);
1036
1037 let domain = config.owned_server_name()?;
1038
1039 let stream = TcpStream::connect(addr).await?;
1040
1041 let tls_stream = tokio::time::timeout(HANDSHAKE_TIMEOUT, connector.connect(domain, stream))
1042 .await
1043 .map_err(|_| ProtocolError::Timeout)?
1044 .map_err(|e| ProtocolError::TlsError(format!("TLS connection failed: {e}")))?;
1045
1046 let framed = Framed::new(tls_stream, PacketCodec);
1047 Ok(framed)
1048}