mirror of https://github.com/ctz/rustls
Move TLS1.3 KeySchedule into state machine
This means moving key-update processing into the state-machine too.
This commit is contained in:
parent
909b9cf12d
commit
412add83da
|
@ -14,7 +14,7 @@ use crate::msgs::codec::{Codec, Reader};
|
|||
use crate::msgs::persist;
|
||||
use crate::client::ClientSessionImpl;
|
||||
use crate::session::SessionSecrets;
|
||||
use crate::key_schedule::SecretKind;
|
||||
use crate::key_schedule::{KeySchedule, SecretKind};
|
||||
use crate::cipher;
|
||||
use crate::suites;
|
||||
use crate::verify;
|
||||
|
@ -69,12 +69,14 @@ pub trait State {
|
|||
fn handle(self: Box<Self>, sess: &mut ClientSessionImpl, m: Message) -> NextStateOrError;
|
||||
|
||||
fn export_keying_material(&self,
|
||||
_sess: &ClientSessionImpl,
|
||||
_output: &mut [u8],
|
||||
_label: &[u8],
|
||||
_context: Option<&[u8]>) -> Result<(), TLSError> {
|
||||
Err(TLSError::HandshakeNotComplete)
|
||||
}
|
||||
|
||||
fn perhaps_write_key_update(&mut self, _sess: &mut ClientSessionImpl) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn illegal_param(sess: &mut ClientSessionImpl, why: &str) -> TLSError {
|
||||
|
@ -164,6 +166,7 @@ pub fn start_handshake(sess: &mut ClientSessionImpl, host_name: webpki::DNSName,
|
|||
|
||||
struct ExpectServerHello {
|
||||
handshake: HandshakeDetails,
|
||||
early_key_schedule: Option<KeySchedule>,
|
||||
hello: ClientHelloDetails,
|
||||
server_cert: ServerCertDetails,
|
||||
may_send_cert_status: bool,
|
||||
|
@ -297,9 +300,11 @@ fn emit_client_hello_for_retry(sess: &mut ClientSessionImpl,
|
|||
}),
|
||||
};
|
||||
|
||||
if fill_in_binder {
|
||||
tls13::fill_in_psk_binder(sess, &mut handshake, &mut chp);
|
||||
}
|
||||
let early_key_schedule = if fill_in_binder {
|
||||
Some(tls13::fill_in_psk_binder(sess, &mut handshake, &mut chp))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let ch = Message {
|
||||
typ: ContentType::Handshake,
|
||||
|
@ -336,8 +341,9 @@ fn emit_client_hello_for_retry(sess: &mut ClientSessionImpl,
|
|||
.and_then(|resume| sess.find_cipher_suite(resume.cipher_suite)).unwrap();
|
||||
|
||||
let client_hello_hash = handshake.transcript.get_hash_given(resuming_suite.get_hash(), &[]);
|
||||
let client_early_traffic_secret = sess.common
|
||||
.get_key_schedule()
|
||||
let client_early_traffic_secret = early_key_schedule
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.derive_logged_secret(SecretKind::ClientEarlyTrafficSecret, &client_hello_hash,
|
||||
&*sess.config.key_log,
|
||||
&handshake.randoms.client);
|
||||
|
@ -357,7 +363,9 @@ fn emit_client_hello_for_retry(sess: &mut ClientSessionImpl,
|
|||
}
|
||||
|
||||
let next = ExpectServerHello {
|
||||
handshake, hello,
|
||||
handshake,
|
||||
hello,
|
||||
early_key_schedule,
|
||||
server_cert: ServerCertDetails::new(),
|
||||
may_send_cert_status: false,
|
||||
must_issue_new_ticket: false,
|
||||
|
@ -388,9 +396,10 @@ pub fn sct_list_is_invalid(scts: &SCTList) -> bool {
|
|||
}
|
||||
|
||||
impl ExpectServerHello {
|
||||
fn into_expect_tls13_encrypted_extensions(self) -> NextState {
|
||||
fn into_expect_tls13_encrypted_extensions(self, key_schedule: KeySchedule) -> NextState {
|
||||
Box::new(tls13::ExpectEncryptedExtensions {
|
||||
handshake: self.handshake,
|
||||
key_schedule: key_schedule,
|
||||
server_cert: self.server_cert,
|
||||
hello: self.hello,
|
||||
})
|
||||
|
@ -534,9 +543,13 @@ impl State for ExpectServerHello {
|
|||
// handshake_traffic_secret.
|
||||
if sess.common.is_tls13() {
|
||||
tls13::validate_server_hello(sess, server_hello)?;
|
||||
tls13::start_handshake_traffic(sess, server_hello, &mut self.handshake, &mut self.hello)?;
|
||||
let key_schedule = tls13::start_handshake_traffic(sess,
|
||||
self.early_key_schedule.take(),
|
||||
server_hello,
|
||||
&mut self.handshake,
|
||||
&mut self.hello)?;
|
||||
tls13::emit_fake_ccs(&mut self.handshake, sess);
|
||||
return Ok(self.into_expect_tls13_encrypted_extensions());
|
||||
return Ok(self.into_expect_tls13_encrypted_extensions(key_schedule));
|
||||
}
|
||||
|
||||
// TLS1.2 only from here-on
|
||||
|
|
|
@ -589,7 +589,16 @@ impl ClientSessionImpl {
|
|||
self.state
|
||||
.as_ref()
|
||||
.ok_or_else(|| TLSError::HandshakeNotComplete)
|
||||
.and_then(|st| st.export_keying_material(self, output, label, context))
|
||||
.and_then(|st| st.export_keying_material(output, label, context))
|
||||
}
|
||||
|
||||
fn send_some_plaintext(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
let mut st = self.state.take();
|
||||
st.as_mut()
|
||||
.map(|st| st.perhaps_write_key_update(self));
|
||||
self.state = st;
|
||||
|
||||
self.common.send_some_plaintext(buf)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -729,7 +738,7 @@ impl io::Write for ClientSession {
|
|||
/// writing much data before it can be sent will
|
||||
/// cause excess memory usage.
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.imp.common.send_some_plaintext(buf)
|
||||
self.imp.send_some_plaintext(buf)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
|
|
|
@ -778,7 +778,6 @@ impl hs::State for ExpectTraffic {
|
|||
}
|
||||
|
||||
fn export_keying_material(&self,
|
||||
_sess: &ClientSessionImpl,
|
||||
output: &mut [u8],
|
||||
label: &[u8],
|
||||
context: Option<&[u8]>) -> Result<(), TLSError> {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::msgs::enums::{ContentType, HandshakeType, ExtensionType, SignatureScheme};
|
||||
use crate::msgs::enums::{ProtocolVersion, AlertDescription, NamedGroup};
|
||||
use crate::msgs::enums::KeyUpdateRequest;
|
||||
use crate::msgs::message::{Message, MessagePayload};
|
||||
use crate::msgs::base::{Payload, PayloadU8};
|
||||
use crate::msgs::handshake::{HandshakePayload, HandshakeMessagePayload};
|
||||
|
@ -122,7 +123,7 @@ pub fn choose_kx_groups(sess: &mut ClientSessionImpl,
|
|||
/// data dependency on the message they are contained within.
|
||||
pub fn fill_in_psk_binder(sess: &mut ClientSessionImpl,
|
||||
handshake: &mut HandshakeDetails,
|
||||
hmp: &mut HandshakeMessagePayload) {
|
||||
hmp: &mut HandshakeMessagePayload) -> KeySchedule {
|
||||
// We need to know the hash function of the suite we're trying to resume into.
|
||||
let resuming = handshake.resuming_session.as_ref().unwrap();
|
||||
let suite = sess.find_cipher_suite(resuming.cipher_suite).unwrap();
|
||||
|
@ -148,17 +149,19 @@ pub fn fill_in_psk_binder(sess: &mut ClientSessionImpl,
|
|||
if let HandshakePayload::ClientHello(ref mut ch) = hmp.payload {
|
||||
ch.set_psk_binder(real_binder);
|
||||
};
|
||||
sess.common.set_key_schedule(key_schedule);
|
||||
|
||||
key_schedule
|
||||
}
|
||||
|
||||
pub fn start_handshake_traffic(sess: &mut ClientSessionImpl,
|
||||
early_key_schedule: Option<KeySchedule>,
|
||||
server_hello: &ServerHelloPayload,
|
||||
handshake: &mut HandshakeDetails,
|
||||
hello: &mut ClientHelloDetails)
|
||||
-> Result<(), TLSError> {
|
||||
-> Result<KeySchedule, TLSError> {
|
||||
let suite = sess.common.get_suite_assert();
|
||||
|
||||
if let Some(selected_psk) = server_hello.get_psk_index() {
|
||||
let mut key_schedule = if let Some(selected_psk) = server_hello.get_psk_index() {
|
||||
if let Some(ref resuming) = handshake.resuming_session {
|
||||
let resume_from_suite = sess.find_cipher_suite(resuming.cipher_suite).unwrap();
|
||||
if !resume_from_suite.can_resume_to(suite) {
|
||||
|
@ -172,21 +175,21 @@ pub fn start_handshake_traffic(sess: &mut ClientSessionImpl,
|
|||
}
|
||||
|
||||
debug!("Resuming using PSK");
|
||||
// The key schedule has been initialized and set in fill_in_psk()
|
||||
// The key schedule has been initialized and set in fill_in_psk_binder()
|
||||
// Server must be using the resumption suite, otherwise set_suite()
|
||||
// in ExpectServerHello::handle() would fail.
|
||||
// key_schedule.input_secret(&resuming.master_secret.0);
|
||||
} else {
|
||||
return Err(TLSError::PeerMisbehavedError("server selected unoffered psk".to_string()));
|
||||
}
|
||||
early_key_schedule.unwrap()
|
||||
} else {
|
||||
debug!("Not resuming");
|
||||
// Discard the early data key schedule.
|
||||
sess.early_data.rejected();
|
||||
sess.common.early_traffic = false;
|
||||
sess.common.set_key_schedule(KeySchedule::new_with_empty_secret(suite.hkdf_algorithm));
|
||||
handshake.resuming_session.take();
|
||||
}
|
||||
KeySchedule::new_with_empty_secret(suite.hkdf_algorithm)
|
||||
};
|
||||
|
||||
let their_key_share = server_hello.get_key_share()
|
||||
.ok_or_else(|| {
|
||||
|
@ -201,7 +204,7 @@ pub fn start_handshake_traffic(sess: &mut ClientSessionImpl,
|
|||
.to_string()))?;
|
||||
|
||||
save_kx_hint(sess, handshake.dns_name.as_ref(), their_key_share.group);
|
||||
sess.common.get_mut_key_schedule().input_secret(&shared.shared_secret);
|
||||
key_schedule.input_secret(&shared.shared_secret);
|
||||
|
||||
hs::check_aligned_handshake(sess)?;
|
||||
|
||||
|
@ -210,7 +213,7 @@ pub fn start_handshake_traffic(sess: &mut ClientSessionImpl,
|
|||
|
||||
if !sess.early_data.is_enabled() {
|
||||
// Set the client encryption key for handshakes if early data is not used
|
||||
let write_key = sess.common.get_key_schedule()
|
||||
let write_key = key_schedule
|
||||
.derive_logged_secret(SecretKind::ClientHandshakeTrafficSecret,
|
||||
&handshake.hash_at_client_recvd_server_hello,
|
||||
&*sess.config.key_log,
|
||||
|
@ -218,10 +221,10 @@ pub fn start_handshake_traffic(sess: &mut ClientSessionImpl,
|
|||
sess.common
|
||||
.record_layer
|
||||
.set_message_encrypter(cipher::new_tls13_write(suite, &write_key));
|
||||
sess.common.get_mut_key_schedule().current_client_traffic_secret = Some(write_key);
|
||||
key_schedule.current_client_traffic_secret = Some(write_key);
|
||||
}
|
||||
|
||||
let read_key = sess.common.get_key_schedule()
|
||||
let read_key = key_schedule
|
||||
.derive_logged_secret(SecretKind::ServerHandshakeTrafficSecret,
|
||||
&handshake.hash_at_client_recvd_server_hello,
|
||||
&*sess.config.key_log,
|
||||
|
@ -229,16 +232,15 @@ pub fn start_handshake_traffic(sess: &mut ClientSessionImpl,
|
|||
sess.common
|
||||
.record_layer
|
||||
.set_message_decrypter(cipher::new_tls13_read(suite, &read_key));
|
||||
sess.common.get_mut_key_schedule().current_server_traffic_secret = Some(read_key);
|
||||
key_schedule.current_server_traffic_secret = Some(read_key);
|
||||
|
||||
#[cfg(feature = "quic")] {
|
||||
let key_schedule = sess.common.key_schedule.as_ref().unwrap();
|
||||
let client = if sess.early_data.is_enabled() {
|
||||
// Traffic secret wasn't computed and stored above, so do it here.
|
||||
sess.common.get_key_schedule().derive(
|
||||
sess.common.get_key_schedule().algorithm(),
|
||||
SecretKind::ClientHandshakeTrafficSecret,
|
||||
&handshake.hash_at_client_recvd_server_hello)
|
||||
key_schedule
|
||||
.derive(key_schedule.algorithm(),
|
||||
SecretKind::ClientHandshakeTrafficSecret,
|
||||
&handshake.hash_at_client_recvd_server_hello)
|
||||
} else {
|
||||
key_schedule.current_client_traffic_secret.clone().unwrap()
|
||||
};
|
||||
|
@ -248,7 +250,7 @@ pub fn start_handshake_traffic(sess: &mut ClientSessionImpl,
|
|||
});
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(key_schedule)
|
||||
}
|
||||
|
||||
pub fn prepare_resumption(sess: &mut ClientSessionImpl,
|
||||
|
@ -344,6 +346,7 @@ fn validate_encrypted_extensions(sess: &mut ClientSessionImpl,
|
|||
|
||||
pub struct ExpectEncryptedExtensions {
|
||||
pub handshake: HandshakeDetails,
|
||||
pub key_schedule: KeySchedule,
|
||||
pub server_cert: ServerCertDetails,
|
||||
pub hello: ClientHelloDetails,
|
||||
}
|
||||
|
@ -354,6 +357,7 @@ impl ExpectEncryptedExtensions {
|
|||
sigv: verify::HandshakeSignatureValid) -> hs::NextState {
|
||||
Box::new(ExpectFinished {
|
||||
handshake: self.handshake,
|
||||
key_schedule: self.key_schedule,
|
||||
client_auth: None,
|
||||
cert_verified: certv,
|
||||
sig_verified: sigv,
|
||||
|
@ -363,6 +367,7 @@ impl ExpectEncryptedExtensions {
|
|||
fn into_expect_certificate_or_certreq(self) -> hs::NextState {
|
||||
Box::new(ExpectCertificateOrCertReq {
|
||||
handshake: self.handshake,
|
||||
key_schedule: self.key_schedule,
|
||||
server_cert: self.server_cert,
|
||||
})
|
||||
}
|
||||
|
@ -402,7 +407,7 @@ impl hs::State for ExpectEncryptedExtensions {
|
|||
if was_early_traffic && !sess.common.early_traffic {
|
||||
// If no early traffic, set the encryption key for handshakes
|
||||
let suite = sess.common.get_suite_assert();
|
||||
let write_key = sess.common.get_key_schedule()
|
||||
let write_key = self.key_schedule
|
||||
.derive_logged_secret(
|
||||
SecretKind::ClientHandshakeTrafficSecret,
|
||||
&self.handshake.hash_at_client_recvd_server_hello,
|
||||
|
@ -411,7 +416,7 @@ impl hs::State for ExpectEncryptedExtensions {
|
|||
sess.common
|
||||
.record_layer
|
||||
.set_message_encrypter(cipher::new_tls13_write(suite, &write_key));
|
||||
sess.common.get_mut_key_schedule()
|
||||
self.key_schedule
|
||||
.current_client_traffic_secret = Some(write_key);
|
||||
}
|
||||
let certv = verify::ServerCertVerified::assertion();
|
||||
|
@ -429,6 +434,7 @@ impl hs::State for ExpectEncryptedExtensions {
|
|||
|
||||
struct ExpectCertificate {
|
||||
handshake: HandshakeDetails,
|
||||
key_schedule: KeySchedule,
|
||||
server_cert: ServerCertDetails,
|
||||
client_auth: Option<ClientAuthDetails>,
|
||||
}
|
||||
|
@ -437,6 +443,7 @@ impl ExpectCertificate {
|
|||
fn into_expect_certificate_verify(self) -> hs::NextState {
|
||||
Box::new(ExpectCertificateVerify {
|
||||
handshake: self.handshake,
|
||||
key_schedule: self.key_schedule,
|
||||
server_cert: self.server_cert,
|
||||
client_auth: self.client_auth,
|
||||
})
|
||||
|
@ -488,6 +495,7 @@ impl hs::State for ExpectCertificate {
|
|||
|
||||
struct ExpectCertificateOrCertReq {
|
||||
handshake: HandshakeDetails,
|
||||
key_schedule: KeySchedule,
|
||||
server_cert: ServerCertDetails,
|
||||
}
|
||||
|
||||
|
@ -495,6 +503,7 @@ impl ExpectCertificateOrCertReq {
|
|||
fn into_expect_certificate(self) -> hs::NextState {
|
||||
Box::new(ExpectCertificate {
|
||||
handshake: self.handshake,
|
||||
key_schedule: self.key_schedule,
|
||||
server_cert: self.server_cert,
|
||||
client_auth: None,
|
||||
})
|
||||
|
@ -503,6 +512,7 @@ impl ExpectCertificateOrCertReq {
|
|||
fn into_expect_certificate_req(self) -> hs::NextState {
|
||||
Box::new(ExpectCertificateRequest {
|
||||
handshake: self.handshake,
|
||||
key_schedule: self.key_schedule,
|
||||
server_cert: self.server_cert,
|
||||
})
|
||||
}
|
||||
|
@ -527,16 +537,18 @@ impl hs::State for ExpectCertificateOrCertReq {
|
|||
// --- TLS1.3 CertificateVerify ---
|
||||
struct ExpectCertificateVerify {
|
||||
handshake: HandshakeDetails,
|
||||
key_schedule: KeySchedule,
|
||||
server_cert: ServerCertDetails,
|
||||
client_auth: Option<ClientAuthDetails>,
|
||||
}
|
||||
|
||||
impl ExpectCertificateVerify {
|
||||
fn into_expect_finished(self,
|
||||
certv: verify::ServerCertVerified,
|
||||
sigv: verify::HandshakeSignatureValid) -> hs::NextState {
|
||||
certv: verify::ServerCertVerified,
|
||||
sigv: verify::HandshakeSignatureValid) -> hs::NextState {
|
||||
Box::new(ExpectFinished {
|
||||
handshake: self.handshake,
|
||||
key_schedule: self.key_schedule,
|
||||
client_auth: self.client_auth,
|
||||
cert_verified: certv,
|
||||
sig_verified: sigv,
|
||||
|
@ -613,6 +625,7 @@ impl hs::State for ExpectCertificateVerify {
|
|||
// in TLS1.3.
|
||||
struct ExpectCertificateRequest {
|
||||
handshake: HandshakeDetails,
|
||||
key_schedule: KeySchedule,
|
||||
server_cert: ServerCertDetails,
|
||||
}
|
||||
|
||||
|
@ -620,6 +633,7 @@ impl ExpectCertificateRequest {
|
|||
fn into_expect_certificate(self, client_auth: ClientAuthDetails) -> hs::NextState {
|
||||
Box::new(ExpectCertificate {
|
||||
handshake: self.handshake,
|
||||
key_schedule: self.key_schedule,
|
||||
server_cert: self.server_cert,
|
||||
client_auth: Some(client_auth),
|
||||
})
|
||||
|
@ -747,10 +761,10 @@ fn emit_certverify_tls13(handshake: &mut HandshakeDetails,
|
|||
}
|
||||
|
||||
fn emit_finished_tls13(handshake: &mut HandshakeDetails,
|
||||
key_schedule: &KeySchedule,
|
||||
sess: &mut ClientSessionImpl) {
|
||||
let handshake_hash = handshake.transcript.get_current_hash();
|
||||
let verify_data = sess.common
|
||||
.get_key_schedule()
|
||||
let verify_data = key_schedule
|
||||
.sign_finish(SecretKind::ClientHandshakeTrafficSecret, &handshake_hash);
|
||||
let verify_data_payload = Payload::new(verify_data);
|
||||
|
||||
|
@ -789,6 +803,7 @@ fn emit_end_of_early_data_tls13(handshake: &mut HandshakeDetails,
|
|||
|
||||
struct ExpectFinished {
|
||||
handshake: HandshakeDetails,
|
||||
key_schedule: KeySchedule,
|
||||
client_auth: Option<ClientAuthDetails>,
|
||||
cert_verified: verify::ServerCertVerified,
|
||||
sig_verified: verify::HandshakeSignatureValid,
|
||||
|
@ -796,9 +811,11 @@ struct ExpectFinished {
|
|||
|
||||
impl ExpectFinished {
|
||||
fn into_expect_traffic(self,
|
||||
fin: verify::FinishedMessageVerified) -> ExpectTraffic {
|
||||
fin: verify::FinishedMessageVerified) -> ExpectTraffic {
|
||||
ExpectTraffic {
|
||||
handshake: self.handshake,
|
||||
key_schedule: self.key_schedule,
|
||||
want_write_key_update: false,
|
||||
_cert_verified: self.cert_verified,
|
||||
_sig_verified: self.sig_verified,
|
||||
_fin_verified: fin,
|
||||
|
@ -816,8 +833,7 @@ impl hs::State for ExpectFinished {
|
|||
let finished = extract_handshake!(m, HandshakePayload::Finished).unwrap();
|
||||
|
||||
let handshake_hash = st.handshake.transcript.get_current_hash();
|
||||
let expect_verify_data = sess.common
|
||||
.get_key_schedule()
|
||||
let expect_verify_data = st.key_schedule
|
||||
.sign_finish(SecretKind::ServerHandshakeTrafficSecret, &handshake_hash);
|
||||
|
||||
let fin = constant_time::verify_slices_are_equal(&expect_verify_data, &finished.0)
|
||||
|
@ -830,8 +846,7 @@ impl hs::State for ExpectFinished {
|
|||
let suite = sess.common.get_suite_assert();
|
||||
let maybe_write_key = if sess.common.early_traffic {
|
||||
/* Derive the client-to-server encryption key before key schedule update */
|
||||
let key = sess.common
|
||||
.get_key_schedule()
|
||||
let key = st.key_schedule
|
||||
.derive_logged_secret(
|
||||
SecretKind::ClientHandshakeTrafficSecret,
|
||||
&st.handshake.hash_at_client_recvd_server_hello,
|
||||
|
@ -845,12 +860,11 @@ impl hs::State for ExpectFinished {
|
|||
st.handshake.transcript.add_message(&m);
|
||||
|
||||
/* Transition to application data */
|
||||
sess.common.get_mut_key_schedule().input_empty();
|
||||
st.key_schedule.input_empty();
|
||||
|
||||
/* Traffic from server is now decrypted with application data keys. */
|
||||
let handshake_hash = st.handshake.transcript.get_current_hash();
|
||||
let read_key = sess.common
|
||||
.get_key_schedule()
|
||||
let read_key = st.key_schedule
|
||||
.derive_logged_secret(
|
||||
SecretKind::ServerApplicationTrafficSecret,
|
||||
&handshake_hash,
|
||||
|
@ -859,18 +873,15 @@ impl hs::State for ExpectFinished {
|
|||
sess.common
|
||||
.record_layer
|
||||
.set_message_decrypter(cipher::new_tls13_read(suite, &read_key));
|
||||
sess.common
|
||||
.get_mut_key_schedule()
|
||||
st.key_schedule
|
||||
.current_server_traffic_secret = Some(read_key);
|
||||
|
||||
let exporter_secret = sess.common
|
||||
.get_key_schedule()
|
||||
let exporter_secret = st.key_schedule
|
||||
.derive_logged_secret(SecretKind::ExporterMasterSecret,
|
||||
&handshake_hash,
|
||||
&*sess.config.key_log,
|
||||
&st.handshake.randoms.client);
|
||||
sess.common
|
||||
.get_mut_key_schedule()
|
||||
st.key_schedule
|
||||
.current_exporter_secret = Some(exporter_secret);
|
||||
|
||||
/* The EndOfEarlyData message to server is still encrypted with early data keys,
|
||||
|
@ -882,7 +893,8 @@ impl hs::State for ExpectFinished {
|
|||
sess.common
|
||||
.record_layer
|
||||
.set_message_encrypter(cipher::new_tls13_write(suite, &write_key));
|
||||
sess.common.get_mut_key_schedule().current_client_traffic_secret = Some(write_key);
|
||||
st.key_schedule
|
||||
.current_client_traffic_secret = Some(write_key);
|
||||
}
|
||||
|
||||
/* Send our authentication/finished messages. These are still encrypted
|
||||
|
@ -896,12 +908,11 @@ impl hs::State for ExpectFinished {
|
|||
sess)?;
|
||||
}
|
||||
|
||||
emit_finished_tls13(&mut st.handshake, sess);
|
||||
emit_finished_tls13(&mut st.handshake, &st.key_schedule, sess);
|
||||
|
||||
/* Now move to our application traffic keys. */
|
||||
hs::check_aligned_handshake(sess)?;
|
||||
let write_key = sess.common
|
||||
.get_key_schedule()
|
||||
let write_key = st.key_schedule
|
||||
.derive_logged_secret(SecretKind::ClientApplicationTrafficSecret,
|
||||
&handshake_hash,
|
||||
&*sess.config.key_log,
|
||||
|
@ -909,8 +920,7 @@ impl hs::State for ExpectFinished {
|
|||
sess.common
|
||||
.record_layer
|
||||
.set_message_encrypter(cipher::new_tls13_write(suite, &write_key));
|
||||
sess.common
|
||||
.get_mut_key_schedule()
|
||||
st.key_schedule
|
||||
.current_client_traffic_secret = Some(write_key);
|
||||
|
||||
sess.common.start_traffic();
|
||||
|
@ -918,10 +928,9 @@ impl hs::State for ExpectFinished {
|
|||
let st = st.into_expect_traffic(fin);
|
||||
#[cfg(feature = "quic")] {
|
||||
if sess.common.protocol == Protocol::Quic {
|
||||
let key_schedule = sess.common.key_schedule.as_ref().unwrap();
|
||||
sess.common.quic.traffic_secrets = Some(quic::Secrets {
|
||||
client: key_schedule.current_client_traffic_secret.clone().unwrap(),
|
||||
server: key_schedule.current_server_traffic_secret.clone().unwrap(),
|
||||
client: st.key_schedule.current_client_traffic_secret.clone().unwrap(),
|
||||
server: st.key_schedule.current_server_traffic_secret.clone().unwrap(),
|
||||
});
|
||||
return Ok(Box::new(ExpectQUICTraffic(st)));
|
||||
}
|
||||
|
@ -936,6 +945,8 @@ impl hs::State for ExpectFinished {
|
|||
// and application data.
|
||||
struct ExpectTraffic {
|
||||
handshake: HandshakeDetails,
|
||||
key_schedule: KeySchedule,
|
||||
want_write_key_update: bool,
|
||||
_cert_verified: verify::ServerCertVerified,
|
||||
_sig_verified: verify::HandshakeSignatureValid,
|
||||
_fin_verified: verify::FinishedMessageVerified,
|
||||
|
@ -945,11 +956,11 @@ impl ExpectTraffic {
|
|||
fn handle_new_ticket_tls13(&mut self, sess: &mut ClientSessionImpl, m: Message) -> Result<(), TLSError> {
|
||||
let nst = extract_handshake!(m, HandshakePayload::NewSessionTicketTLS13).unwrap();
|
||||
let handshake_hash = self.handshake.transcript.get_current_hash();
|
||||
let key_schedule = sess.common.get_key_schedule();
|
||||
let resumption_master_secret =
|
||||
key_schedule.derive(key_schedule.algorithm(), SecretKind::ResumptionMasterSecret, &handshake_hash);
|
||||
let secret = sess.common
|
||||
.get_key_schedule()
|
||||
let resumption_master_secret = self.key_schedule
|
||||
.derive(self.key_schedule.algorithm(),
|
||||
SecretKind::ResumptionMasterSecret,
|
||||
&handshake_hash);
|
||||
let secret = self.key_schedule
|
||||
.derive_ticket_psk(&resumption_master_secret, &nst.nonce.0);
|
||||
|
||||
let mut value = persist::ClientSessionValue::new(ProtocolVersion::TLSv1_3,
|
||||
|
@ -995,7 +1006,38 @@ impl ExpectTraffic {
|
|||
|
||||
fn handle_key_update(&mut self, sess: &mut ClientSessionImpl, m: Message) -> Result<(), TLSError> {
|
||||
let kur = extract_handshake!(m, HandshakePayload::KeyUpdate).unwrap();
|
||||
sess.common.process_key_update(*kur, SecretKind::ServerApplicationTrafficSecret)
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
{
|
||||
if let Protocol::Quic = sess.common.protocol {
|
||||
sess.common.send_fatal_alert(AlertDescription::UnexpectedMessage);
|
||||
let msg = "KeyUpdate received in QUIC connection".to_string();
|
||||
warn!("{}", msg);
|
||||
return Err(TLSError::PeerMisbehavedError(msg));
|
||||
}
|
||||
}
|
||||
|
||||
// Mustn't be interleaved with other handshake messages.
|
||||
hs::check_aligned_handshake(sess)?;
|
||||
|
||||
match kur {
|
||||
KeyUpdateRequest::UpdateNotRequested => {}
|
||||
KeyUpdateRequest::UpdateRequested => {
|
||||
self.want_write_key_update = true;
|
||||
}
|
||||
_ => {
|
||||
sess.common.send_fatal_alert(AlertDescription::IllegalParameter);
|
||||
return Err(TLSError::CorruptMessagePayload(ContentType::Handshake));
|
||||
}
|
||||
}
|
||||
|
||||
// Update our read-side keys.
|
||||
let new_read_key = self.key_schedule.derive_next(SecretKind::ServerApplicationTrafficSecret);
|
||||
let suite = sess.common.get_suite_assert();
|
||||
sess.common.record_layer.set_message_decrypter(cipher::new_tls13_read(suite, &new_read_key));
|
||||
self.key_schedule.current_server_traffic_secret = Some(new_read_key);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1019,11 +1061,22 @@ impl hs::State for ExpectTraffic {
|
|||
}
|
||||
|
||||
fn export_keying_material(&self,
|
||||
sess: &ClientSessionImpl,
|
||||
output: &mut [u8],
|
||||
label: &[u8],
|
||||
context: Option<&[u8]>) -> Result<(), TLSError> {
|
||||
sess.common.get_key_schedule().export_keying_material(output, label, context)
|
||||
self.key_schedule.export_keying_material(output, label, context)
|
||||
}
|
||||
|
||||
fn perhaps_write_key_update(&mut self, sess: &mut ClientSessionImpl) {
|
||||
if self.want_write_key_update {
|
||||
self.want_write_key_update = false;
|
||||
sess.common.send_msg_encrypt(Message::build_key_update_notify());
|
||||
|
||||
let write_key = self.key_schedule.derive_next(SecretKind::ClientApplicationTrafficSecret);
|
||||
let scs = sess.common.get_suite_assert();
|
||||
sess.common.record_layer.set_message_encrypter(cipher::new_tls13_write(scs, &write_key));
|
||||
self.key_schedule.current_client_traffic_secret = Some(write_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,12 +53,14 @@ pub trait State {
|
|||
fn handle(self: Box<Self>, sess: &mut ServerSessionImpl, m: Message) -> NextStateOrError;
|
||||
|
||||
fn export_keying_material(&self,
|
||||
_sess: &ServerSessionImpl,
|
||||
_output: &mut [u8],
|
||||
_label: &[u8],
|
||||
_context: Option<&[u8]>) -> Result<(), TLSError> {
|
||||
Err(TLSError::HandshakeNotComplete)
|
||||
}
|
||||
|
||||
fn perhaps_write_key_update(&mut self, _sess: &mut ServerSessionImpl) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn incompatible(sess: &mut ServerSessionImpl, why: &str) -> TLSError {
|
||||
|
|
|
@ -484,7 +484,15 @@ impl ServerSessionImpl {
|
|||
self.state
|
||||
.as_ref()
|
||||
.ok_or_else(|| TLSError::HandshakeNotComplete)
|
||||
.and_then(|st| st.export_keying_material(self, output, label, context))
|
||||
.and_then(|st| st.export_keying_material(output, label, context))
|
||||
}
|
||||
|
||||
fn send_some_plaintext(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
let mut st = self.state.take();
|
||||
st.as_mut()
|
||||
.map(|st| st.perhaps_write_key_update(self));
|
||||
self.state = st;
|
||||
self.common.send_some_plaintext(buf)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -640,7 +648,7 @@ impl io::Write for ServerSession {
|
|||
/// writing much data before it can be sent will
|
||||
/// cause excess memory usage.
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.imp.common.send_some_plaintext(buf)
|
||||
self.imp.send_some_plaintext(buf)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
|
|
|
@ -398,7 +398,6 @@ impl hs::State for ExpectTraffic {
|
|||
}
|
||||
|
||||
fn export_keying_material(&self,
|
||||
_sess: &ServerSessionImpl,
|
||||
output: &mut [u8],
|
||||
label: &[u8],
|
||||
context: Option<&[u8]>) -> Result<(), TLSError> {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::msgs::enums::{ContentType, HandshakeType, ProtocolVersion};
|
||||
use crate::msgs::enums::{AlertDescription, SignatureScheme, NamedGroup};
|
||||
use crate::msgs::enums::{Compression, PSKKeyExchangeMode};
|
||||
use crate::msgs::enums::KeyUpdateRequest;
|
||||
use crate::msgs::message::{Message, MessagePayload};
|
||||
use crate::msgs::handshake::HandshakePayload;
|
||||
use crate::msgs::handshake::HandshakeMessagePayload;
|
||||
|
@ -88,16 +89,18 @@ impl CompleteClientHelloHandling {
|
|||
})
|
||||
}
|
||||
|
||||
fn into_expect_certificate(self) -> hs::NextState {
|
||||
fn into_expect_certificate(self, key_schedule: KeySchedule) -> hs::NextState {
|
||||
Box::new(ExpectCertificate {
|
||||
handshake: self.handshake,
|
||||
key_schedule,
|
||||
send_ticket: self.send_ticket,
|
||||
})
|
||||
}
|
||||
|
||||
fn into_expect_finished(self) -> hs::NextState {
|
||||
fn into_expect_finished(self, key_schedule: KeySchedule) -> hs::NextState {
|
||||
Box::new(ExpectFinished {
|
||||
handshake: self.handshake,
|
||||
key_schedule,
|
||||
send_ticket: self.send_ticket,
|
||||
})
|
||||
}
|
||||
|
@ -108,7 +111,7 @@ impl CompleteClientHelloHandling {
|
|||
share: &KeyShareEntry,
|
||||
chosen_psk_idx: Option<usize>,
|
||||
resuming_psk: Option<&[u8]>)
|
||||
-> Result<(), TLSError> {
|
||||
-> Result<KeySchedule, TLSError> {
|
||||
let mut extensions = Vec::new();
|
||||
|
||||
// Do key exchange
|
||||
|
@ -202,9 +205,8 @@ impl CompleteClientHelloHandling {
|
|||
|
||||
key_schedule.current_client_traffic_secret = Some(read_key);
|
||||
key_schedule.current_server_traffic_secret = Some(write_key);
|
||||
sess.common.set_key_schedule(key_schedule);
|
||||
|
||||
Ok(())
|
||||
Ok(key_schedule)
|
||||
}
|
||||
|
||||
fn emit_fake_ccs(&mut self,
|
||||
|
@ -388,10 +390,10 @@ impl CompleteClientHelloHandling {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn emit_finished_tls13(&mut self, sess: &mut ServerSessionImpl) {
|
||||
fn emit_finished_tls13(&mut self, sess: &mut ServerSessionImpl,
|
||||
key_schedule: &mut KeySchedule) {
|
||||
let handshake_hash = self.handshake.transcript.get_current_hash();
|
||||
let verify_data = sess.common
|
||||
.get_key_schedule()
|
||||
let verify_data = key_schedule
|
||||
.sign_finish(SecretKind::ServerHandshakeTrafficSecret, &handshake_hash);
|
||||
let verify_data_payload = Payload::new(verify_data);
|
||||
|
||||
|
@ -410,9 +412,8 @@ impl CompleteClientHelloHandling {
|
|||
sess.common.send_msg(m, true);
|
||||
|
||||
// Now move to application data keys.
|
||||
sess.common.get_mut_key_schedule().input_empty();
|
||||
let write_key = sess.common
|
||||
.get_key_schedule()
|
||||
key_schedule.input_empty();
|
||||
let write_key = key_schedule
|
||||
.derive_logged_secret(SecretKind::ServerApplicationTrafficSecret,
|
||||
&self.handshake.hash_at_server_fin,
|
||||
&*sess.config.key_log,
|
||||
|
@ -423,8 +424,8 @@ impl CompleteClientHelloHandling {
|
|||
.set_message_encrypter(cipher::new_tls13_write(suite, &write_key));
|
||||
|
||||
#[cfg(feature = "quic")] {
|
||||
let read_key = sess.common.get_key_schedule()
|
||||
.derive(sess.common.get_key_schedule().algorithm(),
|
||||
let read_key = key_schedule
|
||||
.derive(key_schedule.algorithm(),
|
||||
SecretKind::ClientApplicationTrafficSecret,
|
||||
&self.handshake.hash_at_server_fin);
|
||||
sess.common.quic.traffic_secrets = Some(quic::Secrets {
|
||||
|
@ -433,17 +434,13 @@ impl CompleteClientHelloHandling {
|
|||
});
|
||||
}
|
||||
|
||||
sess.common.get_mut_key_schedule()
|
||||
.current_server_traffic_secret = Some(write_key);
|
||||
let exporter_secret = sess.common
|
||||
.get_key_schedule()
|
||||
key_schedule.current_server_traffic_secret = Some(write_key);
|
||||
let exporter_secret = key_schedule
|
||||
.derive_logged_secret(SecretKind::ExporterMasterSecret,
|
||||
&self.handshake.hash_at_server_fin,
|
||||
&*sess.config.key_log,
|
||||
&self.handshake.randoms.client);
|
||||
sess.common
|
||||
.get_mut_key_schedule()
|
||||
.current_exporter_secret = Some(exporter_secret);
|
||||
key_schedule.current_exporter_secret = Some(exporter_secret);
|
||||
}
|
||||
|
||||
fn attempt_tls13_ticket_decryption(&mut self,
|
||||
|
@ -581,9 +578,9 @@ impl CompleteClientHelloHandling {
|
|||
|
||||
let full_handshake = resumedata.is_none();
|
||||
self.handshake.transcript.add_message(chm);
|
||||
self.emit_server_hello(sess, &client_hello.session_id,
|
||||
chosen_share, chosen_psk_index,
|
||||
resumedata.as_ref().map(|x| &x.master_secret.0[..]))?;
|
||||
let mut key_schedule = self.emit_server_hello(sess, &client_hello.session_id,
|
||||
chosen_share, chosen_psk_index,
|
||||
resumedata.as_ref().map(|x| &x.master_secret.0[..]))?;
|
||||
if !self.done_retry {
|
||||
self.emit_fake_ccs(sess);
|
||||
}
|
||||
|
@ -599,24 +596,26 @@ impl CompleteClientHelloHandling {
|
|||
};
|
||||
|
||||
hs::check_aligned_handshake(sess)?;
|
||||
self.emit_finished_tls13(sess);
|
||||
self.emit_finished_tls13(sess, &mut key_schedule);
|
||||
|
||||
if doing_client_auth {
|
||||
Ok(self.into_expect_certificate())
|
||||
Ok(self.into_expect_certificate(key_schedule))
|
||||
} else {
|
||||
Ok(self.into_expect_finished())
|
||||
Ok(self.into_expect_finished(key_schedule))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ExpectCertificate {
|
||||
pub handshake: HandshakeDetails,
|
||||
pub key_schedule: KeySchedule,
|
||||
pub send_ticket: bool,
|
||||
}
|
||||
|
||||
impl ExpectCertificate {
|
||||
fn into_expect_finished(self) -> hs::NextState {
|
||||
Box::new(ExpectFinished {
|
||||
key_schedule: self.key_schedule,
|
||||
handshake: self.handshake,
|
||||
send_ticket: self.send_ticket,
|
||||
})
|
||||
|
@ -626,6 +625,7 @@ impl ExpectCertificate {
|
|||
cert: ClientCertDetails) -> hs::NextState {
|
||||
Box::new(ExpectCertificateVerify {
|
||||
handshake: self.handshake,
|
||||
key_schedule: self.key_schedule,
|
||||
client_cert: cert,
|
||||
send_ticket: self.send_ticket,
|
||||
})
|
||||
|
@ -674,6 +674,7 @@ impl hs::State for ExpectCertificate {
|
|||
|
||||
pub struct ExpectCertificateVerify {
|
||||
handshake: HandshakeDetails,
|
||||
key_schedule: KeySchedule,
|
||||
client_cert: ClientCertDetails,
|
||||
send_ticket: bool,
|
||||
}
|
||||
|
@ -681,6 +682,7 @@ pub struct ExpectCertificateVerify {
|
|||
impl ExpectCertificateVerify {
|
||||
fn into_expect_finished(self) -> hs::NextState {
|
||||
Box::new(ExpectFinished {
|
||||
key_schedule: self.key_schedule,
|
||||
handshake: self.handshake,
|
||||
send_ticket: self.send_ticket,
|
||||
})
|
||||
|
@ -720,6 +722,7 @@ impl hs::State for ExpectCertificateVerify {
|
|||
|
||||
// --- Process client's Finished ---
|
||||
fn get_server_session_value(handshake: &mut HandshakeDetails,
|
||||
key_schedule: &KeySchedule,
|
||||
sess: &ServerSessionImpl,
|
||||
nonce: &[u8]) -> persist::ServerSessionValue {
|
||||
let scs = sess.common.get_suite_assert();
|
||||
|
@ -728,13 +731,11 @@ fn get_server_session_value(handshake: &mut HandshakeDetails,
|
|||
let handshake_hash = handshake
|
||||
.transcript
|
||||
.get_current_hash();
|
||||
let key_schedule = sess.common.get_key_schedule();
|
||||
let resumption_master_secret =
|
||||
key_schedule.derive(key_schedule.algorithm(),
|
||||
SecretKind::ResumptionMasterSecret,
|
||||
&handshake_hash);
|
||||
let secret = sess.common
|
||||
.get_key_schedule()
|
||||
let secret = key_schedule
|
||||
.derive_ticket_psk(&resumption_master_secret, nonce);
|
||||
|
||||
persist::ServerSessionValue::new(
|
||||
|
@ -748,12 +749,15 @@ fn get_server_session_value(handshake: &mut HandshakeDetails,
|
|||
|
||||
pub struct ExpectFinished {
|
||||
pub handshake: HandshakeDetails,
|
||||
pub key_schedule: KeySchedule,
|
||||
pub send_ticket: bool,
|
||||
}
|
||||
|
||||
impl ExpectFinished {
|
||||
fn into_expect_traffic(self, fin: verify::FinishedMessageVerified) -> hs::NextState {
|
||||
Box::new(ExpectTraffic {
|
||||
key_schedule: self.key_schedule,
|
||||
want_write_key_update: false,
|
||||
_fin_verified: fin,
|
||||
})
|
||||
}
|
||||
|
@ -762,6 +766,7 @@ impl ExpectFinished {
|
|||
debug_assert!(self.send_ticket);
|
||||
let nonce = rand::random_vec(32);
|
||||
let plain = get_server_session_value(&mut self.handshake,
|
||||
&self.key_schedule,
|
||||
sess, &nonce)
|
||||
.get_encoding();
|
||||
let maybe_ticket = sess.config
|
||||
|
@ -801,6 +806,7 @@ impl ExpectFinished {
|
|||
let nonce = rand::random_vec(32);
|
||||
let id = rand::random_vec(32);
|
||||
let plain = get_server_session_value(&mut self.handshake,
|
||||
&self.key_schedule,
|
||||
sess, &nonce)
|
||||
.get_encoding();
|
||||
|
||||
|
@ -841,8 +847,7 @@ impl hs::State for ExpectFinished {
|
|||
let finished = extract_handshake!(m, HandshakePayload::Finished).unwrap();
|
||||
|
||||
let handshake_hash = self.handshake.transcript.get_current_hash();
|
||||
let expect_verify_data = sess.common
|
||||
.get_key_schedule()
|
||||
let expect_verify_data = self.key_schedule
|
||||
.sign_finish(SecretKind::ClientHandshakeTrafficSecret, &handshake_hash);
|
||||
|
||||
let fin = constant_time::verify_slices_are_equal(&expect_verify_data, &finished.0)
|
||||
|
@ -859,8 +864,7 @@ impl hs::State for ExpectFinished {
|
|||
|
||||
// Now move to using application data keys for client traffic.
|
||||
// Server traffic is already done.
|
||||
let read_key = sess.common
|
||||
.get_key_schedule()
|
||||
let read_key = self.key_schedule
|
||||
.derive_logged_secret(SecretKind::ClientApplicationTrafficSecret,
|
||||
&self.handshake.hash_at_server_fin,
|
||||
&*sess.config.key_log,
|
||||
|
@ -871,8 +875,7 @@ impl hs::State for ExpectFinished {
|
|||
sess.common
|
||||
.record_layer
|
||||
.set_message_decrypter(cipher::new_tls13_read(suite, &read_key));
|
||||
sess.common
|
||||
.get_mut_key_schedule()
|
||||
self.key_schedule
|
||||
.current_client_traffic_secret = Some(read_key);
|
||||
|
||||
if self.send_ticket {
|
||||
|
@ -897,6 +900,8 @@ impl hs::State for ExpectFinished {
|
|||
|
||||
// --- Process traffic ---
|
||||
pub struct ExpectTraffic {
|
||||
key_schedule: KeySchedule,
|
||||
want_write_key_update: bool,
|
||||
_fin_verified: verify::FinishedMessageVerified,
|
||||
}
|
||||
|
||||
|
@ -906,9 +911,39 @@ impl ExpectTraffic {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_key_update(&self, sess: &mut ServerSessionImpl, m: Message) -> Result<(), TLSError> {
|
||||
fn handle_key_update(&mut self, sess: &mut ServerSessionImpl, m: Message) -> Result<(), TLSError> {
|
||||
let kur = extract_handshake!(m, HandshakePayload::KeyUpdate).unwrap();
|
||||
sess.common.process_key_update(*kur, SecretKind::ClientApplicationTrafficSecret)
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
{
|
||||
if let Protocol::Quic = sess.common.protocol {
|
||||
sess.common.send_fatal_alert(AlertDescription::UnexpectedMessage);
|
||||
let msg = "KeyUpdate received in QUIC connection".to_string();
|
||||
warn!("{}", msg);
|
||||
return Err(TLSError::PeerMisbehavedError(msg));
|
||||
}
|
||||
}
|
||||
|
||||
hs::check_aligned_handshake(sess)?;
|
||||
|
||||
match kur {
|
||||
KeyUpdateRequest::UpdateNotRequested => {}
|
||||
KeyUpdateRequest::UpdateRequested => {
|
||||
self.want_write_key_update = true;
|
||||
}
|
||||
_ => {
|
||||
sess.common.send_fatal_alert(AlertDescription::IllegalParameter);
|
||||
return Err(TLSError::CorruptMessagePayload(ContentType::Handshake));
|
||||
}
|
||||
}
|
||||
|
||||
// Update our read-side keys.
|
||||
let new_read_key = self.key_schedule.derive_next(SecretKind::ClientApplicationTrafficSecret);
|
||||
let suite = sess.common.get_suite_assert();
|
||||
sess.common.record_layer.set_message_decrypter(cipher::new_tls13_read(suite, &new_read_key));
|
||||
self.key_schedule.current_client_traffic_secret = Some(new_read_key);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -919,7 +954,7 @@ impl hs::State for ExpectTraffic {
|
|||
&[HandshakeType::KeyUpdate])
|
||||
}
|
||||
|
||||
fn handle(self: Box<Self>, sess: &mut ServerSessionImpl, m: Message) -> hs::NextStateOrError {
|
||||
fn handle(mut self: Box<Self>, sess: &mut ServerSessionImpl, m: Message) -> hs::NextStateOrError {
|
||||
if m.is_content_type(ContentType::ApplicationData) {
|
||||
self.handle_traffic(sess, m)?;
|
||||
} else if m.is_handshake_type(HandshakeType::KeyUpdate) {
|
||||
|
@ -930,11 +965,22 @@ impl hs::State for ExpectTraffic {
|
|||
}
|
||||
|
||||
fn export_keying_material(&self,
|
||||
sess: &ServerSessionImpl,
|
||||
output: &mut [u8],
|
||||
label: &[u8],
|
||||
context: Option<&[u8]>) -> Result<(), TLSError> {
|
||||
sess.common.get_key_schedule().export_keying_material(output, label, context)
|
||||
self.key_schedule.export_keying_material(output, label, context)
|
||||
}
|
||||
|
||||
fn perhaps_write_key_update(&mut self, sess: &mut ServerSessionImpl) {
|
||||
if self.want_write_key_update {
|
||||
self.want_write_key_update = false;
|
||||
sess.common.send_msg_encrypt(Message::build_key_update_notify());
|
||||
|
||||
let write_key = self.key_schedule.derive_next(SecretKind::ServerApplicationTrafficSecret);
|
||||
let scs = sess.common.get_suite_assert();
|
||||
sess.common.record_layer.set_message_encrypter(cipher::new_tls13_write(scs, &write_key));
|
||||
self.key_schedule.current_server_traffic_secret = Some(write_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,13 +7,11 @@ use crate::msgs::hsjoiner::HandshakeJoiner;
|
|||
use crate::msgs::base::Payload;
|
||||
use crate::msgs::codec::Codec;
|
||||
use crate::msgs::enums::{ContentType, ProtocolVersion, AlertDescription, AlertLevel};
|
||||
use crate::msgs::enums::KeyUpdateRequest;
|
||||
use crate::error::TLSError;
|
||||
use crate::suites::SupportedCipherSuite;
|
||||
use crate::cipher;
|
||||
use crate::vecbuf::{ChunkVecBuffer, WriteV};
|
||||
use crate::key;
|
||||
use crate::key_schedule::{SecretKind, KeySchedule};
|
||||
use crate::prf;
|
||||
use crate::rand;
|
||||
use crate::quic;
|
||||
|
@ -401,12 +399,10 @@ pub struct SessionCommon {
|
|||
pub negotiated_version: Option<ProtocolVersion>,
|
||||
pub is_client: bool,
|
||||
pub record_layer: record_layer::RecordLayer,
|
||||
pub key_schedule: Option<KeySchedule>,
|
||||
suite: Option<&'static SupportedCipherSuite>,
|
||||
peer_eof: bool,
|
||||
pub traffic: bool,
|
||||
pub early_traffic: bool,
|
||||
pub want_write_key_update: bool,
|
||||
pub message_deframer: MessageDeframer,
|
||||
pub handshake_joiner: HandshakeJoiner,
|
||||
pub message_fragmenter: MessageFragmenter,
|
||||
|
@ -426,11 +422,9 @@ impl SessionCommon {
|
|||
is_client: client,
|
||||
record_layer: record_layer::RecordLayer::new(),
|
||||
suite: None,
|
||||
key_schedule: None,
|
||||
peer_eof: false,
|
||||
traffic: false,
|
||||
early_traffic: false,
|
||||
want_write_key_update: false,
|
||||
message_deframer: MessageDeframer::new(),
|
||||
handshake_joiner: HandshakeJoiner::new(),
|
||||
message_fragmenter: MessageFragmenter::new(mtu.unwrap_or(MAX_FRAGMENT_LEN)),
|
||||
|
@ -472,18 +466,6 @@ impl SessionCommon {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_mut_key_schedule(&mut self) -> &mut KeySchedule {
|
||||
self.key_schedule.as_mut().unwrap()
|
||||
}
|
||||
|
||||
pub fn get_key_schedule(&self) -> &KeySchedule {
|
||||
self.key_schedule.as_ref().unwrap()
|
||||
}
|
||||
|
||||
pub fn set_key_schedule(&mut self, ks: KeySchedule) {
|
||||
self.key_schedule = Some(ks);
|
||||
}
|
||||
|
||||
pub fn decrypt_incoming(&mut self, encr: Message) -> Result<Message, TLSError> {
|
||||
if self.record_layer.wants_close_before_decrypt() {
|
||||
self.send_close_notify();
|
||||
|
@ -539,36 +521,9 @@ impl SessionCommon {
|
|||
}
|
||||
}
|
||||
|
||||
fn do_write_key_update(&mut self) {
|
||||
// TLS1.3 putting key update triggering here breaks layering
|
||||
// between the handshake and record layer.
|
||||
let kind = if self.is_client {
|
||||
SecretKind::ClientApplicationTrafficSecret
|
||||
} else {
|
||||
SecretKind::ServerApplicationTrafficSecret
|
||||
};
|
||||
|
||||
self.want_write_key_update = false;
|
||||
self.send_msg_encrypt(Message::build_key_update_notify());
|
||||
|
||||
let write_key = self.get_key_schedule().derive_next(kind);
|
||||
let scs = self.get_suite_assert();
|
||||
self.record_layer.set_message_encrypter(cipher::new_tls13_write(scs, &write_key));
|
||||
|
||||
if self.is_client {
|
||||
self.get_mut_key_schedule().current_client_traffic_secret = Some(write_key);
|
||||
} else {
|
||||
self.get_mut_key_schedule().current_server_traffic_secret = Some(write_key);
|
||||
}
|
||||
}
|
||||
|
||||
/// Fragment `m`, encrypt the fragments, and then queue
|
||||
/// the encrypted fragments for sending.
|
||||
pub fn send_msg_encrypt(&mut self, m: Message) {
|
||||
if self.want_write_key_update {
|
||||
self.do_write_key_update();
|
||||
}
|
||||
|
||||
let mut plain_messages = VecDeque::new();
|
||||
self.message_fragmenter.fragment(m, &mut plain_messages);
|
||||
|
||||
|
@ -581,10 +536,6 @@ impl SessionCommon {
|
|||
fn send_appdata_encrypt(&mut self,
|
||||
payload: &[u8],
|
||||
limit: Limit) -> usize {
|
||||
if self.want_write_key_update {
|
||||
self.do_write_key_update();
|
||||
}
|
||||
|
||||
// Here, the limit on sendable_tls applies to encrypted data,
|
||||
// but we're respecting it for plaintext data -- so we'll
|
||||
// be out by whatever the cipher+record overhead is. That's a
|
||||
|
@ -724,7 +675,7 @@ impl SessionCommon {
|
|||
"QUIC uses TLS for the cryptographic handshake only");
|
||||
let mut bytes = Vec::new();
|
||||
m.payload.encode(&mut bytes);
|
||||
self.quic.hs_queue.push_back((self.key_schedule.is_some(), bytes));
|
||||
self.quic.hs_queue.push_back((must_encrypt, bytes));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -777,53 +728,6 @@ impl SessionCommon {
|
|||
self.send_warning_alert_no_log(AlertDescription::CloseNotify);
|
||||
}
|
||||
|
||||
pub fn process_key_update(&mut self,
|
||||
kur: KeyUpdateRequest,
|
||||
read_kind: SecretKind)
|
||||
-> Result<(), TLSError> {
|
||||
#[cfg(feature = "quic")]
|
||||
{
|
||||
if let Protocol::Quic = self.protocol {
|
||||
self.send_fatal_alert(AlertDescription::UnexpectedMessage);
|
||||
let msg = "KeyUpdate received in QUIC connection".to_string();
|
||||
warn!("{}", msg);
|
||||
return Err(TLSError::PeerMisbehavedError(msg));
|
||||
}
|
||||
}
|
||||
|
||||
// Mustn't be interleaved with other handshake messages.
|
||||
if !self.handshake_joiner.is_empty() {
|
||||
let msg = "KeyUpdate received at wrong time".to_string();
|
||||
warn!("{}", msg);
|
||||
return Err(TLSError::PeerMisbehavedError(msg));
|
||||
}
|
||||
|
||||
match kur {
|
||||
KeyUpdateRequest::UpdateNotRequested => {}
|
||||
KeyUpdateRequest::UpdateRequested => {
|
||||
self.want_write_key_update = true;
|
||||
}
|
||||
_ => {
|
||||
self.send_fatal_alert(AlertDescription::IllegalParameter);
|
||||
return Err(TLSError::CorruptMessagePayload(ContentType::Handshake));
|
||||
}
|
||||
}
|
||||
|
||||
// Update our read-side keys.
|
||||
let new_read_key = self.get_key_schedule()
|
||||
.derive_next(read_kind);
|
||||
let suite = self.get_suite_assert();
|
||||
self.record_layer.set_message_decrypter(cipher::new_tls13_read(suite, &new_read_key));
|
||||
|
||||
if read_kind == SecretKind::ServerApplicationTrafficSecret {
|
||||
self.get_mut_key_schedule().current_server_traffic_secret = Some(new_read_key);
|
||||
} else {
|
||||
self.get_mut_key_schedule().current_client_traffic_secret = Some(new_read_key);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn send_warning_alert_no_log(&mut self, desc: AlertDescription) {
|
||||
let m = Message::build_alert(AlertLevel::Warning, desc);
|
||||
self.send_msg(m, self.record_layer.is_encrypting());
|
||||
|
|
Loading…
Reference in New Issue