//! Tests for configuring and using a [`ServerCertVerifier`] for a client. #![cfg(feature = "dangerous_configuration")] mod common; use crate::common::{ do_handshake, do_handshake_until_both_error, make_client_config_with_versions, make_pair_for_arc_configs, make_server_config, ErrorFromPeer, ALL_KEY_TYPES, }; use rustls::client::{ HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier, WebPkiVerifier, }; use rustls::internal::msgs::handshake::DigitallySignedStruct; use rustls::AlertDescription; use rustls::{Certificate, Error, SignatureScheme}; use std::sync::Arc; #[test] fn client_can_override_certificate_verification() { for kt in ALL_KEY_TYPES.iter() { let verifier = Arc::new(MockServerVerifier::accepts_anything()); let server_config = Arc::new(make_server_config(*kt)); for version in rustls::ALL_VERSIONS { let mut client_config = make_client_config_with_versions(*kt, &[version]); client_config .dangerous() .set_certificate_verifier(verifier.clone()); let (mut client, mut server) = make_pair_for_arc_configs(&Arc::new(client_config), &server_config); do_handshake(&mut client, &mut server); } } } #[test] fn client_can_override_certificate_verification_and_reject_certificate() { for kt in ALL_KEY_TYPES.iter() { let verifier = Arc::new(MockServerVerifier::rejects_certificate( Error::CorruptMessage, )); let server_config = Arc::new(make_server_config(*kt)); for version in rustls::ALL_VERSIONS { let mut client_config = make_client_config_with_versions(*kt, &[version]); client_config .dangerous() .set_certificate_verifier(verifier.clone()); let (mut client, mut server) = make_pair_for_arc_configs(&Arc::new(client_config), &server_config); let errs = do_handshake_until_both_error(&mut client, &mut server); assert_eq!( errs, Err(vec![ ErrorFromPeer::Client(Error::CorruptMessage), ErrorFromPeer::Server(Error::AlertReceived(AlertDescription::BadCertificate)) ]) ); } } } #[cfg(feature = "tls12")] #[test] fn client_can_override_certificate_verification_and_reject_tls12_signatures() { for kt in ALL_KEY_TYPES.iter() { let mut client_config = make_client_config_with_versions(*kt, &[&rustls::version::TLS12]); let verifier = Arc::new(MockServerVerifier::rejects_tls12_signatures( Error::CorruptMessage, )); client_config .dangerous() .set_certificate_verifier(verifier); let server_config = Arc::new(make_server_config(*kt)); let (mut client, mut server) = make_pair_for_arc_configs(&Arc::new(client_config), &server_config); let errs = do_handshake_until_both_error(&mut client, &mut server); assert_eq!( errs, Err(vec![ ErrorFromPeer::Client(Error::CorruptMessage), ErrorFromPeer::Server(Error::AlertReceived(AlertDescription::BadCertificate)) ]) ); } } #[test] fn client_can_override_certificate_verification_and_reject_tls13_signatures() { for kt in ALL_KEY_TYPES.iter() { let mut client_config = make_client_config_with_versions(*kt, &[&rustls::version::TLS13]); let verifier = Arc::new(MockServerVerifier::rejects_tls13_signatures( Error::CorruptMessage, )); client_config .dangerous() .set_certificate_verifier(verifier); let server_config = Arc::new(make_server_config(*kt)); let (mut client, mut server) = make_pair_for_arc_configs(&Arc::new(client_config), &server_config); let errs = do_handshake_until_both_error(&mut client, &mut server); assert_eq!( errs, Err(vec![ ErrorFromPeer::Client(Error::CorruptMessage), ErrorFromPeer::Server(Error::AlertReceived(AlertDescription::BadCertificate)) ]) ); } } #[test] fn client_can_override_certificate_verification_and_offer_no_signature_schemes() { for kt in ALL_KEY_TYPES.iter() { let verifier = Arc::new(MockServerVerifier::offers_no_signature_schemes()); let server_config = Arc::new(make_server_config(*kt)); for version in rustls::ALL_VERSIONS { let mut client_config = make_client_config_with_versions(*kt, &[version]); client_config .dangerous() .set_certificate_verifier(verifier.clone()); let (mut client, mut server) = make_pair_for_arc_configs(&Arc::new(client_config), &server_config); let errs = do_handshake_until_both_error(&mut client, &mut server); assert_eq!( errs, Err(vec![ ErrorFromPeer::Server(Error::PeerIncompatibleError( "no overlapping sigschemes".into() )), ErrorFromPeer::Client(Error::AlertReceived(AlertDescription::HandshakeFailure)), ]) ); } } } pub struct MockServerVerifier { cert_rejection_error: Option, tls12_signature_error: Option, tls13_signature_error: Option, wants_scts: bool, signature_schemes: Vec, } impl ServerCertVerifier for MockServerVerifier { fn verify_server_cert( &self, end_entity: &rustls::Certificate, intermediates: &[rustls::Certificate], server_name: &rustls::ServerName, scts: &mut dyn Iterator, oscp_response: &[u8], now: std::time::SystemTime, ) -> Result { let scts: Vec> = scts.map(|x| x.to_owned()).collect(); println!( "verify_server_cert({:?}, {:?}, {:?}, {:?}, {:?}, {:?})", end_entity, intermediates, server_name, scts, oscp_response, now ); if let Some(error) = &self.cert_rejection_error { Err(error.clone()) } else { Ok(ServerCertVerified::assertion()) } } fn verify_tls12_signature( &self, message: &[u8], cert: &Certificate, dss: &DigitallySignedStruct, ) -> Result { println!( "verify_tls12_signature({:?}, {:?}, {:?})", message, cert, dss ); if let Some(error) = &self.tls12_signature_error { Err(error.clone()) } else { Ok(HandshakeSignatureValid::assertion()) } } fn verify_tls13_signature( &self, message: &[u8], cert: &Certificate, dss: &DigitallySignedStruct, ) -> Result { println!( "verify_tls13_signature({:?}, {:?}, {:?})", message, cert, dss ); if let Some(error) = &self.tls13_signature_error { Err(error.clone()) } else { Ok(HandshakeSignatureValid::assertion()) } } fn supported_verify_schemes(&self) -> Vec { self.signature_schemes.clone() } fn request_scts(&self) -> bool { println!("request_scts? {:?}", self.wants_scts); self.wants_scts } } impl MockServerVerifier { pub fn accepts_anything() -> Self { MockServerVerifier { cert_rejection_error: None, ..Default::default() } } pub fn rejects_certificate(err: Error) -> Self { MockServerVerifier { cert_rejection_error: Some(err), ..Default::default() } } pub fn rejects_tls12_signatures(err: Error) -> Self { MockServerVerifier { tls12_signature_error: Some(err), ..Default::default() } } pub fn rejects_tls13_signatures(err: Error) -> Self { MockServerVerifier { tls13_signature_error: Some(err), ..Default::default() } } pub fn offers_no_signature_schemes() -> Self { MockServerVerifier { signature_schemes: vec![], ..Default::default() } } } impl Default for MockServerVerifier { fn default() -> Self { MockServerVerifier { cert_rejection_error: None, tls12_signature_error: None, tls13_signature_error: None, wants_scts: false, signature_schemes: WebPkiVerifier::verification_schemes(), } } }