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::{ServerCertVerified, ServerCertVerifier};
25use rustls::pki_types::pem::PemObject;
26use rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer, ServerName, UnixTime};
27use rustls::{ClientConfig, DigitallySignedStruct, RootCertStore, ServerConfig};
28use tokio::net::{TcpListener, TcpStream};
29use tokio_rustls::client::TlsStream as ClientTlsStream;
30use tokio_rustls::server::TlsStream as ServerTlsStream;
31use tokio_rustls::{TlsAcceptor, TlsConnector};
32use tokio_util::codec::Framed;
33use tracing::{debug, error, info, instrument, warn};
34
35use crate::core::codec::PacketCodec;
36use crate::core::packet::Packet;
37use crate::error::{ProtocolError, Result};
38use futures::{SinkExt, StreamExt};
39
40#[derive(Debug)]
42struct CertificateFingerprint {
43 fingerprint: Vec<u8>,
44}
45
46impl ServerCertVerifier for CertificateFingerprint {
47 fn verify_server_cert(
48 &self,
49 end_entity: &CertificateDer<'_>,
50 _intermediates: &[CertificateDer<'_>],
51 _server_name: &ServerName,
52 _ocsp_response: &[u8],
53 _now: UnixTime,
54 ) -> std::result::Result<ServerCertVerified, rustls::Error> {
55 use sha2::{Digest, Sha256};
56
57 let mut hasher = Sha256::new();
58 hasher.update(end_entity);
59 let hash = hasher.finalize();
60
61 if hash.as_slice() == self.fingerprint.as_slice() {
62 Ok(ServerCertVerified::assertion())
63 } else {
64 Err(rustls::Error::General(
65 "Pinned certificate hash mismatch".into(),
66 ))
67 }
68 }
69
70 fn verify_tls12_signature(
71 &self,
72 _message: &[u8],
73 _cert: &CertificateDer<'_>,
74 _dss: &DigitallySignedStruct,
75 ) -> std::result::Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
76 Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
77 }
78
79 fn verify_tls13_signature(
80 &self,
81 _message: &[u8],
82 _cert: &CertificateDer<'_>,
83 _dss: &DigitallySignedStruct,
84 ) -> std::result::Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
85 Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
86 }
87
88 fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
89 vec![
91 rustls::SignatureScheme::RSA_PKCS1_SHA256,
92 rustls::SignatureScheme::ECDSA_NISTP256_SHA256,
93 rustls::SignatureScheme::ED25519,
94 ]
95 }
96}
97
98#[derive(Debug)]
99struct AcceptAnyServerCert;
100
101impl ServerCertVerifier for AcceptAnyServerCert {
102 fn verify_server_cert(
103 &self,
104 _end_entity: &CertificateDer<'_>,
105 _intermediates: &[CertificateDer<'_>],
106 _server_name: &ServerName,
107 _ocsp_response: &[u8],
108 _now: UnixTime,
109 ) -> std::result::Result<ServerCertVerified, rustls::Error> {
110 Ok(ServerCertVerified::assertion())
111 }
112
113 fn verify_tls12_signature(
114 &self,
115 _message: &[u8],
116 _cert: &CertificateDer<'_>,
117 _dss: &DigitallySignedStruct,
118 ) -> std::result::Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
119 Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
120 }
121
122 fn verify_tls13_signature(
123 &self,
124 _message: &[u8],
125 _cert: &CertificateDer<'_>,
126 _dss: &DigitallySignedStruct,
127 ) -> std::result::Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
128 Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
129 }
130
131 fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
132 vec![
133 rustls::SignatureScheme::RSA_PKCS1_SHA256,
134 rustls::SignatureScheme::ECDSA_NISTP256_SHA256,
135 rustls::SignatureScheme::ED25519,
136 ]
137 }
138}
139
140fn crypto_provider() -> Arc<rustls::crypto::CryptoProvider> {
146 Arc::new(rustls::crypto::ring::default_provider())
147}
148
149fn load_private_key(reader: &mut BufReader<File>) -> Result<PrivateKeyDer<'static>> {
151 reader
154 .seek(std::io::SeekFrom::Start(0))
155 .map_err(ProtocolError::Io)?;
156
157 let keys: std::result::Result<Vec<_>, _> =
159 PrivatePkcs8KeyDer::pem_reader_iter(reader).collect();
160 let keys =
161 keys.map_err(|_| ProtocolError::TlsError("Failed to parse PKCS8 private key".into()))?;
162
163 if !keys.is_empty() {
164 return Ok(PrivateKeyDer::Pkcs8(keys[0].clone_key()));
165 }
166
167 Err(ProtocolError::TlsError(
170 "No supported private key format found".into(),
171 ))
172}
173
174pub enum TlsVersion {
176 TLS12,
178 TLS13,
180 All,
182}
183
184pub struct TlsServerConfig {
186 cert_path: String,
187 key_path: String,
188 client_ca_path: Option<String>,
190 require_client_auth: bool,
192 tls_versions: Option<Vec<TlsVersion>>,
194 cipher_suites: Option<Vec<rustls::SupportedCipherSuite>>,
196 alpn_protocols: Option<Vec<Vec<u8>>>,
198}
199
200impl TlsServerConfig {
201 pub fn new<P: AsRef<std::path::Path>>(cert_path: P, key_path: P) -> Self {
203 Self {
204 cert_path: cert_path.as_ref().to_string_lossy().to_string(),
205 key_path: key_path.as_ref().to_string_lossy().to_string(),
206 client_ca_path: None,
207 require_client_auth: false,
208 tls_versions: None,
209 cipher_suites: None,
210 alpn_protocols: Some(vec![b"h2".to_vec(), b"http/1.1".to_vec()]),
211 }
212 }
213
214 pub fn with_tls_versions(mut self, versions: Vec<TlsVersion>) -> Self {
216 self.tls_versions = Some(versions);
217 self
218 }
219
220 pub fn with_cipher_suites(mut self, cipher_suites: Vec<rustls::SupportedCipherSuite>) -> Self {
222 self.cipher_suites = Some(cipher_suites);
223 self
224 }
225
226 pub fn with_client_auth<S: Into<String>>(mut self, client_ca_path: S) -> Self {
228 self.client_ca_path = Some(client_ca_path.into());
229 self.require_client_auth = true;
230 self
231 }
232
233 pub fn require_client_auth(mut self, required: bool) -> Self {
235 self.require_client_auth = required;
236 self
237 }
238
239 pub fn with_alpn_protocols(mut self, protocols: Vec<Vec<u8>>) -> Self {
241 self.alpn_protocols = Some(protocols);
242 self
243 }
244
245 pub fn generate_self_signed<P: AsRef<Path>>(cert_path: P, key_path: P) -> io::Result<Self> {
247 let cert = rcgen::generate_simple_self_signed(vec!["localhost".into()])
248 .map_err(|e| io::Error::other(format!("Certificate generation error: {e}")))?;
249
250 let mut cert_file = File::create(&cert_path)?;
252 let pem = cert.cert.pem();
253 cert_file.write_all(pem.as_bytes())?;
254
255 let mut key_file = File::create(&key_path)?;
257 key_file.write_all(cert.signing_key.serialize_pem().as_bytes())?;
258
259 Ok(Self {
260 cert_path: cert_path.as_ref().to_string_lossy().to_string(),
261 key_path: key_path.as_ref().to_string_lossy().to_string(),
262 client_ca_path: None,
263 require_client_auth: false,
264 tls_versions: None,
265 cipher_suites: None,
266 alpn_protocols: Some(vec![b"h2".to_vec(), b"http/1.1".to_vec()]),
267 })
268 }
269
270 pub fn load_server_config(&self) -> Result<ServerConfig> {
272 let cert_file = File::open(&self.cert_path)
274 .map_err(|e| ProtocolError::TlsError(format!("Failed to open cert file: {e}")))?;
275 let mut cert_reader = BufReader::new(cert_file);
276 let cert_chain: std::result::Result<Vec<_>, _> =
277 CertificateDer::pem_reader_iter(&mut cert_reader).collect();
278 let cert_chain: Vec<CertificateDer<'static>> = cert_chain
279 .map_err(|_| ProtocolError::TlsError("Failed to parse certificate".into()))?;
280
281 if cert_chain.is_empty() {
282 return Err(ProtocolError::TlsError("No certificates found".into()));
283 }
284
285 let key_file = File::open(&self.key_path)
287 .map_err(|e| ProtocolError::TlsError(format!("Failed to open key file: {e}")))?;
288 let mut key_reader = BufReader::new(key_file);
289 let private_key = load_private_key(&mut key_reader)?;
290
291 if let Some(versions) = &self.tls_versions {
294 let mut has_tls13 = false;
295 let mut has_tls12 = false;
296 for v in versions {
297 match v {
298 TlsVersion::TLS12 => has_tls12 = true,
299 TlsVersion::TLS13 => has_tls13 = true,
300 TlsVersion::All => {
301 has_tls13 = true;
302 has_tls12 = true;
303 }
304 }
305 }
306 debug!(
308 "TLS versions requested: TLS1.2={}, TLS1.3={}",
309 has_tls12, has_tls13
310 );
311 }
312
313 let config_builder = ServerConfig::builder_with_provider(crypto_provider())
315 .with_safe_default_protocol_versions()
316 .map_err(|_| {
317 ProtocolError::TlsError("Failed to configure TLS protocol versions".into())
318 })?;
319
320 let cert_builder = config_builder.with_no_client_auth();
321
322 let mut config = cert_builder
324 .with_single_cert(cert_chain.clone(), private_key.clone_key())
325 .map_err(|e| ProtocolError::TlsError(format!("TLS error: {e}")))?;
326
327 if let Some(client_ca_path) = &self.client_ca_path {
329 let client_ca_file = File::open(client_ca_path).map_err(|e| {
331 ProtocolError::TlsError(format!("Failed to open client CA file: {e}"))
332 })?;
333 let mut client_ca_reader = BufReader::new(client_ca_file);
334 let client_ca_certs: std::result::Result<Vec<_>, _> =
335 CertificateDer::pem_reader_iter(&mut client_ca_reader).collect();
336 let client_ca_certs: Vec<CertificateDer<'static>> = client_ca_certs.map_err(|_| {
337 ProtocolError::TlsError("Failed to parse client CA certificate".into())
338 })?;
339
340 if client_ca_certs.is_empty() {
341 return Err(ProtocolError::TlsError(
342 "No client CA certificates found".into(),
343 ));
344 }
345
346 let mut client_root_store = RootCertStore::empty();
348 for cert in client_ca_certs {
349 client_root_store.add(cert).map_err(|e| {
350 ProtocolError::TlsError(format!("Failed to add client CA cert: {e}"))
351 })?;
352 }
353
354 let client_auth = rustls::server::WebPkiClientVerifier::builder_with_provider(
358 Arc::new(client_root_store),
359 crypto_provider(),
360 )
361 .build()
362 .map_err(|e| {
363 ProtocolError::TlsError(format!("Failed to build client verifier: {e}"))
364 })?;
365
366 let new_builder = ServerConfig::builder_with_provider(crypto_provider())
368 .with_safe_default_protocol_versions()
369 .map_err(|_| {
370 ProtocolError::TlsError("Failed to configure TLS protocol versions".into())
371 })?;
372 let new_cert_builder = new_builder.with_client_cert_verifier(client_auth);
373
374 config = new_cert_builder
376 .with_single_cert(cert_chain, private_key.clone_key())
377 .map_err(|e| ProtocolError::TlsError(format!("TLS error with client auth: {e}")))?;
378
379 debug!("mTLS enabled with client certificate verification required");
380 }
381
382 if let Some(protocols) = &self.alpn_protocols {
384 config.alpn_protocols = protocols.clone();
385 debug!(
386 protocol_count = protocols.len(),
387 "ALPN protocols configured"
388 );
389 }
390
391 Ok(config)
392 }
393
394 pub fn calculate_cert_hash(cert: &CertificateDer<'_>) -> Vec<u8> {
396 use sha2::{Digest, Sha256};
397 let mut hasher = Sha256::new();
398 hasher.update(cert.as_ref());
399 hasher.finalize().to_vec()
400 }
401}
402
403pub struct TlsClientConfig {
405 server_name: String,
406 insecure: bool,
407 pinned_cert_hash: Option<Vec<u8>>,
409 client_cert_path: Option<String>,
411 client_key_path: Option<String>,
413 tls_versions: Option<Vec<TlsVersion>>,
415 cipher_suites: Option<Vec<rustls::SupportedCipherSuite>>,
417}
418
419impl TlsClientConfig {
420 pub fn new<S: Into<String>>(server_name: S) -> Self {
422 Self {
423 server_name: server_name.into(),
424 insecure: false,
425 pinned_cert_hash: None,
426 client_cert_path: None,
427 client_key_path: None,
428 tls_versions: None,
429 cipher_suites: None,
430 }
431 }
432
433 pub fn with_tls_versions(mut self, versions: Vec<TlsVersion>) -> Self {
435 self.tls_versions = Some(versions);
436 self
437 }
438
439 pub fn with_cipher_suites(mut self, cipher_suites: Vec<rustls::SupportedCipherSuite>) -> Self {
441 self.cipher_suites = Some(cipher_suites);
442 self
443 }
444
445 pub fn with_client_certificate<S: Into<String>>(mut self, cert_path: S, key_path: S) -> Self {
447 self.client_cert_path = Some(cert_path.into());
448 self.client_key_path = Some(key_path.into());
449 self
450 }
451
452 pub fn insecure(mut self) -> Self {
465 warn!("INSECURE MODE ENABLED: Certificate verification is disabled. This should only be used for development/testing.");
466 self.insecure = true;
467 self
468 }
469
470 pub fn with_pinned_cert_hash(mut self, hash: Vec<u8>) -> Self {
477 if hash.len() != 32 {
478 warn!(
479 "Certificate hash has unexpected length: {} (expected 32 bytes for SHA-256)",
480 hash.len()
481 );
482 }
483 self.pinned_cert_hash = Some(hash);
484 self
485 }
486
487 pub fn load_client_config(&self) -> Result<ClientConfig> {
489 self.log_tls_version_info();
490
491 if self.insecure {
492 self.build_insecure_client_config()
493 } else {
494 self.build_secure_client_config()
495 }
496 }
497
498 fn log_tls_version_info(&self) {
500 if let Some(versions) = &self.tls_versions {
501 let mut has_tls13 = false;
502 let mut has_tls12 = false;
503 for v in versions {
504 match v {
505 TlsVersion::TLS12 => has_tls12 = true,
506 TlsVersion::TLS13 => has_tls13 = true,
507 TlsVersion::All => {
508 has_tls13 = true;
509 has_tls12 = true;
510 }
511 }
512 }
513 debug!(
514 "TLS client versions requested: TLS1.2={}, TLS1.3={}",
515 has_tls12, has_tls13
516 );
517 }
518 }
519
520 fn build_secure_client_config(&self) -> Result<ClientConfig> {
522 let root_store = self.load_system_root_certificates()?;
523 let builder = ClientConfig::builder_with_provider(crypto_provider())
524 .with_safe_default_protocol_versions()
525 .map_err(|_| {
526 ProtocolError::TlsError("Failed to configure TLS protocol versions".into())
527 })?
528 .with_root_certificates(root_store);
529
530 if let (Some(client_cert_path), Some(client_key_path)) =
532 (&self.client_cert_path, &self.client_key_path)
533 {
534 let (cert_chain, key) =
535 self.load_client_credentials(client_cert_path, client_key_path)?;
536 builder.with_client_auth_cert(cert_chain, key).map_err(|e| {
537 ProtocolError::TlsError(format!("Failed to set client certificate: {e}"))
538 })
539 } else {
540 Ok(builder.with_no_client_auth())
541 }
542 }
543
544 fn build_insecure_client_config(&self) -> Result<ClientConfig> {
546 let builder = ClientConfig::builder_with_provider(crypto_provider())
547 .with_safe_default_protocol_versions()
548 .map_err(|_| {
549 ProtocolError::TlsError("Failed to configure TLS protocol versions".into())
550 })?;
551 let verifier = self.create_custom_verifier();
552 let custom_builder = builder
553 .dangerous()
554 .with_custom_certificate_verifier(verifier);
555
556 if let (Some(client_cert_path), Some(client_key_path)) =
558 (&self.client_cert_path, &self.client_key_path)
559 {
560 let (cert_chain, key) =
561 self.load_client_credentials(client_cert_path, client_key_path)?;
562 custom_builder
563 .with_client_auth_cert(cert_chain, key)
564 .map_err(|e| {
565 ProtocolError::TlsError(format!("Failed to set client certificate: {e}"))
566 })
567 } else {
568 Ok(custom_builder.with_no_client_auth())
569 }
570 }
571
572 fn load_system_root_certificates(&self) -> Result<RootCertStore> {
574 let mut root_store = RootCertStore::empty();
575 let native_certs = rustls_native_certs::load_native_certs();
576 if let Some(e) = native_certs.errors.first() {
577 return Err(ProtocolError::TlsError(format!(
578 "Failed to load native certs: {e}"
579 )));
580 }
581
582 for cert in native_certs.certs {
583 root_store.add(cert).map_err(|e| {
584 ProtocolError::TlsError(format!("Failed to add cert to root store: {e}"))
585 })?;
586 }
587
588 Ok(root_store)
589 }
590
591 fn create_custom_verifier(&self) -> Arc<dyn ServerCertVerifier> {
593 if let Some(hash) = &self.pinned_cert_hash {
594 Arc::new(CertificateFingerprint {
595 fingerprint: hash.clone(),
596 })
597 } else {
598 Arc::new(AcceptAnyServerCert)
599 }
600 }
601
602 fn load_client_credentials(
604 &self,
605 cert_path: &str,
606 key_path: &str,
607 ) -> Result<(Vec<CertificateDer<'static>>, PrivateKeyDer<'static>)> {
608 let cert_file = File::open(cert_path).map_err(ProtocolError::Io)?;
610 let mut cert_reader = BufReader::new(cert_file);
611 let certs_result: std::result::Result<Vec<_>, _> =
612 CertificateDer::pem_reader_iter(&mut cert_reader).collect();
613 let certs: Vec<CertificateDer<'static>> = certs_result
614 .map_err(|_| ProtocolError::TlsError("Failed to parse client certificate".into()))?;
615
616 if certs.is_empty() {
617 return Err(ProtocolError::TlsError(
618 "No client certificates found".into(),
619 ));
620 }
621
622 let key_file = File::open(key_path).map_err(ProtocolError::Io)?;
624 let mut key_reader = BufReader::new(key_file);
625 let key = load_private_key(&mut key_reader)?;
626
627 Ok((certs, key))
628 }
629
630 pub fn server_name(&self) -> Result<ServerName<'_>> {
632 ServerName::try_from(self.server_name.as_str())
633 .map_err(|_| ProtocolError::TlsError("Invalid server name".into()))
634 }
635
636 pub fn server_name_string(&self) -> String {
638 self.server_name.clone()
639 }
640}
641
642#[instrument(skip(config))]
644pub async fn start_server(addr: &str, config: TlsServerConfig) -> Result<()> {
645 let tls_config = config.load_server_config()?;
646 let acceptor = TlsAcceptor::from(Arc::new(tls_config));
647 let listener = TcpListener::bind(addr).await?;
648
649 info!(address=%addr, "TLS server listening");
650
651 loop {
652 let (stream, peer) = listener.accept().await?;
653 let acceptor = acceptor.clone();
654
655 tokio::spawn(async move {
656 match acceptor.accept(stream).await {
657 Ok(tls_stream) => {
658 if let Err(e) = handle_tls_connection(tls_stream, peer).await {
659 error!(%peer, error=%e, "Connection error");
660 }
661 }
662 Err(e) => {
663 error!(%peer, error=%e, "TLS handshake failed");
664 }
665 }
666 });
667 }
668}
669
670#[instrument(skip(tls_stream), fields(peer=%peer))]
672async fn handle_tls_connection(
673 tls_stream: ServerTlsStream<TcpStream>,
674 peer: SocketAddr,
675) -> Result<()> {
676 let mut framed = Framed::new(tls_stream, PacketCodec);
677
678 info!("TLS connection established");
679
680 while let Some(packet) = framed.next().await {
681 match packet {
682 Ok(pkt) => {
683 debug!(bytes = pkt.payload.len(), "Received data");
684 on_packet(pkt, &mut framed).await?;
685 }
686 Err(e) => {
687 error!(error=%e, "Protocol error");
688 break;
689 }
690 }
691 }
692
693 info!("TLS connection closed");
694 Ok(())
695}
696
697#[instrument(skip(framed), fields(packet_version=pkt.version, payload_size=pkt.payload.len()))]
699async fn on_packet<T>(pkt: Packet, framed: &mut Framed<T, PacketCodec>) -> Result<()>
700where
701 T: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin,
702{
703 let response = Packet {
705 version: pkt.version,
706 payload: pkt.payload,
707 };
708
709 framed.send(response).await?;
710 Ok(())
711}
712
713pub async fn connect(
715 addr: &str,
716 config: TlsClientConfig,
717) -> Result<Framed<ClientTlsStream<TcpStream>, PacketCodec>> {
718 let tls_config = Arc::new(config.load_client_config()?);
719 let connector = TlsConnector::from(tls_config);
720
721 let stream = TcpStream::connect(addr).await?;
722
723 let server_name_str = config.server_name_string();
726 let domain_static: &'static str = Box::leak(server_name_str.into_boxed_str());
727 let domain = ServerName::try_from(domain_static)
728 .map_err(|_| ProtocolError::TlsError("Invalid server name".into()))?;
729
730 let tls_stream = connector
731 .connect(domain, stream)
732 .await
733 .map_err(|e| ProtocolError::TlsError(format!("TLS connection failed: {e}")))?;
734
735 let framed = Framed::new(tls_stream, PacketCodec);
736 Ok(framed)
737}