Skip to content
Permalink
Browse files

Merge d002722 into 13d2a90

  • Loading branch information
jeromegn committed Sep 14, 2019
2 parents 13d2a90 + d002722 commit 87a79f05c7ed6c964629be4d9048324c9dd748b9
@@ -22,6 +22,7 @@ use std::ops::{Deref, DerefMut};
use rustls::internal::msgs::enums::ProtocolVersion;
use rustls::quic::ClientQuicExt;
use rustls::quic::ServerQuicExt;
use rustls::ClientHello;

static BOGO_NACK: i32 = 89;

@@ -215,12 +216,8 @@ struct FixedSignatureSchemeServerCertResolver {
}

impl rustls::ResolvesServerCert for FixedSignatureSchemeServerCertResolver {
fn resolve(&self,
server_name: Option<webpki::DNSNameRef<'_>>,
sigschemes: &[rustls::SignatureScheme],
alpn: Option<&[&[u8]]>
) -> Option<rustls::sign::CertifiedKey> {
let mut certkey = self.resolver.resolve(server_name, sigschemes, alpn)?;
fn resolve(&self, client_hello: ClientHello) -> Option<rustls::sign::CertifiedKey> {
let mut certkey = self.resolver.resolve(client_hello)?;
certkey.key = Arc::new(Box::new(FixedSignatureSchemeSigningKey {
key: certkey.key.clone(),
scheme: self.scheme,
@@ -277,6 +277,7 @@ pub use crate::suites::{ALL_CIPHERSUITES, BulkAlgorithm, SupportedCipherSuite};
pub use crate::key::{Certificate, PrivateKey};
pub use crate::keylog::{KeyLog, NoKeyLog, KeyLogFile};
pub use crate::vecbuf::{WriteV, WriteVAdapter};
pub use crate::server::client_hello::ClientHello;

/// Message signing interfaces and implementations.
pub mod sign;
@@ -0,0 +1,37 @@
use crate::msgs::enums::SignatureScheme;

/// A struct representing the received Client Hello
pub struct ClientHello<'a> {
server_name: Option<webpki::DNSNameRef<'a>>,
sigschemes: &'a [SignatureScheme],
alpn: Option<&'a[&'a[u8]]>,
}

impl<'a> ClientHello<'a> {
/// Creates a new ClientHello
pub fn new(server_name: Option<webpki::DNSNameRef<'a>>, sigschemes: &'a [SignatureScheme],
alpn: Option<&'a[&'a[u8]]>)->Self {
ClientHello {server_name, sigschemes, alpn}
}

/// Get the server name indicator.
///
/// Returns `None` if the client did not supply a SNI.
pub fn server_name(&self) -> Option<webpki::DNSNameRef> {
self.server_name
}

/// Get the compatible signature schemes.
///
/// Returns standard-specified default if the client omitted this extension.
pub fn sigschemes(&self) -> &[SignatureScheme] {
self.sigschemes
}

/// Get the alpn.
///
/// Returns `None` if the client did not include an ALPN extension
pub fn alpn(&self) -> Option<&'a[&'a[u8]]> {
self.alpn
}
}
@@ -1,9 +1,9 @@
use crate::msgs::enums::SignatureScheme;
use crate::sign;
use crate::key;
use webpki;
use crate::server;
use crate::error::TLSError;
use crate::server::client_hello::ClientHello;

use std::collections;
use std::sync::{Arc, Mutex};
@@ -95,11 +95,7 @@ impl server::ProducesTickets for NeverProducesTickets {
pub struct FailResolveChain {}

impl server::ResolvesServerCert for FailResolveChain {
fn resolve(&self,
_server_name: Option<webpki::DNSNameRef>,
_sigschemes: &[SignatureScheme],
_alpn_protocols: Option<&[&[u8]]>)
-> Option<sign::CertifiedKey> {
fn resolve(&self, _client_hello: ClientHello) -> Option<sign::CertifiedKey> {
None
}
}
@@ -137,11 +133,7 @@ impl AlwaysResolvesChain {
}

impl server::ResolvesServerCert for AlwaysResolvesChain {
fn resolve(&self,
_server_name: Option<webpki::DNSNameRef>,
_sigschemes: &[SignatureScheme],
_alpn_protocols: Option<&[&[u8]]>)
-> Option<sign::CertifiedKey> {
fn resolve(&self, _client_hello: ClientHello) -> Option<sign::CertifiedKey> {
Some(self.0.clone())
}
}
@@ -174,12 +166,8 @@ impl ResolvesServerCertUsingSNI {
}

impl server::ResolvesServerCert for ResolvesServerCertUsingSNI {
fn resolve(&self,
server_name: Option<webpki::DNSNameRef>,
_sigschemes: &[SignatureScheme],
_alpn_protocols: Option<&[&[u8]]>)
-> Option<sign::CertifiedKey> {
if let Some(name) = server_name {
fn resolve(&self, client_hello: ClientHello) -> Option<sign::CertifiedKey> {
if let Some(name) = client_hello.server_name() {
self.by_name.get(name.into())
.cloned()
} else {
@@ -21,6 +21,7 @@ use crate::suites;
use crate::verify;
use crate::rand;
use crate::sign;
use crate::server::client_hello::ClientHello;
#[cfg(feature = "logging")]
use crate::log::{trace, debug};
use crate::error::TLSError;
@@ -615,9 +616,9 @@ impl State for ExpectClientHello {
None => None,
};

let certkey = sess.config.cert_resolver.resolve(sni_ref,
&sigschemes_ext,
alpn_slices);
let client_hello = ClientHello::new(sni_ref, &sigschemes_ext, alpn_slices);

let certkey = sess.config.cert_resolver.resolve(client_hello);
certkey.ok_or_else(|| {
sess.common.send_fatal_alert(AlertDescription::AccessDenied);
TLSError::General("no server certificate chain resolved".to_string())
@@ -1,7 +1,7 @@
use crate::session::{Session, SessionCommon};
use crate::keylog::{KeyLog, NoKeyLog};
use crate::suites::{SupportedCipherSuite, ALL_CIPHERSUITES};
use crate::msgs::enums::{ContentType, SignatureScheme};
use crate::msgs::enums::ContentType;
use crate::msgs::enums::{AlertDescription, HandshakeType, ProtocolVersion};
use crate::msgs::handshake::ServerExtension;
use crate::msgs::message::Message;
@@ -10,6 +10,7 @@ use crate::sign;
use crate::verify;
use crate::key;
use crate::vecbuf::WriteV;
use crate::server::client_hello::ClientHello;
#[cfg(feature = "logging")]
use crate::log::trace;

@@ -25,6 +26,7 @@ mod tls12;
mod tls13;
mod common;
pub mod handy;
pub mod client_hello;

/// A trait for the ability to store server session data.
///
@@ -95,26 +97,11 @@ pub trait ProducesTickets : Send + Sync {
/// How to choose a certificate chain and signing key for use
/// in server authentication.
pub trait ResolvesServerCert : Send + Sync {
/// Choose a certificate chain and matching key given any server DNS
/// name provided via SNI, any ALPN protocol names, and signature schemes
/// advertised by the client.
///
/// `server_name` is `None` if the client did not supply an SNI name.
///
/// `sigschemes` is replaced with a standard-specified default if the client
/// omitted this extension.
///
/// `alpn_protocols` is `None` if the client did not include an ALPN extension.
///
/// Return a `CertifiedKey` to continue the handshake. A `CertifiedKey`
/// binds together a signing key and a certificate chain.
///
/// Choose a certificate chain and matching key given simplified
/// ClientHello information.
///
/// Return `None` to abort the handshake.
fn resolve(&self,
server_name: Option<webpki::DNSNameRef>,
sigschemes: &[SignatureScheme],
alpn_protocols: Option<&[&[u8]]>)
-> Option<sign::CertifiedKey>;
fn resolve(&self, client_hello: ClientHello) -> Option<sign::CertifiedKey>;
}

/// Common configuration for a set of server sessions.
@@ -19,6 +19,7 @@ use rustls::TLSError;
use rustls::sign;
use rustls::{ALL_CIPHERSUITES, SupportedCipherSuite};
use rustls::KeyLog;
use rustls::ClientHello;
#[cfg(feature = "quic")]
use rustls::quic::{self, QuicExt, ClientQuicExt, ServerQuicExt};
#[cfg(feature = "quic")]
@@ -318,29 +319,25 @@ struct ServerCheckCertResolve {
}

impl ResolvesServerCert for ServerCheckCertResolve {
fn resolve(&self,
server_name: Option<webpki::DNSNameRef<'_>>,
sigschemes: &[SignatureScheme],
alpn: Option<&[&[u8]]>)
-> Option<sign::CertifiedKey> {
if sigschemes.len() == 0 {
fn resolve(&self, client_hello: ClientHello) -> Option<sign::CertifiedKey> {
if client_hello.sigschemes().len() == 0 {
panic!("no signature schemes shared by client");
}

if let Some(expected_sni) = &self.expected_sni {
let sni: &str = server_name.expect("sni unexpectedly absent").into();
let sni: &str = client_hello.server_name().expect("sni unexpectedly absent").into();
assert_eq!(expected_sni, sni);
}

if let Some(expected_sigalgs) = &self.expected_sigalgs {
if expected_sigalgs != &sigschemes {
if expected_sigalgs != &client_hello.sigschemes() {
panic!("unexpected signature schemes (wanted {:?} got {:?})",
self.expected_sigalgs, sigschemes);
self.expected_sigalgs, client_hello.sigschemes());
}
}

if let Some(expected_alpn) = &self.expected_alpn {
let alpn = alpn.expect("alpn unexpectedly absent");
let alpn = client_hello.alpn().expect("alpn unexpectedly absent");
assert_eq!(alpn.len(), expected_alpn.len());

for (got, wanted) in alpn.iter().zip(expected_alpn.iter()) {
@@ -442,12 +439,8 @@ fn server_cert_resolve_reduces_sigalgs_for_ecdsa_ciphersuite() {
struct ServerCheckNoSNI {}

impl ResolvesServerCert for ServerCheckNoSNI {
fn resolve(&self,
server_name: Option<webpki::DNSNameRef<'_>>,
_sigschemes: &[SignatureScheme],
_alpn: Option<&[&[u8]]>)
-> Option<sign::CertifiedKey> {
assert!(server_name.is_none());
fn resolve(&self, client_hello: ClientHello) -> Option<sign::CertifiedKey> {
assert!(client_hello.server_name().is_none());

None
}

0 comments on commit 87a79f0

Please sign in to comment.
You can’t perform that action at this time.