Expand Shadowsocks runtime compatibility
This commit is contained in:
parent
d1638726ca
commit
4d1f589280
167 changed files with 57173 additions and 1640 deletions
4382
third_party/rustls-fork-shadow-tls/tests/api.rs
vendored
Normal file
4382
third_party/rustls-fork-shadow-tls/tests/api.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
18
third_party/rustls-fork-shadow-tls/tests/bogo.rs
vendored
Normal file
18
third_party/rustls-fork-shadow-tls/tests/bogo.rs
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// Runs the bogo test suite, in the form of a rust test.
|
||||
// Note that bogo requires a golang environment to build
|
||||
// and run.
|
||||
|
||||
#[test]
|
||||
#[cfg(all(coverage, feature = "quic", feature = "dangerous_configuration"))]
|
||||
fn run_bogo_tests() {
|
||||
use std::process::Command;
|
||||
|
||||
let rc = Command::new("./runme")
|
||||
.current_dir("../bogo")
|
||||
.spawn()
|
||||
.expect("cannot run bogo/runme")
|
||||
.wait()
|
||||
.expect("cannot wait for bogo");
|
||||
|
||||
assert!(rc.success(), "bogo exited non-zero");
|
||||
}
|
||||
324
third_party/rustls-fork-shadow-tls/tests/client_cert_verifier.rs
vendored
Normal file
324
third_party/rustls-fork-shadow-tls/tests/client_cert_verifier.rs
vendored
Normal file
|
|
@ -0,0 +1,324 @@
|
|||
//! Tests for configuring and using a [`ClientCertVerifier`] for a server.
|
||||
|
||||
#![cfg(feature = "dangerous_configuration")]
|
||||
|
||||
mod common;
|
||||
|
||||
use crate::common::{
|
||||
dns_name, do_handshake_until_both_error, do_handshake_until_error, get_client_root_store,
|
||||
make_client_config_with_versions, make_client_config_with_versions_with_auth,
|
||||
make_pair_for_arc_configs, ErrorFromPeer, KeyType, ALL_KEY_TYPES,
|
||||
};
|
||||
use rustls::client::WebPkiVerifier;
|
||||
use rustls::internal::msgs::base::PayloadU16;
|
||||
use rustls::server::{ClientCertVerified, ClientCertVerifier};
|
||||
use rustls::AlertDescription;
|
||||
use rustls::ContentType;
|
||||
use rustls::{
|
||||
Certificate, ClientConnection, DistinguishedNames, Error, ServerConfig, ServerConnection,
|
||||
SignatureScheme,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
// Client is authorized!
|
||||
fn ver_ok() -> Result<ClientCertVerified, Error> {
|
||||
Ok(rustls::server::ClientCertVerified::assertion())
|
||||
}
|
||||
|
||||
// Use when we shouldn't even attempt verification
|
||||
fn ver_unreachable() -> Result<ClientCertVerified, Error> {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
// Verifier that returns an error that we can expect
|
||||
fn ver_err() -> Result<ClientCertVerified, Error> {
|
||||
Err(Error::General("test err".to_string()))
|
||||
}
|
||||
|
||||
fn server_config_with_verifier(
|
||||
kt: KeyType,
|
||||
client_cert_verifier: MockClientVerifier,
|
||||
) -> ServerConfig {
|
||||
ServerConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_client_cert_verifier(Arc::new(client_cert_verifier))
|
||||
.with_single_cert(kt.get_chain(), kt.get_key())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
// Happy path, we resolve to a root, it is verified OK, should be able to connect
|
||||
fn client_verifier_works() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let client_verifier = MockClientVerifier {
|
||||
verified: ver_ok,
|
||||
subjects: Some(
|
||||
get_client_root_store(*kt)
|
||||
.roots
|
||||
.iter()
|
||||
.map(|r| PayloadU16(r.subject().to_vec()))
|
||||
.collect(),
|
||||
),
|
||||
mandatory: Some(true),
|
||||
offered_schemes: None,
|
||||
};
|
||||
|
||||
let server_config = server_config_with_verifier(*kt, client_verifier);
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let client_config = make_client_config_with_versions_with_auth(*kt, &[version]);
|
||||
let (mut client, mut server) =
|
||||
make_pair_for_arc_configs(&Arc::new(client_config.clone()), &server_config);
|
||||
let err = do_handshake_until_error(&mut client, &mut server);
|
||||
assert_eq!(err, Ok(()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Server offers no verification schemes
|
||||
#[test]
|
||||
fn client_verifier_no_schemes() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let client_verifier = MockClientVerifier {
|
||||
verified: ver_ok,
|
||||
subjects: Some(
|
||||
get_client_root_store(*kt)
|
||||
.roots
|
||||
.iter()
|
||||
.map(|r| PayloadU16(r.subject().to_vec()))
|
||||
.collect(),
|
||||
),
|
||||
mandatory: Some(true),
|
||||
offered_schemes: Some(vec![]),
|
||||
};
|
||||
|
||||
let server_config = server_config_with_verifier(*kt, client_verifier);
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let client_config = make_client_config_with_versions_with_auth(*kt, &[version]);
|
||||
let (mut client, mut server) =
|
||||
make_pair_for_arc_configs(&Arc::new(client_config.clone()), &server_config);
|
||||
let err = do_handshake_until_error(&mut client, &mut server);
|
||||
assert_eq!(
|
||||
err,
|
||||
Err(ErrorFromPeer::Client(Error::CorruptMessagePayload(
|
||||
ContentType::Handshake
|
||||
)))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Common case, we do not find a root store to resolve to
|
||||
#[test]
|
||||
fn client_verifier_no_root() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let client_verifier = MockClientVerifier {
|
||||
verified: ver_ok,
|
||||
subjects: None,
|
||||
mandatory: Some(true),
|
||||
offered_schemes: None,
|
||||
};
|
||||
|
||||
let server_config = server_config_with_verifier(*kt, client_verifier);
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let client_config = make_client_config_with_versions_with_auth(*kt, &[version]);
|
||||
let mut server = ServerConnection::new(Arc::clone(&server_config)).unwrap();
|
||||
let mut client =
|
||||
ClientConnection::new(Arc::new(client_config), dns_name("notlocalhost")).unwrap();
|
||||
let errs = do_handshake_until_both_error(&mut client, &mut server);
|
||||
assert_eq!(
|
||||
errs,
|
||||
Err(vec![
|
||||
ErrorFromPeer::Server(Error::General(
|
||||
"client rejected by client_auth_root_subjects".into()
|
||||
)),
|
||||
ErrorFromPeer::Client(Error::AlertReceived(AlertDescription::AccessDenied))
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we cannot resolve a root, we cannot decide if auth is mandatory
|
||||
#[test]
|
||||
fn client_verifier_no_auth_no_root() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let client_verifier = MockClientVerifier {
|
||||
verified: ver_unreachable,
|
||||
subjects: None,
|
||||
mandatory: Some(true),
|
||||
offered_schemes: None,
|
||||
};
|
||||
|
||||
let server_config = server_config_with_verifier(*kt, client_verifier);
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let client_config = make_client_config_with_versions(*kt, &[version]);
|
||||
let mut server = ServerConnection::new(Arc::clone(&server_config)).unwrap();
|
||||
let mut client =
|
||||
ClientConnection::new(Arc::new(client_config), dns_name("notlocalhost")).unwrap();
|
||||
let errs = do_handshake_until_both_error(&mut client, &mut server);
|
||||
assert_eq!(
|
||||
errs,
|
||||
Err(vec![
|
||||
ErrorFromPeer::Server(Error::General(
|
||||
"client rejected by client_auth_root_subjects".into()
|
||||
)),
|
||||
ErrorFromPeer::Client(Error::AlertReceived(AlertDescription::AccessDenied))
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we do have a root, we must do auth
|
||||
#[test]
|
||||
fn client_verifier_no_auth_yes_root() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let client_verifier = MockClientVerifier {
|
||||
verified: ver_unreachable,
|
||||
subjects: Some(
|
||||
get_client_root_store(*kt)
|
||||
.roots
|
||||
.iter()
|
||||
.map(|r| PayloadU16(r.subject().to_vec()))
|
||||
.collect(),
|
||||
),
|
||||
mandatory: Some(true),
|
||||
offered_schemes: None,
|
||||
};
|
||||
|
||||
let server_config = server_config_with_verifier(*kt, client_verifier);
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let client_config = make_client_config_with_versions(*kt, &[version]);
|
||||
let mut server = ServerConnection::new(Arc::clone(&server_config)).unwrap();
|
||||
let mut client =
|
||||
ClientConnection::new(Arc::new(client_config), dns_name("localhost")).unwrap();
|
||||
let errs = do_handshake_until_both_error(&mut client, &mut server);
|
||||
assert_eq!(
|
||||
errs,
|
||||
Err(vec![
|
||||
ErrorFromPeer::Server(Error::NoCertificatesPresented),
|
||||
ErrorFromPeer::Client(Error::AlertReceived(
|
||||
AlertDescription::CertificateRequired
|
||||
))
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
// Triple checks we propagate the rustls::Error through
|
||||
fn client_verifier_fails_properly() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let client_verifier = MockClientVerifier {
|
||||
verified: ver_err,
|
||||
subjects: Some(
|
||||
get_client_root_store(*kt)
|
||||
.roots
|
||||
.iter()
|
||||
.map(|r| PayloadU16(r.subject().to_vec()))
|
||||
.collect(),
|
||||
),
|
||||
mandatory: Some(true),
|
||||
offered_schemes: None,
|
||||
};
|
||||
|
||||
let server_config = server_config_with_verifier(*kt, client_verifier);
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let client_config = make_client_config_with_versions_with_auth(*kt, &[version]);
|
||||
let mut server = ServerConnection::new(Arc::clone(&server_config)).unwrap();
|
||||
let mut client =
|
||||
ClientConnection::new(Arc::new(client_config), dns_name("localhost")).unwrap();
|
||||
let err = do_handshake_until_error(&mut client, &mut server);
|
||||
assert_eq!(
|
||||
err,
|
||||
Err(ErrorFromPeer::Server(Error::General("test err".into())))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
// If a verifier returns a None on Mandatory-ness, then we error out
|
||||
fn client_verifier_must_determine_client_auth_requirement_to_continue() {
|
||||
for kt in ALL_KEY_TYPES.iter() {
|
||||
let client_verifier = MockClientVerifier {
|
||||
verified: ver_ok,
|
||||
subjects: Some(
|
||||
get_client_root_store(*kt)
|
||||
.roots
|
||||
.iter()
|
||||
.map(|r| PayloadU16(r.subject().to_vec()))
|
||||
.collect(),
|
||||
),
|
||||
mandatory: None,
|
||||
offered_schemes: None,
|
||||
};
|
||||
|
||||
let server_config = server_config_with_verifier(*kt, client_verifier);
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let client_config = make_client_config_with_versions_with_auth(*kt, &[version]);
|
||||
let mut server = ServerConnection::new(Arc::clone(&server_config)).unwrap();
|
||||
let mut client =
|
||||
ClientConnection::new(Arc::new(client_config), dns_name("localhost")).unwrap();
|
||||
let errs = do_handshake_until_both_error(&mut client, &mut server);
|
||||
assert_eq!(
|
||||
errs,
|
||||
Err(vec![
|
||||
ErrorFromPeer::Server(Error::General(
|
||||
"client rejected by client_auth_mandatory".into()
|
||||
)),
|
||||
ErrorFromPeer::Client(Error::AlertReceived(AlertDescription::AccessDenied))
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MockClientVerifier {
|
||||
pub verified: fn() -> Result<ClientCertVerified, Error>,
|
||||
pub subjects: Option<DistinguishedNames>,
|
||||
pub mandatory: Option<bool>,
|
||||
pub offered_schemes: Option<Vec<SignatureScheme>>,
|
||||
}
|
||||
|
||||
impl ClientCertVerifier for MockClientVerifier {
|
||||
fn client_auth_mandatory(&self) -> Option<bool> {
|
||||
self.mandatory
|
||||
}
|
||||
|
||||
fn client_auth_root_subjects(&self) -> Option<DistinguishedNames> {
|
||||
self.subjects.as_ref().cloned()
|
||||
}
|
||||
|
||||
fn verify_client_cert(
|
||||
&self,
|
||||
_end_entity: &Certificate,
|
||||
_intermediates: &[Certificate],
|
||||
_now: std::time::SystemTime,
|
||||
) -> Result<ClientCertVerified, Error> {
|
||||
(self.verified)()
|
||||
}
|
||||
|
||||
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
|
||||
if let Some(schemes) = &self.offered_schemes {
|
||||
schemes.clone()
|
||||
} else {
|
||||
WebPkiVerifier::verification_schemes()
|
||||
}
|
||||
}
|
||||
}
|
||||
474
third_party/rustls-fork-shadow-tls/tests/common/mod.rs
vendored
Normal file
474
third_party/rustls-fork-shadow-tls/tests/common/mod.rs
vendored
Normal file
|
|
@ -0,0 +1,474 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::io;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::sync::Arc;
|
||||
|
||||
use rustls::internal::msgs::codec::Reader;
|
||||
use rustls::internal::msgs::message::{Message, OpaqueMessage, PlainMessage};
|
||||
use rustls::server::AllowAnyAuthenticatedClient;
|
||||
use rustls::Connection;
|
||||
use rustls::Error;
|
||||
use rustls::RootCertStore;
|
||||
use rustls::{Certificate, PrivateKey};
|
||||
use rustls::{ClientConfig, ClientConnection};
|
||||
use rustls::{ConnectionCommon, ServerConfig, ServerConnection, SideData};
|
||||
|
||||
macro_rules! embed_files {
|
||||
(
|
||||
$(
|
||||
($name:ident, $keytype:expr, $path:expr);
|
||||
)+
|
||||
) => {
|
||||
$(
|
||||
const $name: &'static [u8] = include_bytes!(
|
||||
concat!("../../../test-ca/", $keytype, "/", $path));
|
||||
)+
|
||||
|
||||
pub fn bytes_for(keytype: &str, path: &str) -> &'static [u8] {
|
||||
match (keytype, path) {
|
||||
$(
|
||||
($keytype, $path) => $name,
|
||||
)+
|
||||
_ => panic!("unknown keytype {} with path {}", keytype, path),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
embed_files! {
|
||||
(ECDSA_CA_CERT, "ecdsa", "ca.cert");
|
||||
(ECDSA_CA_DER, "ecdsa", "ca.der");
|
||||
(ECDSA_CA_KEY, "ecdsa", "ca.key");
|
||||
(ECDSA_CLIENT_CERT, "ecdsa", "client.cert");
|
||||
(ECDSA_CLIENT_CHAIN, "ecdsa", "client.chain");
|
||||
(ECDSA_CLIENT_FULLCHAIN, "ecdsa", "client.fullchain");
|
||||
(ECDSA_CLIENT_KEY, "ecdsa", "client.key");
|
||||
(ECDSA_CLIENT_REQ, "ecdsa", "client.req");
|
||||
(ECDSA_END_CERT, "ecdsa", "end.cert");
|
||||
(ECDSA_END_CHAIN, "ecdsa", "end.chain");
|
||||
(ECDSA_END_FULLCHAIN, "ecdsa", "end.fullchain");
|
||||
(ECDSA_END_KEY, "ecdsa", "end.key");
|
||||
(ECDSA_END_REQ, "ecdsa", "end.req");
|
||||
(ECDSA_INTER_CERT, "ecdsa", "inter.cert");
|
||||
(ECDSA_INTER_KEY, "ecdsa", "inter.key");
|
||||
(ECDSA_INTER_REQ, "ecdsa", "inter.req");
|
||||
(ECDSA_NISTP256_PEM, "ecdsa", "nistp256.pem");
|
||||
(ECDSA_NISTP384_PEM, "ecdsa", "nistp384.pem");
|
||||
|
||||
(EDDSA_CA_CERT, "eddsa", "ca.cert");
|
||||
(EDDSA_CA_DER, "eddsa", "ca.der");
|
||||
(EDDSA_CA_KEY, "eddsa", "ca.key");
|
||||
(EDDSA_CLIENT_CERT, "eddsa", "client.cert");
|
||||
(EDDSA_CLIENT_CHAIN, "eddsa", "client.chain");
|
||||
(EDDSA_CLIENT_FULLCHAIN, "eddsa", "client.fullchain");
|
||||
(EDDSA_CLIENT_KEY, "eddsa", "client.key");
|
||||
(EDDSA_CLIENT_REQ, "eddsa", "client.req");
|
||||
(EDDSA_END_CERT, "eddsa", "end.cert");
|
||||
(EDDSA_END_CHAIN, "eddsa", "end.chain");
|
||||
(EDDSA_END_FULLCHAIN, "eddsa", "end.fullchain");
|
||||
(EDDSA_END_KEY, "eddsa", "end.key");
|
||||
(EDDSA_END_REQ, "eddsa", "end.req");
|
||||
(EDDSA_INTER_CERT, "eddsa", "inter.cert");
|
||||
(EDDSA_INTER_KEY, "eddsa", "inter.key");
|
||||
(EDDSA_INTER_REQ, "eddsa", "inter.req");
|
||||
|
||||
(RSA_CA_CERT, "rsa", "ca.cert");
|
||||
(RSA_CA_DER, "rsa", "ca.der");
|
||||
(RSA_CA_KEY, "rsa", "ca.key");
|
||||
(RSA_CLIENT_CERT, "rsa", "client.cert");
|
||||
(RSA_CLIENT_CHAIN, "rsa", "client.chain");
|
||||
(RSA_CLIENT_FULLCHAIN, "rsa", "client.fullchain");
|
||||
(RSA_CLIENT_KEY, "rsa", "client.key");
|
||||
(RSA_CLIENT_REQ, "rsa", "client.req");
|
||||
(RSA_CLIENT_RSA, "rsa", "client.rsa");
|
||||
(RSA_END_CERT, "rsa", "end.cert");
|
||||
(RSA_END_CHAIN, "rsa", "end.chain");
|
||||
(RSA_END_FULLCHAIN, "rsa", "end.fullchain");
|
||||
(RSA_END_KEY, "rsa", "end.key");
|
||||
(RSA_END_REQ, "rsa", "end.req");
|
||||
(RSA_END_RSA, "rsa", "end.rsa");
|
||||
(RSA_INTER_CERT, "rsa", "inter.cert");
|
||||
(RSA_INTER_KEY, "rsa", "inter.key");
|
||||
(RSA_INTER_REQ, "rsa", "inter.req");
|
||||
}
|
||||
|
||||
pub fn transfer(
|
||||
left: &mut (impl DerefMut + Deref<Target = ConnectionCommon<impl SideData>>),
|
||||
right: &mut (impl DerefMut + Deref<Target = ConnectionCommon<impl SideData>>),
|
||||
) -> usize {
|
||||
let mut buf = [0u8; 262144];
|
||||
let mut total = 0;
|
||||
|
||||
while left.wants_write() {
|
||||
let sz = {
|
||||
let into_buf: &mut dyn io::Write = &mut &mut buf[..];
|
||||
left.write_tls(into_buf).unwrap()
|
||||
};
|
||||
total += sz;
|
||||
if sz == 0 {
|
||||
return total;
|
||||
}
|
||||
|
||||
let mut offs = 0;
|
||||
loop {
|
||||
let from_buf: &mut dyn io::Read = &mut &buf[offs..sz];
|
||||
offs += right.read_tls(from_buf).unwrap();
|
||||
if sz == offs {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
total
|
||||
}
|
||||
|
||||
pub fn transfer_eof(conn: &mut (impl DerefMut + Deref<Target = ConnectionCommon<impl SideData>>)) {
|
||||
let empty_buf = [0u8; 0];
|
||||
let empty_cursor: &mut dyn io::Read = &mut &empty_buf[..];
|
||||
let sz = conn.read_tls(empty_cursor).unwrap();
|
||||
assert_eq!(sz, 0);
|
||||
}
|
||||
|
||||
pub enum Altered {
|
||||
/// message has been edited in-place (or is unchanged)
|
||||
InPlace,
|
||||
/// send these raw bytes instead of the message.
|
||||
Raw(Vec<u8>),
|
||||
}
|
||||
|
||||
pub fn transfer_altered<F>(left: &mut Connection, filter: F, right: &mut Connection) -> usize
|
||||
where
|
||||
F: Fn(&mut Message) -> Altered,
|
||||
{
|
||||
let mut buf = [0u8; 262144];
|
||||
let mut total = 0;
|
||||
|
||||
while left.wants_write() {
|
||||
let sz = {
|
||||
let into_buf: &mut dyn io::Write = &mut &mut buf[..];
|
||||
left.write_tls(into_buf).unwrap()
|
||||
};
|
||||
total += sz;
|
||||
if sz == 0 {
|
||||
return total;
|
||||
}
|
||||
|
||||
let mut reader = Reader::init(&buf[..sz]);
|
||||
while reader.any_left() {
|
||||
let message = OpaqueMessage::read(&mut reader).unwrap();
|
||||
let mut message = Message::try_from(message.into_plain_message()).unwrap();
|
||||
let message_enc = match filter(&mut message) {
|
||||
Altered::InPlace => PlainMessage::from(message)
|
||||
.into_unencrypted_opaque()
|
||||
.encode(),
|
||||
Altered::Raw(data) => data,
|
||||
};
|
||||
|
||||
let message_enc_reader: &mut dyn io::Read = &mut &message_enc[..];
|
||||
let len = right
|
||||
.read_tls(message_enc_reader)
|
||||
.unwrap();
|
||||
assert_eq!(len, message_enc.len());
|
||||
}
|
||||
}
|
||||
|
||||
total
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum KeyType {
|
||||
Rsa,
|
||||
Ecdsa,
|
||||
Ed25519,
|
||||
}
|
||||
|
||||
pub static ALL_KEY_TYPES: [KeyType; 3] = [KeyType::Rsa, KeyType::Ecdsa, KeyType::Ed25519];
|
||||
|
||||
impl KeyType {
|
||||
fn bytes_for(&self, part: &str) -> &'static [u8] {
|
||||
match self {
|
||||
KeyType::Rsa => bytes_for("rsa", part),
|
||||
KeyType::Ecdsa => bytes_for("ecdsa", part),
|
||||
KeyType::Ed25519 => bytes_for("eddsa", part),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_chain(&self) -> Vec<Certificate> {
|
||||
rustls_pemfile::certs(&mut io::BufReader::new(self.bytes_for("end.fullchain")))
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|v| Certificate(v.clone()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn get_key(&self) -> PrivateKey {
|
||||
PrivateKey(
|
||||
rustls_pemfile::pkcs8_private_keys(&mut io::BufReader::new(self.bytes_for("end.key")))
|
||||
.unwrap()[0]
|
||||
.clone(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_client_chain(&self) -> Vec<Certificate> {
|
||||
rustls_pemfile::certs(&mut io::BufReader::new(self.bytes_for("client.fullchain")))
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|v| Certificate(v.clone()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn get_client_key(&self) -> PrivateKey {
|
||||
PrivateKey(
|
||||
rustls_pemfile::pkcs8_private_keys(&mut io::BufReader::new(
|
||||
self.bytes_for("client.key"),
|
||||
))
|
||||
.unwrap()[0]
|
||||
.clone(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn finish_server_config(
|
||||
kt: KeyType,
|
||||
conf: rustls::ConfigBuilder<ServerConfig, rustls::WantsVerifier>,
|
||||
) -> ServerConfig {
|
||||
conf.with_no_client_auth()
|
||||
.with_single_cert(kt.get_chain(), kt.get_key())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn make_server_config(kt: KeyType) -> ServerConfig {
|
||||
finish_server_config(kt, ServerConfig::builder().with_safe_defaults())
|
||||
}
|
||||
|
||||
pub fn make_server_config_with_versions(
|
||||
kt: KeyType,
|
||||
versions: &[&'static rustls::SupportedProtocolVersion],
|
||||
) -> ServerConfig {
|
||||
finish_server_config(
|
||||
kt,
|
||||
ServerConfig::builder()
|
||||
.with_safe_default_cipher_suites()
|
||||
.with_safe_default_kx_groups()
|
||||
.with_protocol_versions(versions)
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn make_server_config_with_kx_groups(
|
||||
kt: KeyType,
|
||||
kx_groups: &[&'static rustls::SupportedKxGroup],
|
||||
) -> ServerConfig {
|
||||
finish_server_config(
|
||||
kt,
|
||||
ServerConfig::builder()
|
||||
.with_safe_default_cipher_suites()
|
||||
.with_kx_groups(kx_groups)
|
||||
.with_safe_default_protocol_versions()
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_client_root_store(kt: KeyType) -> RootCertStore {
|
||||
let roots = kt.get_chain();
|
||||
let mut client_auth_roots = RootCertStore::empty();
|
||||
for root in roots {
|
||||
client_auth_roots.add(&root).unwrap();
|
||||
}
|
||||
client_auth_roots
|
||||
}
|
||||
|
||||
pub fn make_server_config_with_mandatory_client_auth(kt: KeyType) -> ServerConfig {
|
||||
let client_auth_roots = get_client_root_store(kt);
|
||||
|
||||
let client_auth = AllowAnyAuthenticatedClient::new(client_auth_roots);
|
||||
|
||||
ServerConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_client_cert_verifier(client_auth)
|
||||
.with_single_cert(kt.get_chain(), kt.get_key())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn finish_client_config(
|
||||
kt: KeyType,
|
||||
config: rustls::ConfigBuilder<ClientConfig, rustls::WantsVerifier>,
|
||||
) -> ClientConfig {
|
||||
let mut root_store = RootCertStore::empty();
|
||||
let mut rootbuf = io::BufReader::new(kt.bytes_for("ca.cert"));
|
||||
root_store.add_parsable_certificates(&rustls_pemfile::certs(&mut rootbuf).unwrap());
|
||||
|
||||
config
|
||||
.with_root_certificates(root_store)
|
||||
.with_no_client_auth()
|
||||
}
|
||||
|
||||
pub fn finish_client_config_with_creds(
|
||||
kt: KeyType,
|
||||
config: rustls::ConfigBuilder<ClientConfig, rustls::WantsVerifier>,
|
||||
) -> ClientConfig {
|
||||
let mut root_store = RootCertStore::empty();
|
||||
let mut rootbuf = io::BufReader::new(kt.bytes_for("ca.cert"));
|
||||
root_store.add_parsable_certificates(&rustls_pemfile::certs(&mut rootbuf).unwrap());
|
||||
|
||||
config
|
||||
.with_root_certificates(root_store)
|
||||
.with_single_cert(kt.get_client_chain(), kt.get_client_key())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn make_client_config(kt: KeyType) -> ClientConfig {
|
||||
finish_client_config(kt, ClientConfig::builder().with_safe_defaults())
|
||||
}
|
||||
|
||||
pub fn make_client_config_with_kx_groups(
|
||||
kt: KeyType,
|
||||
kx_groups: &[&'static rustls::SupportedKxGroup],
|
||||
) -> ClientConfig {
|
||||
let builder = ClientConfig::builder()
|
||||
.with_safe_default_cipher_suites()
|
||||
.with_kx_groups(kx_groups)
|
||||
.with_safe_default_protocol_versions()
|
||||
.unwrap();
|
||||
finish_client_config(kt, builder)
|
||||
}
|
||||
|
||||
pub fn make_client_config_with_versions(
|
||||
kt: KeyType,
|
||||
versions: &[&'static rustls::SupportedProtocolVersion],
|
||||
) -> ClientConfig {
|
||||
let builder = ClientConfig::builder()
|
||||
.with_safe_default_cipher_suites()
|
||||
.with_safe_default_kx_groups()
|
||||
.with_protocol_versions(versions)
|
||||
.unwrap();
|
||||
finish_client_config(kt, builder)
|
||||
}
|
||||
|
||||
pub fn make_client_config_with_auth(kt: KeyType) -> ClientConfig {
|
||||
finish_client_config_with_creds(kt, ClientConfig::builder().with_safe_defaults())
|
||||
}
|
||||
|
||||
pub fn make_client_config_with_versions_with_auth(
|
||||
kt: KeyType,
|
||||
versions: &[&'static rustls::SupportedProtocolVersion],
|
||||
) -> ClientConfig {
|
||||
let builder = ClientConfig::builder()
|
||||
.with_safe_default_cipher_suites()
|
||||
.with_safe_default_kx_groups()
|
||||
.with_protocol_versions(versions)
|
||||
.unwrap();
|
||||
finish_client_config_with_creds(kt, builder)
|
||||
}
|
||||
|
||||
pub fn make_pair(kt: KeyType) -> (ClientConnection, ServerConnection) {
|
||||
make_pair_for_configs(make_client_config(kt), make_server_config(kt))
|
||||
}
|
||||
|
||||
pub fn make_pair_for_configs(
|
||||
client_config: ClientConfig,
|
||||
server_config: ServerConfig,
|
||||
) -> (ClientConnection, ServerConnection) {
|
||||
make_pair_for_arc_configs(&Arc::new(client_config), &Arc::new(server_config))
|
||||
}
|
||||
|
||||
pub fn make_pair_for_arc_configs(
|
||||
client_config: &Arc<ClientConfig>,
|
||||
server_config: &Arc<ServerConfig>,
|
||||
) -> (ClientConnection, ServerConnection) {
|
||||
(
|
||||
ClientConnection::new(Arc::clone(client_config), dns_name("localhost")).unwrap(),
|
||||
ServerConnection::new(Arc::clone(server_config)).unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn do_handshake(
|
||||
client: &mut (impl DerefMut + Deref<Target = ConnectionCommon<impl SideData>>),
|
||||
server: &mut (impl DerefMut + Deref<Target = ConnectionCommon<impl SideData>>),
|
||||
) -> (usize, usize) {
|
||||
let (mut to_client, mut to_server) = (0, 0);
|
||||
while server.is_handshaking() || client.is_handshaking() {
|
||||
to_server += transfer(client, server);
|
||||
server.process_new_packets().unwrap();
|
||||
to_client += transfer(server, client);
|
||||
client.process_new_packets().unwrap();
|
||||
}
|
||||
(to_server, to_client)
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub enum ErrorFromPeer {
|
||||
Client(Error),
|
||||
Server(Error),
|
||||
}
|
||||
|
||||
pub fn do_handshake_until_error(
|
||||
client: &mut ClientConnection,
|
||||
server: &mut ServerConnection,
|
||||
) -> Result<(), ErrorFromPeer> {
|
||||
while server.is_handshaking() || client.is_handshaking() {
|
||||
transfer(client, server);
|
||||
server
|
||||
.process_new_packets()
|
||||
.map_err(ErrorFromPeer::Server)?;
|
||||
transfer(server, client);
|
||||
client
|
||||
.process_new_packets()
|
||||
.map_err(ErrorFromPeer::Client)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn do_handshake_until_both_error(
|
||||
client: &mut ClientConnection,
|
||||
server: &mut ServerConnection,
|
||||
) -> Result<(), Vec<ErrorFromPeer>> {
|
||||
match do_handshake_until_error(client, server) {
|
||||
Err(server_err @ ErrorFromPeer::Server(_)) => {
|
||||
let mut errors = vec![server_err];
|
||||
transfer(server, client);
|
||||
let client_err = client
|
||||
.process_new_packets()
|
||||
.map_err(ErrorFromPeer::Client)
|
||||
.expect_err("client didn't produce error after server error");
|
||||
errors.push(client_err);
|
||||
Err(errors)
|
||||
}
|
||||
|
||||
Err(client_err @ ErrorFromPeer::Client(_)) => {
|
||||
let mut errors = vec![client_err];
|
||||
transfer(client, server);
|
||||
let server_err = server
|
||||
.process_new_packets()
|
||||
.map_err(ErrorFromPeer::Server)
|
||||
.expect_err("server didn't produce error after client error");
|
||||
errors.push(server_err);
|
||||
Err(errors)
|
||||
}
|
||||
|
||||
Ok(()) => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dns_name(name: &'static str) -> rustls::ServerName {
|
||||
name.try_into().unwrap()
|
||||
}
|
||||
|
||||
pub struct FailsReads {
|
||||
errkind: io::ErrorKind,
|
||||
}
|
||||
|
||||
impl FailsReads {
|
||||
pub fn new(errkind: io::ErrorKind) -> Self {
|
||||
FailsReads { errkind }
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Read for FailsReads {
|
||||
fn read(&mut self, _b: &mut [u8]) -> io::Result<usize> {
|
||||
Err(io::Error::from(self.errkind))
|
||||
}
|
||||
}
|
||||
104
third_party/rustls-fork-shadow-tls/tests/key_log_file_env.rs
vendored
Normal file
104
third_party/rustls-fork-shadow-tls/tests/key_log_file_env.rs
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
//! Tests of [`rustls::KeyLogFile`] that require us to set environment variables.
|
||||
//!
|
||||
//! vvvv
|
||||
//! Every test you add to this file MUST execute through `serialized()`.
|
||||
//! ^^^^
|
||||
//!
|
||||
//! See https://github.com/rust-lang/rust/issues/90308; despite not being marked
|
||||
//! `unsafe`, `env::var::set_var` is an unsafe function. These tests are separated
|
||||
//! from the rest of the tests so that their use of `set_ver` is less likely to
|
||||
//! affect them; as of the time these tests were moved to this file, Cargo will
|
||||
//! compile each test suite file to a separate executable, so these will be run
|
||||
//! in a completely separate process. This way, executing every test through
|
||||
//! `serialized()` will cause them to be run one at a time.
|
||||
//!
|
||||
//! Note: If/when we add new constructors to `KeyLogFile` to allow constructing
|
||||
//! one from a path directly (without using an environment variable), then those
|
||||
//! tests SHOULD NOT go in this file.
|
||||
//!
|
||||
//! XXX: These tests don't actually test the functionality; they just ensure
|
||||
//! the code coverage doesn't complain it isn't covered. TODO: Verify that the
|
||||
//! file was created successfully, with the right permissions, etc., and that it
|
||||
//! contains something like what we expect.
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod common;
|
||||
|
||||
use crate::common::{
|
||||
do_handshake, make_client_config_with_versions, make_pair_for_arc_configs, make_server_config,
|
||||
transfer, KeyType,
|
||||
};
|
||||
use std::{
|
||||
env,
|
||||
io::Write,
|
||||
sync::{Arc, Mutex, Once},
|
||||
};
|
||||
|
||||
/// Approximates `#[serial]` from the `serial_test` crate.
|
||||
///
|
||||
/// No attempt is made to recover from a poisoned mutex, which will
|
||||
/// happen when `f` panics. In other words, all the tests that use
|
||||
/// `serialized` will start failing after one test panics.
|
||||
fn serialized(f: impl FnOnce()) {
|
||||
// Ensure every test is run serialized
|
||||
// TODO: Use `std::sync::Lazy` once that is stable.
|
||||
static mut MUTEX: Option<Mutex<()>> = None;
|
||||
static ONCE: Once = Once::new();
|
||||
ONCE.call_once(|| unsafe {
|
||||
MUTEX = Some(Mutex::new(()));
|
||||
});
|
||||
let mutex = unsafe { MUTEX.as_mut() };
|
||||
|
||||
let _guard = mutex.unwrap().lock().unwrap();
|
||||
|
||||
// XXX: NOT thread safe.
|
||||
env::set_var("SSLKEYLOGFILE", "./sslkeylogfile.txt");
|
||||
|
||||
f()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exercise_key_log_file_for_client() {
|
||||
serialized(|| {
|
||||
let server_config = Arc::new(make_server_config(KeyType::Rsa));
|
||||
env::set_var("SSLKEYLOGFILE", "./sslkeylogfile.txt");
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let mut client_config = make_client_config_with_versions(KeyType::Rsa, &[version]);
|
||||
client_config.key_log = Arc::new(rustls::KeyLogFile::new());
|
||||
|
||||
let (mut client, mut server) =
|
||||
make_pair_for_arc_configs(&Arc::new(client_config), &server_config);
|
||||
|
||||
assert_eq!(5, client.writer().write(b"hello").unwrap());
|
||||
|
||||
do_handshake(&mut client, &mut server);
|
||||
transfer(&mut client, &mut server);
|
||||
server.process_new_packets().unwrap();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exercise_key_log_file_for_server() {
|
||||
serialized(|| {
|
||||
let mut server_config = make_server_config(KeyType::Rsa);
|
||||
|
||||
env::set_var("SSLKEYLOGFILE", "./sslkeylogfile.txt");
|
||||
server_config.key_log = Arc::new(rustls::KeyLogFile::new());
|
||||
|
||||
let server_config = Arc::new(server_config);
|
||||
|
||||
for version in rustls::ALL_VERSIONS {
|
||||
let client_config = make_client_config_with_versions(KeyType::Rsa, &[version]);
|
||||
let (mut client, mut server) =
|
||||
make_pair_for_arc_configs(&Arc::new(client_config), &server_config);
|
||||
|
||||
assert_eq!(5, client.writer().write(b"hello").unwrap());
|
||||
|
||||
do_handshake(&mut client, &mut server);
|
||||
transfer(&mut client, &mut server);
|
||||
server.process_new_packets().unwrap();
|
||||
}
|
||||
})
|
||||
}
|
||||
272
third_party/rustls-fork-shadow-tls/tests/server_cert_verifier.rs
vendored
Normal file
272
third_party/rustls-fork-shadow-tls/tests/server_cert_verifier.rs
vendored
Normal file
|
|
@ -0,0 +1,272 @@
|
|||
//! 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<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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue