1use rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier};
8use rustls::pki_types::{CertificateDer, PrivateKeyDer, ServerName, UnixTime};
9use rustls::server::danger::{ClientCertVerified, ClientCertVerifier};
10use rustls::{
11 ClientConfig, DigitallySignedStruct, DistinguishedName, ServerConfig, SignatureScheme,
12};
13use sha2::{Digest, Sha256};
14use std::sync::Arc;
15
16pub type Fingerprint = [u8; 32];
18
19const TLS_VERSIONS: &[&rustls::SupportedProtocolVersion] = &[&rustls::version::TLS13];
25
26#[derive(Clone)]
28pub struct CertifiedKey {
29 pub cert_der: Vec<u8>,
30 pub key_der: Vec<u8>,
31 pub fingerprint: Fingerprint,
32}
33
34pub fn generate_self_signed_cert() -> anyhow::Result<CertifiedKey> {
39 use rcgen::{CertificateParams, KeyPair};
40 let key_pair = KeyPair::generate_for(&rcgen::PKCS_ED25519)?;
42 let mut params = CertificateParams::default();
44 params.distinguished_name = rcgen::DistinguishedName::new();
45 params.distinguished_name.push(
46 rcgen::DnType::CommonName,
47 format!("rcp-{}", rand::random::<u64>()),
48 );
49 let cert = params.self_signed(&key_pair)?;
51 let cert_der = cert.der().to_vec();
52 let key_der = key_pair.serialize_der();
53 let fingerprint = compute_fingerprint(&cert_der);
55 Ok(CertifiedKey {
56 cert_der,
57 key_der,
58 fingerprint,
59 })
60}
61
62fn signature_verification_algorithms() -> rustls::crypto::WebPkiSupportedAlgorithms {
66 rustls::crypto::ring::default_provider().signature_verification_algorithms
67}
68
69pub fn compute_fingerprint(cert_der: &[u8]) -> Fingerprint {
71 let mut hasher = Sha256::new();
72 hasher.update(cert_der);
73 hasher.finalize().into()
74}
75
76pub fn fingerprint_to_hex(fp: &Fingerprint) -> String {
78 hex::encode(fp)
79}
80
81pub fn fingerprint_from_hex(s: &str) -> anyhow::Result<Fingerprint> {
83 let bytes = hex::decode(s)?;
84 if bytes.len() != 32 {
85 anyhow::bail!(
86 "fingerprint must be 32 bytes (64 hex chars), got {}",
87 bytes.len()
88 );
89 }
90 let mut fp = [0u8; 32];
91 fp.copy_from_slice(&bytes);
92 Ok(fp)
93}
94
95#[cfg(test)]
100fn create_server_config(cert_key: &CertifiedKey) -> anyhow::Result<Arc<ServerConfig>> {
101 let cert = CertificateDer::from(cert_key.cert_der.clone());
102 let key = PrivateKeyDer::try_from(cert_key.key_der.clone())
103 .map_err(|e| anyhow::anyhow!("invalid private key: {e}"))?;
104 let config = ServerConfig::builder_with_protocol_versions(TLS_VERSIONS)
105 .with_no_client_auth()
106 .with_single_cert(vec![cert], key)?;
107 Ok(Arc::new(config))
108}
109
110pub fn create_server_config_with_client_auth(
116 cert_key: &CertifiedKey,
117 expected_client_fingerprint: Fingerprint,
118) -> anyhow::Result<Arc<ServerConfig>> {
119 let cert = CertificateDer::from(cert_key.cert_der.clone());
120 let key = PrivateKeyDer::try_from(cert_key.key_der.clone())
121 .map_err(|e| anyhow::anyhow!("invalid private key: {e}"))?;
122 let client_verifier = Arc::new(FingerprintClientCertVerifier::new(
123 expected_client_fingerprint,
124 ));
125 let config = ServerConfig::builder_with_protocol_versions(TLS_VERSIONS)
126 .with_client_cert_verifier(client_verifier)
127 .with_single_cert(vec![cert], key)?;
128 Ok(Arc::new(config))
129}
130
131#[cfg(test)]
137fn create_client_config(expected_server_fingerprint: Fingerprint) -> Arc<ClientConfig> {
138 let verifier = Arc::new(FingerprintServerCertVerifier::new(
139 expected_server_fingerprint,
140 ));
141 let config = ClientConfig::builder_with_protocol_versions(TLS_VERSIONS)
142 .dangerous()
143 .with_custom_certificate_verifier(verifier)
144 .with_no_client_auth();
145 Arc::new(config)
146}
147
148pub fn create_client_config_with_cert(
154 client_cert_key: &CertifiedKey,
155 expected_server_fingerprint: Fingerprint,
156) -> anyhow::Result<Arc<ClientConfig>> {
157 let verifier = Arc::new(FingerprintServerCertVerifier::new(
158 expected_server_fingerprint,
159 ));
160 let cert = CertificateDer::from(client_cert_key.cert_der.clone());
161 let key = PrivateKeyDer::try_from(client_cert_key.key_der.clone())
162 .map_err(|e| anyhow::anyhow!("invalid private key: {e}"))?;
163 let config = ClientConfig::builder_with_protocol_versions(TLS_VERSIONS)
164 .dangerous()
165 .with_custom_certificate_verifier(verifier)
166 .with_client_auth_cert(vec![cert], key)?;
167 Ok(Arc::new(config))
168}
169
170#[derive(Debug)]
172struct FingerprintServerCertVerifier {
173 expected_fingerprint: Fingerprint,
174}
175
176impl FingerprintServerCertVerifier {
177 fn new(expected_fingerprint: Fingerprint) -> Self {
178 Self {
179 expected_fingerprint,
180 }
181 }
182}
183
184impl ServerCertVerifier for FingerprintServerCertVerifier {
185 fn verify_server_cert(
186 &self,
187 end_entity: &CertificateDer<'_>,
188 _intermediates: &[CertificateDer<'_>],
189 _server_name: &ServerName<'_>,
190 _ocsp_response: &[u8],
191 _now: UnixTime,
192 ) -> Result<ServerCertVerified, rustls::Error> {
193 let actual_fingerprint = compute_fingerprint(end_entity.as_ref());
194 if actual_fingerprint == self.expected_fingerprint {
195 Ok(ServerCertVerified::assertion())
196 } else {
197 tracing::error!(
198 "TLS server certificate fingerprint mismatch: expected {}, got {}",
199 fingerprint_to_hex(&self.expected_fingerprint),
200 fingerprint_to_hex(&actual_fingerprint)
201 );
202 Err(rustls::Error::InvalidCertificate(
203 rustls::CertificateError::BadSignature,
204 ))
205 }
206 }
207 fn verify_tls12_signature(
208 &self,
209 message: &[u8],
210 cert: &CertificateDer<'_>,
211 dss: &DigitallySignedStruct,
212 ) -> Result<HandshakeSignatureValid, rustls::Error> {
213 rustls::crypto::verify_tls12_signature(
216 message,
217 cert,
218 dss,
219 &signature_verification_algorithms(),
220 )
221 }
222 fn verify_tls13_signature(
223 &self,
224 message: &[u8],
225 cert: &CertificateDer<'_>,
226 dss: &DigitallySignedStruct,
227 ) -> Result<HandshakeSignatureValid, rustls::Error> {
228 rustls::crypto::verify_tls13_signature(
229 message,
230 cert,
231 dss,
232 &signature_verification_algorithms(),
233 )
234 }
235 fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
236 signature_verification_algorithms().supported_schemes()
237 }
238}
239
240#[derive(Debug)]
242struct FingerprintClientCertVerifier {
243 expected_fingerprint: Fingerprint,
244}
245
246impl FingerprintClientCertVerifier {
247 fn new(expected_fingerprint: Fingerprint) -> Self {
248 Self {
249 expected_fingerprint,
250 }
251 }
252}
253
254impl ClientCertVerifier for FingerprintClientCertVerifier {
255 fn root_hint_subjects(&self) -> &[DistinguishedName] {
256 &[]
257 }
258 fn verify_client_cert(
259 &self,
260 end_entity: &CertificateDer<'_>,
261 _intermediates: &[CertificateDer<'_>],
262 _now: UnixTime,
263 ) -> Result<ClientCertVerified, rustls::Error> {
264 let actual_fingerprint = compute_fingerprint(end_entity.as_ref());
265 if actual_fingerprint == self.expected_fingerprint {
266 Ok(ClientCertVerified::assertion())
267 } else {
268 tracing::error!(
269 "TLS client certificate fingerprint mismatch: expected {}, got {}",
270 fingerprint_to_hex(&self.expected_fingerprint),
271 fingerprint_to_hex(&actual_fingerprint)
272 );
273 Err(rustls::Error::InvalidCertificate(
274 rustls::CertificateError::BadSignature,
275 ))
276 }
277 }
278 fn verify_tls12_signature(
279 &self,
280 message: &[u8],
281 cert: &CertificateDer<'_>,
282 dss: &DigitallySignedStruct,
283 ) -> Result<HandshakeSignatureValid, rustls::Error> {
284 rustls::crypto::verify_tls12_signature(
287 message,
288 cert,
289 dss,
290 &signature_verification_algorithms(),
291 )
292 }
293 fn verify_tls13_signature(
294 &self,
295 message: &[u8],
296 cert: &CertificateDer<'_>,
297 dss: &DigitallySignedStruct,
298 ) -> Result<HandshakeSignatureValid, rustls::Error> {
299 rustls::crypto::verify_tls13_signature(
300 message,
301 cert,
302 dss,
303 &signature_verification_algorithms(),
304 )
305 }
306 fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
307 signature_verification_algorithms().supported_schemes()
308 }
309 fn client_auth_mandatory(&self) -> bool {
310 true
311 }
312}
313
314#[cfg(test)]
315mod tests {
316 use super::*;
317
318 fn install_crypto_provider() {
319 rustls::crypto::ring::default_provider()
320 .install_default()
321 .ok(); }
323
324 #[test]
325 fn test_generate_cert_and_fingerprint() {
326 install_crypto_provider();
327 let cert_key = generate_self_signed_cert().unwrap();
328 assert_eq!(cert_key.fingerprint.len(), 32);
329 assert!(!cert_key.cert_der.is_empty());
330 assert!(!cert_key.key_der.is_empty());
331 let fp2 = compute_fingerprint(&cert_key.cert_der);
333 assert_eq!(cert_key.fingerprint, fp2);
334 }
335
336 #[test]
337 fn test_fingerprint_hex_roundtrip() {
338 install_crypto_provider();
339 let cert_key = generate_self_signed_cert().unwrap();
340 let hex = fingerprint_to_hex(&cert_key.fingerprint);
341 assert_eq!(hex.len(), 64);
342 let fp2 = fingerprint_from_hex(&hex).unwrap();
343 assert_eq!(cert_key.fingerprint, fp2);
344 }
345
346 #[test]
347 fn test_fingerprint_from_hex_invalid() {
348 assert!(fingerprint_from_hex("abcd").is_err());
350 assert!(fingerprint_from_hex("zzzz").is_err());
352 }
353
354 #[test]
355 fn test_create_server_config() {
356 install_crypto_provider();
357 let cert_key = generate_self_signed_cert().unwrap();
358 let config = create_server_config(&cert_key).unwrap();
359 assert!(config.alpn_protocols.is_empty());
360 }
361
362 #[test]
363 fn test_create_client_config() {
364 install_crypto_provider();
365 let fp = [0u8; 32];
366 let config = create_client_config(fp);
367 assert!(config.alpn_protocols.is_empty());
368 }
369
370 #[test]
371 fn test_server_fingerprint_verifier_accepts_matching() {
372 install_crypto_provider();
373 let cert_key = generate_self_signed_cert().unwrap();
374 let verifier = FingerprintServerCertVerifier::new(cert_key.fingerprint);
375 let cert = CertificateDer::from(cert_key.cert_der);
376 let server_name = ServerName::try_from("rcp").unwrap();
377 let result = verifier.verify_server_cert(&cert, &[], &server_name, &[], UnixTime::now());
378 assert!(result.is_ok());
379 }
380
381 #[test]
382 fn test_server_fingerprint_verifier_rejects_mismatch() {
383 install_crypto_provider();
384 let cert_key = generate_self_signed_cert().unwrap();
385 let wrong_fingerprint = [0u8; 32];
387 let verifier = FingerprintServerCertVerifier::new(wrong_fingerprint);
388 let cert = CertificateDer::from(cert_key.cert_der);
389 let server_name = ServerName::try_from("rcp").unwrap();
390 let result = verifier.verify_server_cert(&cert, &[], &server_name, &[], UnixTime::now());
391 assert!(result.is_err());
392 match result {
394 Err(rustls::Error::InvalidCertificate(rustls::CertificateError::BadSignature)) => {}
395 other => panic!("expected BadSignature error, got: {:?}", other),
396 }
397 }
398
399 #[test]
400 fn test_client_fingerprint_verifier_accepts_matching() {
401 install_crypto_provider();
402 let cert_key = generate_self_signed_cert().unwrap();
403 let verifier = FingerprintClientCertVerifier::new(cert_key.fingerprint);
404 let cert = CertificateDer::from(cert_key.cert_der);
405 let result = verifier.verify_client_cert(&cert, &[], UnixTime::now());
406 assert!(result.is_ok());
407 }
408
409 #[test]
410 fn test_client_fingerprint_verifier_rejects_mismatch() {
411 install_crypto_provider();
412 let cert_key = generate_self_signed_cert().unwrap();
413 let wrong_fingerprint = [0u8; 32];
415 let verifier = FingerprintClientCertVerifier::new(wrong_fingerprint);
416 let cert = CertificateDer::from(cert_key.cert_der);
417 let result = verifier.verify_client_cert(&cert, &[], UnixTime::now());
418 assert!(result.is_err());
419 match result {
421 Err(rustls::Error::InvalidCertificate(rustls::CertificateError::BadSignature)) => {}
422 other => panic!("expected BadSignature error, got: {:?}", other),
423 }
424 }
425
426 #[test]
427 fn test_client_verifier_requires_auth() {
428 install_crypto_provider();
429 let verifier = FingerprintClientCertVerifier::new([0u8; 32]);
430 assert!(verifier.client_auth_mandatory());
431 }
432}
433
434#[cfg(test)]
435mod integration_tests {
436 use super::*;
437 use tokio::io::{AsyncReadExt, AsyncWriteExt};
438 use tokio::net::{TcpListener, TcpStream};
439 use tokio_rustls::{TlsAcceptor, TlsConnector};
440
441 fn install_crypto_provider() {
442 rustls::crypto::ring::default_provider()
443 .install_default()
444 .ok();
445 }
446
447 #[tokio::test]
449 async fn test_tls_handshake_success_with_matching_fingerprint() {
450 install_crypto_provider();
451 let server_cert = generate_self_signed_cert().unwrap();
453 let server_config = create_server_config(&server_cert).unwrap();
454 let acceptor = TlsAcceptor::from(server_config);
455 let client_config = create_client_config(server_cert.fingerprint);
457 let connector = TlsConnector::from(client_config);
458 let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
460 let addr = listener.local_addr().unwrap();
461 let server_acceptor = acceptor.clone();
463 let server_task = tokio::spawn(async move {
464 let (stream, _) = listener.accept().await.unwrap();
465 let mut tls_stream = server_acceptor.accept(stream).await.unwrap();
466 tls_stream.write_all(b"hello").await.unwrap();
467 tls_stream.shutdown().await.unwrap();
468 });
469 let stream = TcpStream::connect(addr).await.unwrap();
471 let server_name = ServerName::try_from("rcp").unwrap();
472 let mut tls_stream = connector.connect(server_name, stream).await.unwrap();
473 let mut buf = [0u8; 5];
474 tls_stream.read_exact(&mut buf).await.unwrap();
475 assert_eq!(&buf, b"hello");
476 server_task.await.unwrap();
477 }
478
479 #[tokio::test]
481 async fn test_tls_handshake_fails_with_wrong_server_fingerprint() {
482 install_crypto_provider();
483 let server_cert = generate_self_signed_cert().unwrap();
485 let server_config = create_server_config(&server_cert).unwrap();
486 let acceptor = TlsAcceptor::from(server_config);
487 let wrong_fingerprint = [0xAB; 32];
489 let client_config = create_client_config(wrong_fingerprint);
490 let connector = TlsConnector::from(client_config);
491 let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
493 let addr = listener.local_addr().unwrap();
494 let server_acceptor = acceptor.clone();
496 let server_task = tokio::spawn(async move {
497 let (stream, _) = listener.accept().await.unwrap();
498 let _ = server_acceptor.accept(stream).await;
500 });
501 let stream = TcpStream::connect(addr).await.unwrap();
503 let server_name = ServerName::try_from("rcp").unwrap();
504 let result = connector.connect(server_name, stream).await;
505 assert!(result.is_err(), "expected TLS handshake to fail");
506 let err = result.unwrap_err();
507 assert!(
509 err.to_string().contains("certificate")
510 || err.to_string().contains("Certificate")
511 || err.to_string().contains("invalid"),
512 "expected certificate error, got: {}",
513 err
514 );
515 server_task.await.unwrap();
516 }
517
518 #[tokio::test]
520 async fn test_mutual_tls_fails_with_wrong_client_fingerprint() {
521 install_crypto_provider();
522 let server_cert = generate_self_signed_cert().unwrap();
524 let client_cert = generate_self_signed_cert().unwrap();
525 let wrong_fingerprint = [0xCD; 32];
527 let server_config =
528 create_server_config_with_client_auth(&server_cert, wrong_fingerprint).unwrap();
529 let acceptor = TlsAcceptor::from(server_config);
530 let client_config =
532 create_client_config_with_cert(&client_cert, server_cert.fingerprint).unwrap();
533 let connector = TlsConnector::from(client_config);
534 let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
536 let addr = listener.local_addr().unwrap();
537 let server_acceptor = acceptor.clone();
539 let server_task = tokio::spawn(async move {
540 let (stream, _) = listener.accept().await.unwrap();
541 let result = server_acceptor.accept(stream).await;
542 assert!(result.is_err(), "expected server to reject client cert");
543 });
544 let stream = TcpStream::connect(addr).await.unwrap();
546 let server_name = ServerName::try_from("rcp").unwrap();
547 match connector.connect(server_name, stream).await {
550 Ok(mut tls_stream) => {
551 let mut buf = [0u8; 1];
554 let read_result = tls_stream.read(&mut buf).await;
555 assert!(
556 read_result.is_err() || read_result.unwrap() == 0,
557 "expected read to fail or return EOF after server rejection"
558 );
559 }
560 Err(_) => {
561 }
563 }
564 server_task.await.unwrap();
565 }
566
567 #[tokio::test]
569 async fn test_mutual_tls_success_with_matching_fingerprints() {
570 install_crypto_provider();
571 let server_cert = generate_self_signed_cert().unwrap();
573 let client_cert = generate_self_signed_cert().unwrap();
574 let server_config =
576 create_server_config_with_client_auth(&server_cert, client_cert.fingerprint).unwrap();
577 let acceptor = TlsAcceptor::from(server_config);
578 let client_config =
580 create_client_config_with_cert(&client_cert, server_cert.fingerprint).unwrap();
581 let connector = TlsConnector::from(client_config);
582 let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
584 let addr = listener.local_addr().unwrap();
585 let server_acceptor = acceptor.clone();
587 let server_task = tokio::spawn(async move {
588 let (stream, _) = listener.accept().await.unwrap();
589 let mut tls_stream = server_acceptor.accept(stream).await.unwrap();
590 tls_stream.write_all(b"mutual").await.unwrap();
591 tls_stream.shutdown().await.unwrap();
592 });
593 let stream = TcpStream::connect(addr).await.unwrap();
595 let server_name = ServerName::try_from("rcp").unwrap();
596 let mut tls_stream = connector.connect(server_name, stream).await.unwrap();
597 let mut buf = [0u8; 6];
598 tls_stream.read_exact(&mut buf).await.unwrap();
599 assert_eq!(&buf, b"mutual");
600 server_task.await.unwrap();
601 }
602
603 #[tokio::test]
609 async fn test_tls_handshake_fails_when_cert_replayed_without_private_key() {
610 install_crypto_provider();
611 let legit_cert = generate_self_signed_cert().unwrap();
613 let attacker_cert = generate_self_signed_cert().unwrap();
615 let attacker_signing_key = rustls::crypto::ring::sign::any_supported_type(
619 &PrivateKeyDer::try_from(attacker_cert.key_der.clone()).unwrap(),
620 )
621 .unwrap();
622 let replayed = std::sync::Arc::new(rustls::sign::CertifiedKey::new(
623 vec![CertificateDer::from(legit_cert.cert_der.clone())],
624 attacker_signing_key,
625 ));
626 #[derive(Debug)]
627 struct StaticResolver(std::sync::Arc<rustls::sign::CertifiedKey>);
628 impl rustls::server::ResolvesServerCert for StaticResolver {
629 fn resolve(
630 &self,
631 _client_hello: rustls::server::ClientHello<'_>,
632 ) -> Option<std::sync::Arc<rustls::sign::CertifiedKey>> {
633 Some(self.0.clone())
634 }
635 }
636 let server_config = ServerConfig::builder()
637 .with_no_client_auth()
638 .with_cert_resolver(std::sync::Arc::new(StaticResolver(replayed)));
639 let acceptor = TlsAcceptor::from(std::sync::Arc::new(server_config));
640 let client_config = create_client_config(legit_cert.fingerprint);
642 let connector = TlsConnector::from(client_config);
643 let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
644 let addr = listener.local_addr().unwrap();
645 let server_acceptor = acceptor.clone();
646 let server_task = tokio::spawn(async move {
647 let (stream, _) = listener.accept().await.unwrap();
648 let _ = server_acceptor.accept(stream).await;
650 });
651 let stream = TcpStream::connect(addr).await.unwrap();
652 let server_name = ServerName::try_from("rcp").unwrap();
653 let result = connector.connect(server_name, stream).await;
654 assert!(
655 result.is_err(),
656 "handshake must fail: cert fingerprint matched but the peer did not prove possession \
657 of the private key"
658 );
659 server_task.await.unwrap();
660 }
661
662 #[tokio::test]
667 async fn test_mutual_tls_fails_when_client_cert_replayed_without_private_key() {
668 install_crypto_provider();
669 let server_cert = generate_self_signed_cert().unwrap();
670 let legit_client_cert = generate_self_signed_cert().unwrap();
672 let attacker_cert = generate_self_signed_cert().unwrap();
674 let server_config =
676 create_server_config_with_client_auth(&server_cert, legit_client_cert.fingerprint)
677 .unwrap();
678 let acceptor = TlsAcceptor::from(server_config);
679 let attacker_signing_key = rustls::crypto::ring::sign::any_supported_type(
681 &PrivateKeyDer::try_from(attacker_cert.key_der.clone()).unwrap(),
682 )
683 .unwrap();
684 let replayed = std::sync::Arc::new(rustls::sign::CertifiedKey::new(
685 vec![CertificateDer::from(legit_client_cert.cert_der.clone())],
686 attacker_signing_key,
687 ));
688 #[derive(Debug)]
689 struct ReplayResolver(std::sync::Arc<rustls::sign::CertifiedKey>);
690 impl rustls::client::ResolvesClientCert for ReplayResolver {
691 fn resolve(
692 &self,
693 _root_hint_subjects: &[&[u8]],
694 _sigschemes: &[SignatureScheme],
695 ) -> Option<std::sync::Arc<rustls::sign::CertifiedKey>> {
696 Some(self.0.clone())
697 }
698 fn has_certs(&self) -> bool {
699 true
700 }
701 }
702 let server_verifier =
704 std::sync::Arc::new(FingerprintServerCertVerifier::new(server_cert.fingerprint));
705 let client_config = ClientConfig::builder()
706 .dangerous()
707 .with_custom_certificate_verifier(server_verifier)
708 .with_client_cert_resolver(std::sync::Arc::new(ReplayResolver(replayed)));
709 let connector = TlsConnector::from(std::sync::Arc::new(client_config));
710 let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
711 let addr = listener.local_addr().unwrap();
712 let server_acceptor = acceptor.clone();
713 let server_task = tokio::spawn(async move {
714 let (stream, _) = listener.accept().await.unwrap();
715 let result = server_acceptor.accept(stream).await;
716 assert!(
717 result.is_err(),
718 "server must reject a client that replayed the pinned certificate without its key"
719 );
720 });
721 let stream = TcpStream::connect(addr).await.unwrap();
722 let server_name = ServerName::try_from("rcp").unwrap();
723 if let Ok(mut tls_stream) = connector.connect(server_name, stream).await {
727 let mut buf = [0u8; 1];
728 let read_result = tls_stream.read(&mut buf).await;
729 assert!(
730 read_result.is_err() || read_result.unwrap() == 0,
731 "expected read to fail or EOF after the server rejects the replayed client cert"
732 );
733 }
734 server_task.await.unwrap();
735 }
736
737 #[tokio::test]
741 async fn test_tls_handshake_fails_when_peer_offers_only_tls12() {
742 install_crypto_provider();
743 let server_cert = generate_self_signed_cert().unwrap();
744 let server_config = create_server_config(&server_cert).unwrap();
746 let acceptor = TlsAcceptor::from(server_config);
747 let verifier =
749 std::sync::Arc::new(FingerprintServerCertVerifier::new(server_cert.fingerprint));
750 let client_config =
751 ClientConfig::builder_with_protocol_versions(&[&rustls::version::TLS12])
752 .dangerous()
753 .with_custom_certificate_verifier(verifier)
754 .with_no_client_auth();
755 let connector = TlsConnector::from(std::sync::Arc::new(client_config));
756 let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
757 let addr = listener.local_addr().unwrap();
758 let server_acceptor = acceptor.clone();
759 let server_task = tokio::spawn(async move {
760 let (stream, _) = listener.accept().await.unwrap();
761 let _ = server_acceptor.accept(stream).await;
763 });
764 let stream = TcpStream::connect(addr).await.unwrap();
765 let server_name = ServerName::try_from("rcp").unwrap();
766 let result = connector.connect(server_name, stream).await;
767 assert!(
768 result.is_err(),
769 "a server pinned to TLS 1.3 must reject a client that offers only TLS 1.2"
770 );
771 server_task.await.unwrap();
772 }
773}