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::crypto::{CryptoProvider, WebPkiSupportedAlgorithms};
26use rustls::pki_types::pem::PemObject;
27use rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer, ServerName, UnixTime};
28use rustls::{ClientConfig, DigitallySignedStruct, RootCertStore, ServerConfig};
29use tokio::net::{TcpListener, TcpStream};
30use tokio_rustls::client::TlsStream as ClientTlsStream;
31use tokio_rustls::server::TlsStream as ServerTlsStream;
32use tokio_rustls::{TlsAcceptor, TlsConnector};
33use tokio_util::codec::Framed;
34use tracing::{debug, error, info, instrument, warn};
35
36use crate::core::codec::PacketCodec;
37use crate::core::packet::Packet;
38use crate::error::{ProtocolError, Result};
39use futures::{SinkExt, StreamExt};
40
41#[derive(Debug)]
51struct CertificateFingerprint {
52 fingerprint: Vec<u8>,
53 supported_algs: WebPkiSupportedAlgorithms,
54}
55
56impl ServerCertVerifier for CertificateFingerprint {
57 fn verify_server_cert(
58 &self,
59 end_entity: &CertificateDer<'_>,
60 _intermediates: &[CertificateDer<'_>],
61 _server_name: &ServerName,
62 _ocsp_response: &[u8],
63 _now: UnixTime,
64 ) -> std::result::Result<ServerCertVerified, rustls::Error> {
65 use sha2::{Digest, Sha256};
66
67 let mut hasher = Sha256::new();
68 hasher.update(end_entity);
69 let hash = hasher.finalize();
70
71 if hash.as_slice() == self.fingerprint.as_slice() {
72 Ok(ServerCertVerified::assertion())
73 } else {
74 Err(rustls::Error::General(
75 "Pinned certificate hash mismatch".into(),
76 ))
77 }
78 }
79
80 fn verify_tls12_signature(
81 &self,
82 message: &[u8],
83 cert: &CertificateDer<'_>,
84 dss: &DigitallySignedStruct,
85 ) -> std::result::Result<HandshakeSignatureValid, rustls::Error> {
86 rustls::crypto::verify_tls12_signature(message, cert, dss, &self.supported_algs)
87 }
88
89 fn verify_tls13_signature(
90 &self,
91 message: &[u8],
92 cert: &CertificateDer<'_>,
93 dss: &DigitallySignedStruct,
94 ) -> std::result::Result<HandshakeSignatureValid, rustls::Error> {
95 rustls::crypto::verify_tls13_signature(message, cert, dss, &self.supported_algs)
96 }
97
98 fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
99 self.supported_algs.supported_schemes()
100 }
101}
102
103#[derive(Debug)]
106struct AcceptAnyServerCert {
107 supported_algs: WebPkiSupportedAlgorithms,
108}
109
110impl ServerCertVerifier for AcceptAnyServerCert {
111 fn verify_server_cert(
112 &self,
113 _end_entity: &CertificateDer<'_>,
114 _intermediates: &[CertificateDer<'_>],
115 _server_name: &ServerName,
116 _ocsp_response: &[u8],
117 _now: UnixTime,
118 ) -> std::result::Result<ServerCertVerified, rustls::Error> {
119 Ok(ServerCertVerified::assertion())
120 }
121
122 fn verify_tls12_signature(
123 &self,
124 message: &[u8],
125 cert: &CertificateDer<'_>,
126 dss: &DigitallySignedStruct,
127 ) -> std::result::Result<HandshakeSignatureValid, rustls::Error> {
128 rustls::crypto::verify_tls12_signature(message, cert, dss, &self.supported_algs)
129 }
130
131 fn verify_tls13_signature(
132 &self,
133 message: &[u8],
134 cert: &CertificateDer<'_>,
135 dss: &DigitallySignedStruct,
136 ) -> std::result::Result<HandshakeSignatureValid, rustls::Error> {
137 rustls::crypto::verify_tls13_signature(message, cert, dss, &self.supported_algs)
138 }
139
140 fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
141 self.supported_algs.supported_schemes()
142 }
143}
144
145fn crypto_provider() -> Arc<CryptoProvider> {
151 Arc::new(rustls::crypto::ring::default_provider())
152}
153
154fn resolve_protocol_settings(
163 tls_versions: Option<&[TlsVersion]>,
164 cipher_suites: Option<&[rustls::SupportedCipherSuite]>,
165) -> Result<(
166 Arc<CryptoProvider>,
167 Vec<&'static rustls::SupportedProtocolVersion>,
168)> {
169 let versions: Vec<&'static rustls::SupportedProtocolVersion> = match tls_versions {
170 None => rustls::DEFAULT_VERSIONS.to_vec(),
171 Some(requested) => {
172 let mut has_tls13 = false;
173 let mut has_tls12 = false;
174 for v in requested {
175 match v {
176 TlsVersion::TLS12 => has_tls12 = true,
177 TlsVersion::TLS13 => has_tls13 = true,
178 TlsVersion::All => {
179 has_tls13 = true;
180 has_tls12 = true;
181 }
182 }
183 }
184 debug!(
185 "TLS versions requested: TLS1.2={}, TLS1.3={}",
186 has_tls12, has_tls13
187 );
188
189 let mut versions = Vec::with_capacity(2);
190 if has_tls13 {
191 versions.push(&rustls::version::TLS13);
192 }
193 if has_tls12 {
194 versions.push(&rustls::version::TLS12);
195 }
196 if versions.is_empty() {
197 return Err(ProtocolError::TlsError(
198 "No TLS protocol versions configured: with_tls_versions() was given an empty list"
199 .into(),
200 ));
201 }
202 versions
203 }
204 };
205
206 let mut provider = CryptoProvider::clone(&crypto_provider());
207 if let Some(requested) = cipher_suites {
208 for suite in requested {
209 if !provider
210 .cipher_suites
211 .iter()
212 .any(|s| s.suite() == suite.suite())
213 {
214 warn!(suite = ?suite.suite(), "Requested cipher suite is not supported and was ignored");
215 }
216 }
217 provider
218 .cipher_suites
219 .retain(|s| requested.iter().any(|r| r.suite() == s.suite()));
220 if provider.cipher_suites.is_empty() {
221 return Err(ProtocolError::TlsError(
222 "No supported cipher suites configured: none of the suites given to with_cipher_suites() are available"
223 .into(),
224 ));
225 }
226 debug!(
227 suites = ?provider.cipher_suites.iter().map(|s| s.suite()).collect::<Vec<_>>(),
228 "TLS cipher suites restricted"
229 );
230 }
231
232 if !provider
233 .cipher_suites
234 .iter()
235 .any(|s| versions.contains(&s.version()))
236 {
237 return Err(ProtocolError::TlsError(
238 "None of the configured cipher suites can be used with the configured TLS versions"
239 .into(),
240 ));
241 }
242
243 Ok((Arc::new(provider), versions))
244}
245
246fn load_private_key(reader: &mut BufReader<File>) -> Result<PrivateKeyDer<'static>> {
248 reader
251 .seek(std::io::SeekFrom::Start(0))
252 .map_err(ProtocolError::Io)?;
253
254 let keys: std::result::Result<Vec<_>, _> =
256 PrivatePkcs8KeyDer::pem_reader_iter(reader).collect();
257 let keys =
258 keys.map_err(|_| ProtocolError::TlsError("Failed to parse PKCS8 private key".into()))?;
259
260 if !keys.is_empty() {
261 return Ok(PrivateKeyDer::Pkcs8(keys[0].clone_key()));
262 }
263
264 Err(ProtocolError::TlsError(
267 "No supported private key format found".into(),
268 ))
269}
270
271pub enum TlsVersion {
273 TLS12,
275 TLS13,
277 All,
279}
280
281pub struct TlsServerConfig {
283 cert_path: String,
284 key_path: String,
285 client_ca_path: Option<String>,
287 require_client_auth: bool,
289 tls_versions: Option<Vec<TlsVersion>>,
291 cipher_suites: Option<Vec<rustls::SupportedCipherSuite>>,
293 alpn_protocols: Option<Vec<Vec<u8>>>,
295}
296
297impl TlsServerConfig {
298 pub fn new<P: AsRef<std::path::Path>>(cert_path: P, key_path: P) -> Self {
300 Self {
301 cert_path: cert_path.as_ref().to_string_lossy().to_string(),
302 key_path: key_path.as_ref().to_string_lossy().to_string(),
303 client_ca_path: None,
304 require_client_auth: false,
305 tls_versions: None,
306 cipher_suites: None,
307 alpn_protocols: Some(vec![b"h2".to_vec(), b"http/1.1".to_vec()]),
308 }
309 }
310
311 pub fn with_tls_versions(mut self, versions: Vec<TlsVersion>) -> Self {
316 self.tls_versions = Some(versions);
317 self
318 }
319
320 pub fn with_cipher_suites(mut self, cipher_suites: Vec<rustls::SupportedCipherSuite>) -> Self {
326 self.cipher_suites = Some(cipher_suites);
327 self
328 }
329
330 pub fn with_client_auth<S: Into<String>>(mut self, client_ca_path: S) -> Self {
332 self.client_ca_path = Some(client_ca_path.into());
333 self.require_client_auth = true;
334 self
335 }
336
337 pub fn require_client_auth(mut self, required: bool) -> Self {
343 self.require_client_auth = required;
344 self
345 }
346
347 pub fn with_alpn_protocols(mut self, protocols: Vec<Vec<u8>>) -> Self {
349 self.alpn_protocols = Some(protocols);
350 self
351 }
352
353 pub fn generate_self_signed<P: AsRef<Path>>(cert_path: P, key_path: P) -> io::Result<Self> {
355 let cert = rcgen::generate_simple_self_signed(vec!["localhost".into()])
356 .map_err(|e| io::Error::other(format!("Certificate generation error: {e}")))?;
357
358 let mut cert_file = File::create(&cert_path)?;
360 let pem = cert.cert.pem();
361 cert_file.write_all(pem.as_bytes())?;
362
363 let mut key_file = File::create(&key_path)?;
365 key_file.write_all(cert.signing_key.serialize_pem().as_bytes())?;
366
367 Ok(Self {
368 cert_path: cert_path.as_ref().to_string_lossy().to_string(),
369 key_path: key_path.as_ref().to_string_lossy().to_string(),
370 client_ca_path: None,
371 require_client_auth: false,
372 tls_versions: None,
373 cipher_suites: None,
374 alpn_protocols: Some(vec![b"h2".to_vec(), b"http/1.1".to_vec()]),
375 })
376 }
377
378 pub fn load_server_config(&self) -> Result<ServerConfig> {
380 let cert_file = File::open(&self.cert_path)
382 .map_err(|e| ProtocolError::TlsError(format!("Failed to open cert file: {e}")))?;
383 let mut cert_reader = BufReader::new(cert_file);
384 let cert_chain: std::result::Result<Vec<_>, _> =
385 CertificateDer::pem_reader_iter(&mut cert_reader).collect();
386 let cert_chain: Vec<CertificateDer<'static>> = cert_chain
387 .map_err(|_| ProtocolError::TlsError("Failed to parse certificate".into()))?;
388
389 if cert_chain.is_empty() {
390 return Err(ProtocolError::TlsError("No certificates found".into()));
391 }
392
393 let key_file = File::open(&self.key_path)
395 .map_err(|e| ProtocolError::TlsError(format!("Failed to open key file: {e}")))?;
396 let mut key_reader = BufReader::new(key_file);
397 let private_key = load_private_key(&mut key_reader)?;
398
399 let (provider, versions) =
400 resolve_protocol_settings(self.tls_versions.as_deref(), self.cipher_suites.as_deref())?;
401 let config_builder = ServerConfig::builder_with_provider(provider.clone())
402 .with_protocol_versions(&versions)
403 .map_err(|e| {
404 ProtocolError::TlsError(format!("Failed to configure TLS protocol versions: {e}"))
405 })?;
406
407 let cert_builder = if let Some(client_ca_path) = &self.client_ca_path {
409 let client_ca_file = File::open(client_ca_path).map_err(|e| {
411 ProtocolError::TlsError(format!("Failed to open client CA file: {e}"))
412 })?;
413 let mut client_ca_reader = BufReader::new(client_ca_file);
414 let client_ca_certs: std::result::Result<Vec<_>, _> =
415 CertificateDer::pem_reader_iter(&mut client_ca_reader).collect();
416 let client_ca_certs: Vec<CertificateDer<'static>> = client_ca_certs.map_err(|_| {
417 ProtocolError::TlsError("Failed to parse client CA certificate".into())
418 })?;
419
420 if client_ca_certs.is_empty() {
421 return Err(ProtocolError::TlsError(
422 "No client CA certificates found".into(),
423 ));
424 }
425
426 let mut client_root_store = RootCertStore::empty();
428 for cert in client_ca_certs {
429 client_root_store.add(cert).map_err(|e| {
430 ProtocolError::TlsError(format!("Failed to add client CA cert: {e}"))
431 })?;
432 }
433
434 let mut verifier_builder = rustls::server::WebPkiClientVerifier::builder_with_provider(
438 Arc::new(client_root_store),
439 provider,
440 );
441 if !self.require_client_auth {
442 verifier_builder = verifier_builder.allow_unauthenticated();
445 }
446 let client_auth = verifier_builder.build().map_err(|e| {
447 ProtocolError::TlsError(format!("Failed to build client verifier: {e}"))
448 })?;
449
450 if self.require_client_auth {
451 debug!("mTLS enabled with client certificate verification required");
452 } else {
453 debug!("mTLS enabled with optional client certificate verification");
454 }
455 config_builder.with_client_cert_verifier(client_auth)
456 } else {
457 config_builder.with_no_client_auth()
458 };
459
460 let mut config = cert_builder
462 .with_single_cert(cert_chain, private_key)
463 .map_err(|e| ProtocolError::TlsError(format!("TLS error: {e}")))?;
464
465 if let Some(protocols) = &self.alpn_protocols {
467 config.alpn_protocols = protocols.clone();
468 debug!(
469 protocol_count = protocols.len(),
470 "ALPN protocols configured"
471 );
472 }
473
474 Ok(config)
475 }
476
477 pub fn calculate_cert_hash(cert: &CertificateDer<'_>) -> Vec<u8> {
479 use sha2::{Digest, Sha256};
480 let mut hasher = Sha256::new();
481 hasher.update(cert.as_ref());
482 hasher.finalize().to_vec()
483 }
484}
485
486pub struct TlsClientConfig {
488 server_name: String,
489 insecure: bool,
490 pinned_cert_hash: Option<Vec<u8>>,
492 client_cert_path: Option<String>,
494 client_key_path: Option<String>,
496 tls_versions: Option<Vec<TlsVersion>>,
498 cipher_suites: Option<Vec<rustls::SupportedCipherSuite>>,
500}
501
502impl TlsClientConfig {
503 pub fn new<S: Into<String>>(server_name: S) -> Self {
505 Self {
506 server_name: server_name.into(),
507 insecure: false,
508 pinned_cert_hash: None,
509 client_cert_path: None,
510 client_key_path: None,
511 tls_versions: None,
512 cipher_suites: None,
513 }
514 }
515
516 pub fn with_tls_versions(mut self, versions: Vec<TlsVersion>) -> Self {
521 self.tls_versions = Some(versions);
522 self
523 }
524
525 pub fn with_cipher_suites(mut self, cipher_suites: Vec<rustls::SupportedCipherSuite>) -> Self {
531 self.cipher_suites = Some(cipher_suites);
532 self
533 }
534
535 pub fn with_client_certificate<S: Into<String>>(mut self, cert_path: S, key_path: S) -> Self {
537 self.client_cert_path = Some(cert_path.into());
538 self.client_key_path = Some(key_path.into());
539 self
540 }
541
542 pub fn insecure(mut self) -> Self {
558 warn!("INSECURE MODE ENABLED: Certificate verification is disabled. This should only be used for development/testing.");
559 self.insecure = true;
560 self
561 }
562
563 pub fn with_pinned_cert_hash(mut self, hash: Vec<u8>) -> Self {
572 if hash.len() != 32 {
573 warn!(
574 "Certificate hash has unexpected length: {} (expected 32 bytes for SHA-256)",
575 hash.len()
576 );
577 }
578 self.pinned_cert_hash = Some(hash);
579 self
580 }
581
582 pub fn load_client_config(&self) -> Result<ClientConfig> {
584 if self.insecure {
585 self.build_insecure_client_config()
586 } else {
587 self.build_secure_client_config()
588 }
589 }
590
591 fn client_config_builder(
593 &self,
594 ) -> Result<(
595 Arc<CryptoProvider>,
596 rustls::ConfigBuilder<ClientConfig, rustls::WantsVerifier>,
597 )> {
598 let (provider, versions) =
599 resolve_protocol_settings(self.tls_versions.as_deref(), self.cipher_suites.as_deref())?;
600 let builder = ClientConfig::builder_with_provider(provider.clone())
601 .with_protocol_versions(&versions)
602 .map_err(|e| {
603 ProtocolError::TlsError(format!("Failed to configure TLS protocol versions: {e}"))
604 })?;
605 Ok((provider, builder))
606 }
607
608 fn build_secure_client_config(&self) -> Result<ClientConfig> {
610 let (_, builder) = self.client_config_builder()?;
611 let root_store = self.load_system_root_certificates()?;
612 let builder = builder.with_root_certificates(root_store);
613
614 if let (Some(client_cert_path), Some(client_key_path)) =
616 (&self.client_cert_path, &self.client_key_path)
617 {
618 let (cert_chain, key) =
619 self.load_client_credentials(client_cert_path, client_key_path)?;
620 builder.with_client_auth_cert(cert_chain, key).map_err(|e| {
621 ProtocolError::TlsError(format!("Failed to set client certificate: {e}"))
622 })
623 } else {
624 Ok(builder.with_no_client_auth())
625 }
626 }
627
628 fn build_insecure_client_config(&self) -> Result<ClientConfig> {
630 let (provider, builder) = self.client_config_builder()?;
631 let verifier = self.create_custom_verifier(&provider);
632 let custom_builder = builder
633 .dangerous()
634 .with_custom_certificate_verifier(verifier);
635
636 if let (Some(client_cert_path), Some(client_key_path)) =
638 (&self.client_cert_path, &self.client_key_path)
639 {
640 let (cert_chain, key) =
641 self.load_client_credentials(client_cert_path, client_key_path)?;
642 custom_builder
643 .with_client_auth_cert(cert_chain, key)
644 .map_err(|e| {
645 ProtocolError::TlsError(format!("Failed to set client certificate: {e}"))
646 })
647 } else {
648 Ok(custom_builder.with_no_client_auth())
649 }
650 }
651
652 fn load_system_root_certificates(&self) -> Result<RootCertStore> {
654 let mut root_store = RootCertStore::empty();
655 let native_certs = rustls_native_certs::load_native_certs();
656 if let Some(e) = native_certs.errors.first() {
657 return Err(ProtocolError::TlsError(format!(
658 "Failed to load native certs: {e}"
659 )));
660 }
661
662 for cert in native_certs.certs {
663 root_store.add(cert).map_err(|e| {
664 ProtocolError::TlsError(format!("Failed to add cert to root store: {e}"))
665 })?;
666 }
667
668 Ok(root_store)
669 }
670
671 fn create_custom_verifier(&self, provider: &CryptoProvider) -> Arc<dyn ServerCertVerifier> {
675 let supported_algs = provider.signature_verification_algorithms;
676 if let Some(hash) = &self.pinned_cert_hash {
677 Arc::new(CertificateFingerprint {
678 fingerprint: hash.clone(),
679 supported_algs,
680 })
681 } else {
682 Arc::new(AcceptAnyServerCert { supported_algs })
683 }
684 }
685
686 fn load_client_credentials(
688 &self,
689 cert_path: &str,
690 key_path: &str,
691 ) -> Result<(Vec<CertificateDer<'static>>, PrivateKeyDer<'static>)> {
692 let cert_file = File::open(cert_path).map_err(ProtocolError::Io)?;
694 let mut cert_reader = BufReader::new(cert_file);
695 let certs_result: std::result::Result<Vec<_>, _> =
696 CertificateDer::pem_reader_iter(&mut cert_reader).collect();
697 let certs: Vec<CertificateDer<'static>> = certs_result
698 .map_err(|_| ProtocolError::TlsError("Failed to parse client certificate".into()))?;
699
700 if certs.is_empty() {
701 return Err(ProtocolError::TlsError(
702 "No client certificates found".into(),
703 ));
704 }
705
706 let key_file = File::open(key_path).map_err(ProtocolError::Io)?;
708 let mut key_reader = BufReader::new(key_file);
709 let key = load_private_key(&mut key_reader)?;
710
711 Ok((certs, key))
712 }
713
714 pub fn server_name(&self) -> Result<ServerName<'_>> {
716 ServerName::try_from(self.server_name.as_str())
717 .map_err(|_| ProtocolError::TlsError("Invalid server name".into()))
718 }
719
720 pub fn server_name_string(&self) -> String {
722 self.server_name.clone()
723 }
724}
725
726#[instrument(skip(config))]
728pub async fn start_server(addr: &str, config: TlsServerConfig) -> Result<()> {
729 let tls_config = config.load_server_config()?;
730 let acceptor = TlsAcceptor::from(Arc::new(tls_config));
731 let listener = TcpListener::bind(addr).await?;
732
733 info!(address=%addr, "TLS server listening");
734
735 loop {
736 let (stream, peer) = listener.accept().await?;
737 let acceptor = acceptor.clone();
738
739 tokio::spawn(async move {
740 match acceptor.accept(stream).await {
741 Ok(tls_stream) => {
742 if let Err(e) = handle_tls_connection(tls_stream, peer).await {
743 error!(%peer, error=%e, "Connection error");
744 }
745 }
746 Err(e) => {
747 error!(%peer, error=%e, "TLS handshake failed");
748 }
749 }
750 });
751 }
752}
753
754#[instrument(skip(tls_stream), fields(peer=%peer))]
756async fn handle_tls_connection(
757 tls_stream: ServerTlsStream<TcpStream>,
758 peer: SocketAddr,
759) -> Result<()> {
760 let mut framed = Framed::new(tls_stream, PacketCodec);
761
762 info!("TLS connection established");
763
764 while let Some(packet) = framed.next().await {
765 match packet {
766 Ok(pkt) => {
767 debug!(bytes = pkt.payload.len(), "Received data");
768 on_packet(pkt, &mut framed).await?;
769 }
770 Err(e) => {
771 error!(error=%e, "Protocol error");
772 break;
773 }
774 }
775 }
776
777 info!("TLS connection closed");
778 Ok(())
779}
780
781#[instrument(skip(framed), fields(packet_version=pkt.version, payload_size=pkt.payload.len()))]
783async fn on_packet<T>(pkt: Packet, framed: &mut Framed<T, PacketCodec>) -> Result<()>
784where
785 T: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin,
786{
787 let response = Packet {
789 version: pkt.version,
790 payload: pkt.payload,
791 };
792
793 framed.send(response).await?;
794 Ok(())
795}
796
797pub async fn connect(
799 addr: &str,
800 config: TlsClientConfig,
801) -> Result<Framed<ClientTlsStream<TcpStream>, PacketCodec>> {
802 let tls_config = Arc::new(config.load_client_config()?);
803 let connector = TlsConnector::from(tls_config);
804
805 let stream = TcpStream::connect(addr).await?;
806
807 let server_name_str = config.server_name_string();
810 let domain_static: &'static str = Box::leak(server_name_str.into_boxed_str());
811 let domain = ServerName::try_from(domain_static)
812 .map_err(|_| ProtocolError::TlsError("Invalid server name".into()))?;
813
814 let tls_stream = connector
815 .connect(domain, stream)
816 .await
817 .map_err(|e| ProtocolError::TlsError(format!("TLS connection failed: {e}")))?;
818
819 let framed = Framed::new(tls_stream, PacketCodec);
820 Ok(framed)
821}