mirror of https://github.com/ctz/rustls
Remove default certificate verifier trait functions
This is a breaking change. These introduced an implicit dependency on the `webpki` crate for anyone who wanted to implement these traits. Instead, someone who wants to benefit from the `webpki`-backed implementations should dispatch to `WebPkiServerVerifier` themselves. Expose these defaults explicitly, and dispatch to them in our various bits of example and test code.
This commit is contained in:
parent
77ad069312
commit
e9c15abe06
|
@ -338,6 +338,9 @@ fn load_private_key(filename: &str) -> rustls::PrivateKey {
|
|||
|
||||
#[cfg(feature = "dangerous_configuration")]
|
||||
mod danger {
|
||||
use rustls::client::{HandshakeSignatureValid, WebPkiServerVerifier};
|
||||
use rustls::DigitallySignedStruct;
|
||||
|
||||
pub struct NoCertificateVerification {}
|
||||
|
||||
impl rustls::client::ServerCertVerifier for NoCertificateVerification {
|
||||
|
@ -351,6 +354,28 @@ mod danger {
|
|||
) -> Result<rustls::client::ServerCertVerified, rustls::Error> {
|
||||
Ok(rustls::client::ServerCertVerified::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls12_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &rustls::Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, rustls::Error> {
|
||||
WebPkiServerVerifier::default_verify_tls12_signature(message, cert, dss)
|
||||
}
|
||||
|
||||
fn verify_tls13_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &rustls::Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, rustls::Error> {
|
||||
WebPkiServerVerifier::default_verify_tls13_signature(message, cert, dss)
|
||||
}
|
||||
|
||||
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
|
||||
WebPkiServerVerifier::default_supported_verify_schemes()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
// https://boringssl.googlesource.com/boringssl/+/master/ssl/test
|
||||
//
|
||||
|
||||
use rustls::client::{ClientConfig, ClientConnection, Resumption};
|
||||
use rustls::client::{
|
||||
ClientConfig, ClientConnection, HandshakeSignatureValid, Resumption, WebPkiServerVerifier,
|
||||
};
|
||||
use rustls::crypto::ring::Ring;
|
||||
use rustls::crypto::CryptoProvider;
|
||||
use rustls::internal::msgs::codec::Codec;
|
||||
|
@ -12,9 +14,10 @@ use rustls::internal::msgs::persist;
|
|||
use rustls::server::{ClientHello, ServerConfig, ServerConnection};
|
||||
use rustls::{
|
||||
self, client, kx_group, server, sign, version, AlertDescription, Certificate, CertificateError,
|
||||
Connection, DistinguishedName, Error, InvalidMessage, NamedGroup, PeerIncompatible,
|
||||
PeerMisbehaved, PrivateKey, ProtocolVersion, ServerName, Side, SignatureAlgorithm,
|
||||
SignatureScheme, SupportedKxGroup, SupportedProtocolVersion, Ticketer, ALL_KX_GROUPS,
|
||||
Connection, DigitallySignedStruct, DistinguishedName, Error, InvalidMessage, NamedGroup,
|
||||
PeerIncompatible, PeerMisbehaved, PrivateKey, ProtocolVersion, ServerName, Side,
|
||||
SignatureAlgorithm, SignatureScheme, SupportedKxGroup, SupportedProtocolVersion, Ticketer,
|
||||
ALL_KX_GROUPS,
|
||||
};
|
||||
|
||||
use base64::prelude::{Engine, BASE64_STANDARD};
|
||||
|
@ -211,6 +214,28 @@ impl server::ClientCertVerifier for DummyClientAuth {
|
|||
) -> Result<server::ClientCertVerified, Error> {
|
||||
Ok(server::ClientCertVerified::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls12_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &rustls::Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
WebPkiServerVerifier::default_verify_tls12_signature(message, cert, dss)
|
||||
}
|
||||
|
||||
fn verify_tls13_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &rustls::Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
WebPkiServerVerifier::default_verify_tls13_signature(message, cert, dss)
|
||||
}
|
||||
|
||||
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
|
||||
WebPkiServerVerifier::default_supported_verify_schemes()
|
||||
}
|
||||
}
|
||||
|
||||
struct DummyServerAuth {}
|
||||
|
@ -226,6 +251,28 @@ impl client::ServerCertVerifier for DummyServerAuth {
|
|||
) -> Result<client::ServerCertVerified, Error> {
|
||||
Ok(client::ServerCertVerified::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls12_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &rustls::Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
WebPkiServerVerifier::default_verify_tls12_signature(message, cert, dss)
|
||||
}
|
||||
|
||||
fn verify_tls13_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &rustls::Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
WebPkiServerVerifier::default_verify_tls13_signature(message, cert, dss)
|
||||
}
|
||||
|
||||
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
|
||||
WebPkiServerVerifier::default_supported_verify_schemes()
|
||||
}
|
||||
}
|
||||
|
||||
struct FixedSignatureSchemeSigningKey {
|
||||
|
|
|
@ -135,17 +135,12 @@ pub trait ServerCertVerifier: Send + Sync {
|
|||
/// This method is only called for TLS1.2 handshakes. Note that, in TLS1.2,
|
||||
/// SignatureSchemes such as `SignatureScheme::ECDSA_NISTP256_SHA256` are not
|
||||
/// in fact bound to the specific curve implied in their name.
|
||||
///
|
||||
/// This trait method has a default implementation that uses webpki to verify
|
||||
/// the signature.
|
||||
fn verify_tls12_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
verify_signed_struct(message, cert, dss)
|
||||
}
|
||||
) -> Result<HandshakeSignatureValid, Error>;
|
||||
|
||||
/// Verify a signature allegedly by the given server certificate.
|
||||
///
|
||||
|
@ -161,28 +156,18 @@ pub trait ServerCertVerifier: Send + Sync {
|
|||
/// If and only if the signature is valid, return `Ok(HandshakeSignatureValid)`.
|
||||
/// Otherwise, return an error -- rustls will send an alert and abort the
|
||||
/// connection.
|
||||
///
|
||||
/// This trait method has a default implementation that uses webpki to verify
|
||||
/// the signature.
|
||||
fn verify_tls13_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
verify_tls13(message, cert, dss)
|
||||
}
|
||||
) -> Result<HandshakeSignatureValid, Error>;
|
||||
|
||||
/// Return the list of SignatureSchemes that this verifier will handle,
|
||||
/// in `verify_tls12_signature` and `verify_tls13_signature` calls.
|
||||
///
|
||||
/// This should be in priority order, with the most preferred first.
|
||||
///
|
||||
/// This trait method has a default implementation that reflects the schemes
|
||||
/// supported by webpki.
|
||||
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
|
||||
WebPkiServerVerifier::verification_schemes()
|
||||
}
|
||||
fn supported_verify_schemes(&self) -> Vec<SignatureScheme>;
|
||||
}
|
||||
|
||||
impl fmt::Debug for dyn ServerCertVerifier {
|
||||
|
@ -258,17 +243,12 @@ pub trait ClientCertVerifier: Send + Sync {
|
|||
/// This method is only called for TLS1.2 handshakes. Note that, in TLS1.2,
|
||||
/// SignatureSchemes such as `SignatureScheme::ECDSA_NISTP256_SHA256` are not
|
||||
/// in fact bound to the specific curve implied in their name.
|
||||
///
|
||||
/// This trait method has a default implementation that uses webpki to verify
|
||||
/// the signature.
|
||||
fn verify_tls12_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
verify_signed_struct(message, cert, dss)
|
||||
}
|
||||
) -> Result<HandshakeSignatureValid, Error>;
|
||||
|
||||
/// Verify a signature allegedly by the given client certificate.
|
||||
///
|
||||
|
@ -279,28 +259,18 @@ pub trait ClientCertVerifier: Send + Sync {
|
|||
/// `SignatureScheme::ECDSA_NISTP256_SHA256`
|
||||
/// must only validate signatures using public keys on the right curve --
|
||||
/// rustls does not enforce this requirement for you.
|
||||
///
|
||||
/// This trait method has a default implementation that uses webpki to verify
|
||||
/// the signature.
|
||||
fn verify_tls13_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
verify_tls13(message, cert, dss)
|
||||
}
|
||||
) -> Result<HandshakeSignatureValid, Error>;
|
||||
|
||||
/// Return the list of SignatureSchemes that this verifier will handle,
|
||||
/// in `verify_tls12_signature` and `verify_tls13_signature` calls.
|
||||
///
|
||||
/// This should be in priority order, with the most preferred first.
|
||||
///
|
||||
/// This trait method has a default implementation that reflects the schemes
|
||||
/// supported by webpki.
|
||||
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
|
||||
WebPkiServerVerifier::verification_schemes()
|
||||
}
|
||||
fn supported_verify_schemes(&self) -> Vec<SignatureScheme>;
|
||||
}
|
||||
|
||||
impl fmt::Debug for dyn ClientCertVerifier {
|
||||
|
@ -394,6 +364,28 @@ impl ServerCertVerifier for WebPkiServerVerifier {
|
|||
verify_server_name(&cert, server_name)?;
|
||||
Ok(ServerCertVerified::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls12_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
Self::default_verify_tls12_signature(message, cert, dss)
|
||||
}
|
||||
|
||||
fn verify_tls13_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
Self::default_verify_tls13_signature(message, cert, dss)
|
||||
}
|
||||
|
||||
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
|
||||
Self::default_supported_verify_schemes()
|
||||
}
|
||||
}
|
||||
|
||||
/// Default `ServerCertVerifier`, see the trait impl for more information.
|
||||
|
@ -405,16 +397,15 @@ pub struct WebPkiServerVerifier {
|
|||
|
||||
#[allow(unreachable_pub)]
|
||||
impl WebPkiServerVerifier {
|
||||
/// Constructs a new `WebPkiVerifier`.
|
||||
/// Constructs a new `WebPkiServerVerifier`.
|
||||
///
|
||||
/// `roots` is the set of trust anchors to trust for issuing server certs.
|
||||
pub fn new(roots: RootCertStore) -> Self {
|
||||
Self { roots }
|
||||
}
|
||||
|
||||
/// Returns the signature verification methods supported by
|
||||
/// webpki.
|
||||
pub fn verification_schemes() -> Vec<SignatureScheme> {
|
||||
/// Which signature verification schemes the `webpki` crate supports.
|
||||
pub fn default_supported_verify_schemes() -> Vec<SignatureScheme> {
|
||||
vec![
|
||||
SignatureScheme::ECDSA_NISTP384_SHA384,
|
||||
SignatureScheme::ECDSA_NISTP256_SHA256,
|
||||
|
@ -427,6 +418,26 @@ impl WebPkiServerVerifier {
|
|||
SignatureScheme::RSA_PKCS1_SHA256,
|
||||
]
|
||||
}
|
||||
|
||||
/// An full implementation of `ServerCertVerifier::verify_tls12_signature` or
|
||||
/// `ClientCertVerifier::verify_tls12_signature`.
|
||||
pub fn default_verify_tls12_signature(
|
||||
message: &[u8],
|
||||
cert: &Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
verify_signed_struct(message, cert, dss)
|
||||
}
|
||||
|
||||
/// An full implementation of `ServerCertVerifier::verify_tls13_signature` or
|
||||
/// `ClientCertVerifier::verify_tls13_signature`.
|
||||
pub fn default_verify_tls13_signature(
|
||||
message: &[u8],
|
||||
cert: &Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
verify_tls13(message, cert, dss)
|
||||
}
|
||||
}
|
||||
|
||||
fn intermediate_chain(intermediates: &[Certificate]) -> Vec<&[u8]> {
|
||||
|
@ -619,6 +630,28 @@ impl ClientCertVerifier for WebPkiClientVerifier {
|
|||
.map_err(pki_error)
|
||||
.map(|_| ClientCertVerified::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls12_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
WebPkiServerVerifier::default_verify_tls12_signature(message, cert, dss)
|
||||
}
|
||||
|
||||
fn verify_tls13_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
WebPkiServerVerifier::default_verify_tls13_signature(message, cert, dss)
|
||||
}
|
||||
|
||||
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
|
||||
WebPkiServerVerifier::default_supported_verify_schemes()
|
||||
}
|
||||
}
|
||||
|
||||
/// Controls how the [WebPkiClientVerifier] handles anonymous clients.
|
||||
|
@ -678,6 +711,28 @@ impl ClientCertVerifier for NoClientAuth {
|
|||
) -> Result<ClientCertVerified, Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn verify_tls12_signature(
|
||||
&self,
|
||||
_message: &[u8],
|
||||
_cert: &Certificate,
|
||||
_dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn verify_tls13_signature(
|
||||
&self,
|
||||
_message: &[u8],
|
||||
_cert: &Certificate,
|
||||
_dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
/// This type combines a [`SignatureScheme`] and a signature payload produced with that scheme.
|
||||
|
|
|
@ -474,8 +474,7 @@ fn test_config_builders_debug() {
|
|||
/// Test that the server handles combination of `offer_client_auth()` returning true
|
||||
/// and `client_auth_mandatory` returning `Some(false)`. This exercises both the
|
||||
/// client's and server's ability to "recover" from the server asking for a client
|
||||
/// certificate and not being given one. This also covers the implementation
|
||||
/// of `AllowAnyAnonymousOrAuthenticatedClient`.
|
||||
/// certificate and not being given one.
|
||||
#[test]
|
||||
fn server_allow_any_anonymous_or_authenticated_client() {
|
||||
let kt = KeyType::Rsa;
|
||||
|
|
|
@ -9,13 +9,13 @@ use crate::common::{
|
|||
make_client_config_with_versions, make_client_config_with_versions_with_auth,
|
||||
make_pair_for_arc_configs, server_name, ErrorFromPeer, KeyType, ALL_KEY_TYPES,
|
||||
};
|
||||
use rustls::client::WebPkiServerVerifier;
|
||||
use rustls::client::{HandshakeSignatureValid, WebPkiServerVerifier};
|
||||
use rustls::crypto::ring::Ring;
|
||||
use rustls::internal::msgs::handshake::DistinguishedName;
|
||||
use rustls::server::{ClientCertVerified, ClientCertVerifier};
|
||||
use rustls::{
|
||||
AlertDescription, Certificate, ClientConnection, Error, InvalidMessage, ServerConfig,
|
||||
ServerConnection, SignatureScheme,
|
||||
AlertDescription, Certificate, ClientConnection, DigitallySignedStruct, Error, InvalidMessage,
|
||||
ServerConfig, ServerConnection, SignatureScheme,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -200,11 +200,29 @@ impl ClientCertVerifier for MockClientVerifier {
|
|||
(self.verified)()
|
||||
}
|
||||
|
||||
fn verify_tls12_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
WebPkiServerVerifier::default_verify_tls12_signature(message, cert, dss)
|
||||
}
|
||||
|
||||
fn verify_tls13_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &Certificate,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, Error> {
|
||||
WebPkiServerVerifier::default_verify_tls13_signature(message, cert, dss)
|
||||
}
|
||||
|
||||
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
|
||||
if let Some(schemes) = &self.offered_schemes {
|
||||
schemes.clone()
|
||||
} else {
|
||||
WebPkiServerVerifier::verification_schemes()
|
||||
WebPkiServerVerifier::default_supported_verify_schemes()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -262,7 +262,7 @@ impl Default for MockServerVerifier {
|
|||
cert_rejection_error: None,
|
||||
tls12_signature_error: None,
|
||||
tls13_signature_error: None,
|
||||
signature_schemes: WebPkiServerVerifier::verification_schemes(),
|
||||
signature_schemes: WebPkiServerVerifier::default_supported_verify_schemes(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue