mirror of https://github.com/ctz/rustls
Pass around parts of CertifiedKey separately
This commit is contained in:
parent
452b1b275f
commit
3440410bd4
|
@ -388,14 +388,14 @@ impl hs::State for ExpectCertificateRequest {
|
|||
.client_auth_cert_resolver
|
||||
.resolve(&canames, &certreq.sigschemes);
|
||||
|
||||
if let Some(mut certkey) = maybe_certkey {
|
||||
if let Some(certkey) = maybe_certkey {
|
||||
let maybe_signer = certkey
|
||||
.key
|
||||
.choose_scheme(&certreq.sigschemes);
|
||||
|
||||
if let Some(_) = &maybe_signer {
|
||||
debug!("Attempting client auth");
|
||||
client_auth.cert = Some(certkey.take_cert());
|
||||
client_auth.cert = Some(certkey.cert);
|
||||
}
|
||||
client_auth.signer = maybe_signer;
|
||||
} else {
|
||||
|
|
|
@ -760,12 +760,12 @@ impl hs::State for ExpectCertificateRequest {
|
|||
.resolve(&canames, &compat_sigschemes);
|
||||
|
||||
let mut client_auth = ClientAuthDetails::new();
|
||||
if let Some(mut certkey) = maybe_certkey {
|
||||
if let Some(certkey) = maybe_certkey {
|
||||
debug!("Attempting client auth");
|
||||
let maybe_signer = certkey
|
||||
.key
|
||||
.choose_scheme(&compat_sigschemes);
|
||||
client_auth.cert = Some(certkey.take_cert());
|
||||
client_auth.cert = Some(certkey.cert);
|
||||
client_auth.signer = maybe_signer;
|
||||
client_auth.auth_context = Some(certreq.context.0.clone());
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::error::TlsError;
|
||||
use crate::key::Certificate;
|
||||
use crate::kx;
|
||||
#[cfg(feature = "logging")]
|
||||
use crate::log::{debug, trace};
|
||||
|
@ -31,6 +32,8 @@ use webpki;
|
|||
use crate::server::common::{HandshakeDetails, ServerKXDetails};
|
||||
use crate::server::{tls12, tls13};
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
pub type NextState = Box<dyn State + Send + Sync>;
|
||||
pub type NextStateOrError = Result<NextState, TlsError>;
|
||||
|
||||
|
@ -150,7 +153,8 @@ impl ExtensionProcessing {
|
|||
pub fn process_common(
|
||||
&mut self,
|
||||
sess: &mut ServerSessionImpl,
|
||||
server_key: Option<&mut sign::CertifiedKey>,
|
||||
ocsp_response: &mut Option<Vec<u8>>,
|
||||
sct_list: &mut Option<Vec<u8>>,
|
||||
hello: &ClientHelloPayload,
|
||||
resumedata: Option<&persist::ServerSessionValue>,
|
||||
handshake: &HandshakeDetails,
|
||||
|
@ -223,7 +227,6 @@ impl ExtensionProcessing {
|
|||
.push(ServerExtension::ServerNameAck);
|
||||
}
|
||||
|
||||
if let Some(server_key) = server_key {
|
||||
// Send status_request response if we have one. This is not allowed
|
||||
// if we're resuming, and is only triggered if we have an OCSP response
|
||||
// to send.
|
||||
|
@ -232,14 +235,14 @@ impl ExtensionProcessing {
|
|||
.find_extension(ExtensionType::StatusRequest)
|
||||
.is_some()
|
||||
{
|
||||
if server_key.has_ocsp() && !sess.common.is_tls13() {
|
||||
if ocsp_response.is_some() && !sess.common.is_tls13() {
|
||||
// Only TLS1.2 sends confirmation in ServerHello
|
||||
self.exts
|
||||
.push(ServerExtension::CertificateStatusAck);
|
||||
}
|
||||
} else {
|
||||
// Throw away any OCSP response so we don't try to send it later.
|
||||
drop(server_key.take_ocsp());
|
||||
ocsp_response.take();
|
||||
}
|
||||
|
||||
if !for_resume
|
||||
|
@ -250,18 +253,14 @@ impl ExtensionProcessing {
|
|||
if !sess.common.is_tls13() {
|
||||
// Take the SCT list, if any, so we don't send it later,
|
||||
// and put it in the legacy extension.
|
||||
server_key
|
||||
.take_sct_list()
|
||||
.map(|sct_list| {
|
||||
self.exts
|
||||
.push(ServerExtension::make_sct(sct_list))
|
||||
});
|
||||
if let Some(sct_list) = sct_list.take() {
|
||||
self.exts.push(ServerExtension::make_sct(sct_list));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Throw away any SCT list so we don't send it later.
|
||||
drop(server_key.take_sct_list());
|
||||
sct_list.take();
|
||||
}
|
||||
}
|
||||
|
||||
self.exts
|
||||
.extend(handshake.extra_exts.iter().cloned());
|
||||
|
@ -395,13 +394,14 @@ impl ExpectClientHello {
|
|||
fn emit_server_hello(
|
||||
&mut self,
|
||||
sess: &mut ServerSessionImpl,
|
||||
server_key: Option<&mut sign::CertifiedKey>,
|
||||
ocsp_response: &mut Option<Vec<u8>>,
|
||||
sct_list: &mut Option<Vec<u8>>,
|
||||
hello: &ClientHelloPayload,
|
||||
resumedata: Option<&persist::ServerSessionValue>,
|
||||
randoms: &SessionRandoms,
|
||||
) -> Result<(), TlsError> {
|
||||
let mut ep = ExtensionProcessing::new();
|
||||
ep.process_common(sess, server_key, hello, resumedata, &self.handshake)?;
|
||||
ep.process_common(sess, ocsp_response, sct_list, hello, resumedata, &self.handshake)?;
|
||||
ep.process_tls12(sess, hello, self.using_ems);
|
||||
|
||||
self.send_ticket = ep.send_ticket;
|
||||
|
@ -433,10 +433,8 @@ impl ExpectClientHello {
|
|||
fn emit_certificate(
|
||||
&mut self,
|
||||
sess: &mut ServerSessionImpl,
|
||||
server_certkey: &mut sign::CertifiedKey,
|
||||
cert_chain: Vec<Certificate>,
|
||||
) {
|
||||
let cert_chain = server_certkey.take_cert();
|
||||
|
||||
let c = Message {
|
||||
typ: ContentType::Handshake,
|
||||
version: ProtocolVersion::TLSv1_2,
|
||||
|
@ -455,13 +453,8 @@ impl ExpectClientHello {
|
|||
fn emit_cert_status(
|
||||
&mut self,
|
||||
sess: &mut ServerSessionImpl,
|
||||
server_certkey: &mut sign::CertifiedKey,
|
||||
ocsp: Vec<u8>,
|
||||
) {
|
||||
let ocsp = match server_certkey.take_ocsp() {
|
||||
Some(ocsp) => ocsp,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let st = CertificateStatus::new(ocsp);
|
||||
|
||||
let c = Message {
|
||||
|
@ -484,7 +477,7 @@ impl ExpectClientHello {
|
|||
sess: &mut ServerSessionImpl,
|
||||
sigschemes: Vec<SignatureScheme>,
|
||||
skxg: &'static kx::SupportedKxGroup,
|
||||
server_certkey: &mut sign::CertifiedKey,
|
||||
signing_key: Arc<Box<dyn sign::SigningKey>>,
|
||||
randoms: &SessionRandoms,
|
||||
) -> Result<kx::KeyExchange, TlsError> {
|
||||
let kx = kx::KeyExchange::start(skxg)
|
||||
|
@ -496,7 +489,6 @@ impl ExpectClientHello {
|
|||
msg.extend(&randoms.server);
|
||||
secdh.encode(&mut msg);
|
||||
|
||||
let signing_key = &server_certkey.key;
|
||||
let signer = signing_key
|
||||
.choose_scheme(&sigschemes)
|
||||
.ok_or_else(|| TlsError::General("incompatible signing key".to_string()))?;
|
||||
|
@ -600,7 +592,7 @@ impl ExpectClientHello {
|
|||
}
|
||||
|
||||
self.handshake.session_id = *id;
|
||||
self.emit_server_hello(sess, None, client_hello, Some(&resumedata), randoms)?;
|
||||
self.emit_server_hello(sess, &mut None, &mut None, client_hello, Some(&resumedata), randoms)?;
|
||||
|
||||
let suite = sess.common.get_suite_assert();
|
||||
let secrets = SessionSecrets::new_resume(&randoms, suite, &resumedata.master_secret.0);
|
||||
|
@ -738,7 +730,7 @@ impl State for ExpectClientHello {
|
|||
.map(|protos| protos.to_slices());
|
||||
|
||||
// Choose a certificate.
|
||||
let mut certkey = {
|
||||
let certkey = {
|
||||
let sni_ref = sni
|
||||
.as_ref()
|
||||
.map(webpki::DNSName::as_ref);
|
||||
|
@ -943,10 +935,14 @@ impl State for ExpectClientHello {
|
|||
|
||||
debug_assert_eq!(ecpoint, ECPointFormat::Uncompressed);
|
||||
|
||||
self.emit_server_hello(sess, Some(&mut certkey), client_hello, None, &randoms)?;
|
||||
self.emit_certificate(sess, &mut certkey);
|
||||
self.emit_cert_status(sess, &mut certkey);
|
||||
let kx = self.emit_server_kx(sess, sigschemes, group, &mut certkey, &randoms)?;
|
||||
let sign::CertifiedKey { cert, key, mut ocsp, mut sct_list } = certkey;
|
||||
self.emit_server_hello(sess, &mut ocsp, &mut sct_list, client_hello, None, &randoms)?;
|
||||
self.emit_certificate(sess, cert);
|
||||
if let Some(ocsp_response) = ocsp {
|
||||
self.emit_cert_status(sess, ocsp_response);
|
||||
}
|
||||
|
||||
let kx = self.emit_server_kx(sess, sigschemes, group, key, &randoms)?;
|
||||
let doing_client_auth = self.emit_certificate_req(sess)?;
|
||||
self.emit_server_hello_done(sess);
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::check::check_message;
|
||||
use crate::{cipher, SupportedCipherSuite};
|
||||
use crate::error::TlsError;
|
||||
use crate::key;
|
||||
use crate::key_schedule::{
|
||||
KeyScheduleEarly, KeyScheduleHandshake, KeyScheduleNonSecret, KeyScheduleTraffic,
|
||||
KeyScheduleTrafficWithClientFinishedPending,
|
||||
|
@ -48,6 +49,8 @@ use crate::server::hs;
|
|||
|
||||
use ring::constant_time;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct CompleteClientHelloHandling {
|
||||
pub handshake: HandshakeDetails,
|
||||
pub randoms: SessionRandoms,
|
||||
|
@ -275,12 +278,13 @@ impl CompleteClientHelloHandling {
|
|||
fn emit_encrypted_extensions(
|
||||
&mut self,
|
||||
sess: &mut ServerSessionImpl,
|
||||
server_key: &mut sign::CertifiedKey,
|
||||
ocsp_response: &mut Option<Vec<u8>>,
|
||||
sct_list: &mut Option<Vec<u8>>,
|
||||
hello: &ClientHelloPayload,
|
||||
resumedata: Option<&persist::ServerSessionValue>,
|
||||
) -> Result<(), TlsError> {
|
||||
let mut ep = hs::ExtensionProcessing::new();
|
||||
ep.process_common(sess, Some(server_key), hello, resumedata, &self.handshake)?;
|
||||
ep.process_common(sess, ocsp_response, sct_list, hello, resumedata, &self.handshake)?;
|
||||
|
||||
let ee = Message {
|
||||
typ: ContentType::Handshake,
|
||||
|
@ -355,10 +359,12 @@ impl CompleteClientHelloHandling {
|
|||
fn emit_certificate_tls13(
|
||||
&mut self,
|
||||
sess: &mut ServerSessionImpl,
|
||||
server_key: &mut sign::CertifiedKey,
|
||||
server_cert: Vec<key::Certificate>,
|
||||
ocsp_response: Option<Vec<u8>>,
|
||||
sct_list: Option<Vec<u8>>,
|
||||
) {
|
||||
let mut cert_entries = vec![];
|
||||
for cert in server_key.take_cert() {
|
||||
for cert in server_cert {
|
||||
let entry = CertificateEntry {
|
||||
cert,
|
||||
exts: Vec::new(),
|
||||
|
@ -370,7 +376,7 @@ impl CompleteClientHelloHandling {
|
|||
if let Some(end_entity_cert) = cert_entries.first_mut() {
|
||||
// Apply OCSP response to first certificate (we don't support OCSP
|
||||
// except for leaf certs).
|
||||
if let Some(ocsp) = server_key.take_ocsp() {
|
||||
if let Some(ocsp) = ocsp_response {
|
||||
let cst = CertificateStatus::new(ocsp);
|
||||
end_entity_cert
|
||||
.exts
|
||||
|
@ -378,7 +384,7 @@ impl CompleteClientHelloHandling {
|
|||
}
|
||||
|
||||
// Likewise, SCT
|
||||
if let Some(sct_list) = server_key.take_sct_list() {
|
||||
if let Some(sct_list) = sct_list {
|
||||
end_entity_cert
|
||||
.exts
|
||||
.push(CertificateExtension::make_sct(sct_list));
|
||||
|
@ -405,7 +411,7 @@ impl CompleteClientHelloHandling {
|
|||
fn emit_certificate_verify_tls13(
|
||||
&mut self,
|
||||
sess: &mut ServerSessionImpl,
|
||||
server_key: &mut sign::CertifiedKey,
|
||||
signing_key: Arc<Box<dyn sign::SigningKey>>,
|
||||
schemes: &[SignatureScheme],
|
||||
) -> Result<(), TlsError> {
|
||||
let message = verify::construct_tls13_server_verify_message(
|
||||
|
@ -415,7 +421,6 @@ impl CompleteClientHelloHandling {
|
|||
.get_current_hash(),
|
||||
);
|
||||
|
||||
let signing_key = &server_key.key;
|
||||
let signer = signing_key
|
||||
.choose_scheme(schemes)
|
||||
.ok_or_else(|| hs::incompatible(sess, "no overlapping sigschemes"))?;
|
||||
|
@ -532,7 +537,7 @@ impl CompleteClientHelloHandling {
|
|||
mut self,
|
||||
suite: &'static SupportedCipherSuite,
|
||||
sess: &mut ServerSessionImpl,
|
||||
mut server_key: sign::CertifiedKey,
|
||||
server_key: sign::CertifiedKey,
|
||||
chm: &Message,
|
||||
) -> hs::NextStateOrError {
|
||||
let client_hello = require_handshake_msg!(
|
||||
|
@ -669,12 +674,13 @@ impl CompleteClientHelloHandling {
|
|||
if !self.done_retry {
|
||||
self.emit_fake_ccs(sess);
|
||||
}
|
||||
self.emit_encrypted_extensions(sess, &mut server_key, client_hello, resumedata.as_ref())?;
|
||||
|
||||
let sign::CertifiedKey { cert, key, mut ocsp, mut sct_list } = server_key;
|
||||
self.emit_encrypted_extensions(sess, &mut ocsp, &mut sct_list, client_hello, resumedata.as_ref())?;
|
||||
let doing_client_auth = if full_handshake {
|
||||
let client_auth = self.emit_certificate_req_tls13(sess)?;
|
||||
self.emit_certificate_tls13(sess, &mut server_key);
|
||||
self.emit_certificate_verify_tls13(sess, &mut server_key, &sigschemes_ext)?;
|
||||
self.emit_certificate_tls13(sess, cert, ocsp, sct_list);
|
||||
self.emit_certificate_verify_tls13(sess, key, &sigschemes_ext)?;
|
||||
client_auth
|
||||
} else {
|
||||
false
|
||||
|
|
|
@ -8,7 +8,6 @@ use ring::{
|
|||
};
|
||||
use webpki;
|
||||
|
||||
use std::mem;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// An abstract signing key.
|
||||
|
@ -66,31 +65,6 @@ impl CertifiedKey {
|
|||
}
|
||||
}
|
||||
|
||||
/// The end-entity certificate.
|
||||
pub fn end_entity_cert(&self) -> Result<&key::Certificate, ()> {
|
||||
self.cert.get(0).ok_or(())
|
||||
}
|
||||
|
||||
/// Steal ownership of the certificate chain.
|
||||
pub fn take_cert(&mut self) -> Vec<key::Certificate> {
|
||||
mem::replace(&mut self.cert, Vec::new())
|
||||
}
|
||||
|
||||
/// Return true if there's an OCSP response.
|
||||
pub fn has_ocsp(&self) -> bool {
|
||||
self.ocsp.is_some()
|
||||
}
|
||||
|
||||
/// Steal ownership of the OCSP response.
|
||||
pub fn take_ocsp(&mut self) -> Option<Vec<u8>> {
|
||||
mem::replace(&mut self.ocsp, None)
|
||||
}
|
||||
|
||||
/// Steal ownership of the SCT list.
|
||||
pub fn take_sct_list(&mut self) -> Option<Vec<u8>> {
|
||||
mem::replace(&mut self.sct_list, None)
|
||||
}
|
||||
|
||||
/// Check the certificate chain for validity:
|
||||
/// - it should be non-empty list
|
||||
/// - the first certificate should be parsable as a x509v3,
|
||||
|
@ -104,7 +78,7 @@ impl CertifiedKey {
|
|||
name: Option<webpki::DNSNameRef>,
|
||||
) -> Result<(), TlsError> {
|
||||
// Always reject an empty certificate chain.
|
||||
let end_entity_cert = self.end_entity_cert().map_err(|()| {
|
||||
let end_entity_cert = self.cert.first().ok_or_else(|| {
|
||||
TlsError::General("No end-entity certificate in certificate chain".to_string())
|
||||
})?;
|
||||
|
||||
|
|
Loading…
Reference in New Issue