mirror of https://github.com/ctz/rustls
Tighten up SCT list checking
This commit is contained in:
parent
b25072598e
commit
8890d193e3
|
@ -237,6 +237,10 @@
|
|||
"SendUnknownExtensionOnCertificate-TLS13": ":PEER_MISBEHAVIOUR:",
|
||||
"LargePlaintext": ":PEER_MISBEHAVIOUR:",
|
||||
"SendDuplicateExtensionsOnCerts-TLS13": ":PEER_MISBEHAVIOUR:",
|
||||
"SignedCertificateTimestampListEmpty-Client-TLS12": ":PEER_MISBEHAVIOUR:",
|
||||
"SignedCertificateTimestampListEmpty-Client-TLS13": ":PEER_MISBEHAVIOUR:",
|
||||
"SignedCertificateTimestampListEmptySCT-Client-TLS12": ":PEER_MISBEHAVIOUR:",
|
||||
"SignedCertificateTimestampListEmptySCT-Client-TLS13": ":PEER_MISBEHAVIOUR:",
|
||||
"EMS-Forbidden-TLS13": ":PEER_MISBEHAVIOUR:",
|
||||
"SendExtensionOnClientCertificate-TLS13": ":PEER_MISBEHAVIOUR:",
|
||||
"ExtendedMasterSecret-NoToYes-Client": ":PEER_MISBEHAVIOUR:",
|
||||
|
|
|
@ -376,6 +376,12 @@ fn main() {
|
|||
"-signed-cert-timestamps" => {
|
||||
opts.server_sct_list = base64::decode(args.remove(0).as_bytes())
|
||||
.expect("invalid base64");
|
||||
|
||||
if opts.server_sct_list.len() == 2 &&
|
||||
opts.server_sct_list[0] == 0x00 &&
|
||||
opts.server_sct_list[1] == 0x00 {
|
||||
quit(":INVALID_SCT_LIST:");
|
||||
}
|
||||
}
|
||||
"-select-alpn" => {
|
||||
opts.protocols.push(args.remove(0));
|
||||
|
|
|
@ -14,7 +14,7 @@ use msgs::handshake::{CertificatePayloadTLS13, CertificateEntry};
|
|||
use msgs::handshake::ServerKeyExchangePayload;
|
||||
use msgs::handshake::DigitallySignedStruct;
|
||||
use msgs::handshake::{PresharedKeyIdentity, PresharedKeyOffer, HelloRetryRequest};
|
||||
use msgs::handshake::CertificateStatusRequest;
|
||||
use msgs::handshake::{CertificateStatusRequest, SCTList};
|
||||
use msgs::enums::{ClientCertificateType, PSKKeyExchangeMode, ECPointFormat};
|
||||
use msgs::codec::Codec;
|
||||
use msgs::persist;
|
||||
|
@ -585,6 +585,11 @@ fn handle_server_hello(sess: &mut ClientSessionImpl, m: Message) -> StateResult
|
|||
// Save any sent SCTs for verification against the certificate.
|
||||
if let Some(sct_list) = server_hello.get_sct_list() {
|
||||
info!("Server sent {:?} SCTs", sct_list.len());
|
||||
|
||||
if sct_list_is_invalid(&sct_list) {
|
||||
let error_msg = "server sent invalid SCT list".to_string();
|
||||
return Err(TLSError::PeerMisbehavedError(error_msg));
|
||||
}
|
||||
sess.handshake_data.server_cert_scts = Some(sct_list.clone());
|
||||
}
|
||||
|
||||
|
@ -759,6 +764,11 @@ static EXPECT_TLS13_ENCRYPTED_EXTENSIONS: State = State {
|
|||
handle: handle_encrypted_extensions,
|
||||
};
|
||||
|
||||
fn sct_list_is_invalid(scts: &SCTList) -> bool {
|
||||
scts.is_empty() ||
|
||||
scts.iter().any(|sct| sct.0.is_empty())
|
||||
}
|
||||
|
||||
fn handle_certificate_tls13(sess: &mut ClientSessionImpl, m: Message) -> StateResult {
|
||||
let cert_chain = extract_handshake!(m, HandshakePayload::CertificateTLS13).unwrap();
|
||||
sess.handshake_data.transcript.add_message(&m);
|
||||
|
@ -780,6 +790,14 @@ fn handle_certificate_tls13(sess: &mut ClientSessionImpl, m: Message) -> StateRe
|
|||
sess.handshake_data.server_cert_ocsp_response = cert_chain.get_end_entity_ocsp();
|
||||
sess.handshake_data.server_cert_scts = cert_chain.get_end_entity_scts();
|
||||
sess.handshake_data.server_cert_chain = cert_chain.convert();
|
||||
|
||||
if let Some(sct_list) = sess.handshake_data.server_cert_scts.as_ref() {
|
||||
if sct_list_is_invalid(&sct_list) {
|
||||
let error_msg = "server sent invalid SCT list".to_string();
|
||||
return Err(TLSError::PeerMisbehavedError(error_msg));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(&EXPECT_TLS13_CERTIFICATE_VERIFY)
|
||||
}
|
||||
|
||||
|
|
|
@ -224,7 +224,6 @@ pub fn verify_scts(cert: &Certificate,
|
|||
scts: &SCTList,
|
||||
logs: &[&sct::Log]) -> Result<(), TLSError> {
|
||||
let mut valid_scts = 0;
|
||||
let total_scts = scts.len();
|
||||
let now = (time::get_time().sec * 1000) as u64;
|
||||
let mut last_sct_error = None;
|
||||
|
||||
|
@ -247,7 +246,7 @@ pub fn verify_scts(cert: &Certificate,
|
|||
|
||||
/* If we were supplied with some logs, and some SCTs,
|
||||
* but couldn't verify any of them, fail the handshake. */
|
||||
if !logs.is_empty() && total_scts != 0 && valid_scts == 0 {
|
||||
if !logs.is_empty() && !scts.is_empty() && valid_scts == 0 {
|
||||
warn!("No valid SCTs provided");
|
||||
return Err(TLSError::InvalidSCT(last_sct_error.unwrap()));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue