mirror of https://github.com/ctz/rustls
278 lines
9.1 KiB
Rust
278 lines
9.1 KiB
Rust
//! Tests for configuring and using a [`ServerCertVerifier`] for a client.
|
|
|
|
#![cfg(feature = "dangerous_configuration")]
|
|
|
|
mod common;
|
|
use crate::common::{
|
|
assert_debug_eq, 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, Certificate, Error, InvalidMessage, 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::InvalidMessage(InvalidMessage::HandshakePayloadTooLarge),
|
|
));
|
|
|
|
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_debug_eq(
|
|
errs,
|
|
Err(vec![
|
|
ErrorFromPeer::Client(Error::InvalidMessage(
|
|
InvalidMessage::HandshakePayloadTooLarge,
|
|
)),
|
|
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::InvalidMessage(InvalidMessage::HandshakePayloadTooLarge),
|
|
));
|
|
|
|
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_debug_eq(
|
|
errs,
|
|
Err(vec![
|
|
ErrorFromPeer::Client(Error::InvalidMessage(
|
|
InvalidMessage::HandshakePayloadTooLarge,
|
|
)),
|
|
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::InvalidMessage(InvalidMessage::HandshakePayloadTooLarge),
|
|
));
|
|
|
|
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_debug_eq(
|
|
errs,
|
|
Err(vec![
|
|
ErrorFromPeer::Client(Error::InvalidMessage(
|
|
InvalidMessage::HandshakePayloadTooLarge,
|
|
)),
|
|
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_debug_eq(
|
|
errs,
|
|
Err(vec![
|
|
ErrorFromPeer::Server(Error::PeerIncompatible(
|
|
rustls::PeerIncompatible::NoSignatureSchemesInCommon,
|
|
)),
|
|
ErrorFromPeer::Client(Error::AlertReceived(AlertDescription::HandshakeFailure)),
|
|
]),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct MockServerVerifier {
|
|
cert_rejection_error: Option<Error>,
|
|
tls12_signature_error: Option<Error>,
|
|
tls13_signature_error: Option<Error>,
|
|
wants_scts: bool,
|
|
signature_schemes: Vec<SignatureScheme>,
|
|
}
|
|
|
|
impl ServerCertVerifier for MockServerVerifier {
|
|
fn verify_server_cert(
|
|
&self,
|
|
end_entity: &rustls::Certificate,
|
|
intermediates: &[rustls::Certificate],
|
|
server_name: &rustls::ServerName,
|
|
scts: &mut dyn Iterator<Item = &[u8]>,
|
|
oscp_response: &[u8],
|
|
now: std::time::SystemTime,
|
|
) -> Result<ServerCertVerified, Error> {
|
|
let scts: Vec<Vec<u8>> = 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<HandshakeSignatureValid, Error> {
|
|
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<HandshakeSignatureValid, Error> {
|
|
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<SignatureScheme> {
|
|
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(),
|
|
}
|
|
}
|
|
}
|