Skip to content

Commit

Permalink
Client-side TLS 1.2 RFC 5746 Secure Renegotiation
Browse files Browse the repository at this point in the history
  • Loading branch information
cschramm committed May 11, 2024
1 parent ae277be commit 3dd5820
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 52 deletions.
1 change: 1 addition & 0 deletions rustls/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ aws_lc_rs = ["dep:aws-lc-rs", "webpki/aws_lc_rs"]
ring = ["dep:ring", "webpki/ring"]
tls12 = []
read_buf = ["rustversion"]
renegotiation = []

[dev-dependencies]
base64 = "0.21"
Expand Down
36 changes: 24 additions & 12 deletions rustls/src/client/hs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::error::{Error, PeerIncompatible, PeerMisbehaved};
use crate::hash_hs::HandshakeHashBuffer;
#[cfg(feature = "logging")]
use crate::log::{debug, trace};
use crate::msgs::base::Payload;
use crate::msgs::base::{Payload, PayloadU8};
use crate::msgs::enums::{Compression, ExtensionType};
use crate::msgs::enums::{ECPointFormat, PSKKeyExchangeMode};
use crate::msgs::handshake::ConvertProtocolNameList;
Expand Down Expand Up @@ -104,7 +104,11 @@ pub(super) fn start_handshake(
transcript_buffer.set_client_auth_enabled();
}

let mut resuming = find_session(&server_name, &config, cx);
let mut resuming = if cx.common.client_verify_data.is_empty() {
find_session(&server_name, &config, cx)
} else {
None
};

let key_share = if config.supports_version(ProtocolVersion::TLSv1_3) {
Some(tls13::initial_key_share(&config, &server_name)?)
Expand Down Expand Up @@ -271,12 +275,6 @@ fn emit_client_hello_for_retry(
// Do we have a SessionID or ticket cached for this host?
let tls13_session = prepare_resumption(&input.resuming, &mut exts, suite, cx, config);

// Note what extensions we sent.
input.hello.sent_extensions = exts
.iter()
.map(ClientExtension::get_type)
.collect();

let mut cipher_suites: Vec<_> = config
.provider
.cipher_suites
Expand All @@ -286,8 +284,20 @@ fn emit_client_hello_for_retry(
false => None,
})
.collect();
// We don't do renegotiation at all, in fact.
cipher_suites.push(CipherSuite::TLS_EMPTY_RENEGOTIATION_INFO_SCSV);

if cx.common.client_verify_data.is_empty() {
cipher_suites.push(CipherSuite::TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
} else {
exts.push(ClientExtension::RenegotiationInfo(PayloadU8::new(
cx.common.client_verify_data.clone(),
)));
}

// Note what extensions we sent.
input.hello.sent_extensions = exts
.iter()
.map(ClientExtension::get_type)
.collect();

let mut chp = HandshakeMessagePayload {
typ: HandshakeType::ClientHello,
Expand All @@ -312,7 +322,7 @@ fn emit_client_hello_for_retry(
// "This value MUST be set to 0x0303 for all records generated
// by a TLS 1.3 implementation other than an initial ClientHello
// (i.e., one not generated after a HelloRetryRequest)"
version: if retryreq.is_some() {
version: if retryreq.is_some() || !cx.common.client_verify_data.is_empty() {
ProtocolVersion::TLSv1_2
} else {
ProtocolVersion::TLSv1_0
Expand All @@ -329,7 +339,8 @@ fn emit_client_hello_for_retry(
trace!("Sending ClientHello {:#?}", ch);

transcript_buffer.add_message(&ch);
cx.common.send_msg(ch, false);
cx.common
.send_msg(ch, !cx.common.client_verify_data.is_empty());

// Calculate the hash of ClientHello and use it to derive EarlyTrafficSecret
let early_key_schedule = early_key_schedule.map(|(resuming_suite, schedule)| {
Expand Down Expand Up @@ -662,6 +673,7 @@ impl State<ClientConnectionData> for ExpectServerHello {
randoms,
using_ems: self.input.using_ems,
transcript,
message_decrypter: None,
}
.handle_server_hello(cx, suite, server_hello, tls13_supported)
}
Expand Down
Loading

0 comments on commit 3dd5820

Please sign in to comment.