mirror of https://github.com/ctz/rustls
Improve encapsulation of key material during TLS 1.3 key schedule.
This commit is contained in:
parent
952e172f87
commit
1d99471355
|
@ -13,7 +13,7 @@ categories = ["network-programming", "cryptography"]
|
|||
[dependencies]
|
||||
base64 = "0.10"
|
||||
log = { version = "0.4.4", optional = true }
|
||||
ring = "0.16.4"
|
||||
ring = "0.16.5"
|
||||
sct = "0.6.0"
|
||||
webpki = "0.21.0"
|
||||
|
||||
|
|
|
@ -122,19 +122,17 @@ pub fn new_tls12(scs: &'static SupportedCipherSuite,
|
|||
}
|
||||
|
||||
pub fn new_tls13_read(scs: &'static SupportedCipherSuite,
|
||||
secret: &[u8]) -> Box<dyn MessageDecrypter> {
|
||||
let secret = hkdf::Prk::new_less_safe(scs.hkdf_algorithm, secret);
|
||||
let key = derive_traffic_key(&secret, scs.get_aead_alg());
|
||||
let iv = derive_traffic_iv(&secret);
|
||||
secret: &hkdf::Prk) -> Box<dyn MessageDecrypter> {
|
||||
let key = derive_traffic_key(secret, scs.get_aead_alg());
|
||||
let iv = derive_traffic_iv(secret);
|
||||
|
||||
Box::new(TLS13MessageDecrypter::new(key, iv))
|
||||
}
|
||||
|
||||
pub fn new_tls13_write(scs: &'static SupportedCipherSuite,
|
||||
secret: &[u8]) -> Box<dyn MessageEncrypter> {
|
||||
let secret = hkdf::Prk::new_less_safe(scs.hkdf_algorithm, secret);
|
||||
let key = derive_traffic_key(&secret, scs.get_aead_alg());
|
||||
let iv = derive_traffic_iv(&secret);
|
||||
secret: &hkdf::Prk) -> Box<dyn MessageEncrypter> {
|
||||
let key = derive_traffic_key(secret, scs.get_aead_alg());
|
||||
let iv = derive_traffic_iv(secret);
|
||||
|
||||
Box::new(TLS13MessageEncrypter::new(key, iv))
|
||||
}
|
||||
|
|
|
@ -330,15 +330,14 @@ fn emit_client_hello_for_retry(sess: &mut ClientSessionImpl,
|
|||
let client_hello_hash = handshake.transcript.get_hash_given(resuming_suite.get_hash(), &[]);
|
||||
let client_early_traffic_secret = sess.common
|
||||
.get_key_schedule()
|
||||
.derive_bytes(SecretKind::ClientEarlyTrafficSecret, &client_hello_hash);
|
||||
.derive_logged_secret(SecretKind::ClientEarlyTrafficSecret, &client_hello_hash,
|
||||
&*sess.config.key_log,
|
||||
sess.common.protocol.labels().client_early_traffic_secret,
|
||||
&handshake.randoms.client);
|
||||
// Set early data encryption key
|
||||
sess.common
|
||||
.set_message_encrypter(cipher::new_tls13_write(resuming_suite, &client_early_traffic_secret));
|
||||
|
||||
sess.config.key_log.log(sess.common.protocol.labels().client_early_traffic_secret,
|
||||
&handshake.randoms.client,
|
||||
&client_early_traffic_secret);
|
||||
|
||||
#[cfg(feature = "quic")]
|
||||
{
|
||||
sess.common.quic.early_secret = Some(client_early_traffic_secret);
|
||||
|
|
|
@ -211,31 +211,32 @@ 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()
|
||||
.derive_bytes(SecretKind::ClientHandshakeTrafficSecret,
|
||||
&handshake.hash_at_client_recvd_server_hello);
|
||||
.derive_logged_secret(SecretKind::ClientHandshakeTrafficSecret,
|
||||
&handshake.hash_at_client_recvd_server_hello,
|
||||
&*sess.config.key_log,
|
||||
sess.common.protocol.labels().client_handshake_traffic_secret,
|
||||
&handshake.randoms.client);
|
||||
sess.common.set_message_encrypter(cipher::new_tls13_write(suite, &write_key));
|
||||
sess.config.key_log.log(sess.common.protocol.labels().client_handshake_traffic_secret,
|
||||
&handshake.randoms.client,
|
||||
&write_key);
|
||||
sess.common.get_mut_key_schedule().current_client_traffic_secret = write_key;
|
||||
sess.common.get_mut_key_schedule().current_client_traffic_secret = Some(write_key);
|
||||
}
|
||||
|
||||
let read_key = sess.common.get_key_schedule()
|
||||
.derive_bytes(SecretKind::ServerHandshakeTrafficSecret,
|
||||
&handshake.hash_at_client_recvd_server_hello);
|
||||
.derive_logged_secret(SecretKind::ServerHandshakeTrafficSecret,
|
||||
&handshake.hash_at_client_recvd_server_hello,
|
||||
&*sess.config.key_log,
|
||||
sess.common.protocol.labels().server_handshake_traffic_secret,
|
||||
&handshake.randoms.client);
|
||||
sess.common.set_message_decrypter(cipher::new_tls13_read(suite, &read_key));
|
||||
sess.config.key_log.log(sess.common.protocol.labels().server_handshake_traffic_secret,
|
||||
&handshake.randoms.client,
|
||||
&read_key);
|
||||
sess.common.get_mut_key_schedule().current_server_traffic_secret = read_key;
|
||||
sess.common.get_mut_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_bytes(SecretKind::ClientHandshakeTrafficSecret,
|
||||
&handshake.hash_at_client_recvd_server_hello)
|
||||
Some(sess.common.get_key_schedule().derive(
|
||||
sess.common.get_key_schedule().algorithm(),
|
||||
SecretKind::ClientHandshakeTrafficSecret,
|
||||
&handshake.hash_at_client_recvd_server_hello))
|
||||
} else {
|
||||
key_schedule.current_client_traffic_secret.clone()
|
||||
};
|
||||
|
@ -400,14 +401,15 @@ impl hs::State for ExpectEncryptedExtensions {
|
|||
// 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()
|
||||
.derive_bytes(SecretKind::ClientHandshakeTrafficSecret,
|
||||
&self.handshake.hash_at_client_recvd_server_hello);
|
||||
.derive_logged_secret(
|
||||
SecretKind::ClientHandshakeTrafficSecret,
|
||||
&self.handshake.hash_at_client_recvd_server_hello,
|
||||
&*sess.config.key_log,
|
||||
sess.common.protocol.labels().client_handshake_traffic_secret,
|
||||
&self.handshake.randoms.client);
|
||||
sess.common.set_message_encrypter(cipher::new_tls13_write(suite, &write_key));
|
||||
sess.config.key_log.log(sess.common.protocol.labels().client_handshake_traffic_secret,
|
||||
&self.handshake.randoms.client,
|
||||
&write_key);
|
||||
sess.common.get_mut_key_schedule()
|
||||
.current_client_traffic_secret = write_key;
|
||||
.current_client_traffic_secret = Some(write_key);
|
||||
}
|
||||
let certv = verify::ServerCertVerified::assertion();
|
||||
let sigv = verify::HandshakeSignatureValid::assertion();
|
||||
|
@ -827,8 +829,12 @@ impl hs::State for ExpectFinished {
|
|||
/* Derive the client-to-server encryption key before key schedule update */
|
||||
let key = sess.common
|
||||
.get_key_schedule()
|
||||
.derive_bytes(SecretKind::ClientHandshakeTrafficSecret,
|
||||
&st.handshake.hash_at_client_recvd_server_hello);
|
||||
.derive_logged_secret(
|
||||
SecretKind::ClientHandshakeTrafficSecret,
|
||||
&st.handshake.hash_at_client_recvd_server_hello,
|
||||
&*sess.config.key_log,
|
||||
sess.common.protocol.labels().client_handshake_traffic_secret,
|
||||
&st.handshake.randoms.client);
|
||||
Some(key)
|
||||
} else {
|
||||
None
|
||||
|
@ -843,24 +849,27 @@ impl hs::State for ExpectFinished {
|
|||
let handshake_hash = st.handshake.transcript.get_current_hash();
|
||||
let read_key = sess.common
|
||||
.get_key_schedule()
|
||||
.derive_bytes(SecretKind::ServerApplicationTrafficSecret, &handshake_hash);
|
||||
sess.config.key_log.log(sess.common.protocol.labels().server_traffic_secret_0,
|
||||
&st.handshake.randoms.client,
|
||||
&read_key);
|
||||
.derive_logged_secret(
|
||||
SecretKind::ServerApplicationTrafficSecret,
|
||||
&handshake_hash,
|
||||
&*sess.config.key_log,
|
||||
sess.common.protocol.labels().server_traffic_secret_0,
|
||||
&st.handshake.randoms.client);
|
||||
sess.common.set_message_decrypter(cipher::new_tls13_read(suite, &read_key));
|
||||
sess.common
|
||||
.get_mut_key_schedule()
|
||||
.current_server_traffic_secret = read_key;
|
||||
.current_server_traffic_secret = Some(read_key);
|
||||
|
||||
let exporter_secret = sess.common
|
||||
.get_key_schedule()
|
||||
.derive_bytes(SecretKind::ExporterMasterSecret, &handshake_hash);
|
||||
sess.config.key_log.log(sess.common.protocol.labels().exporter_secret,
|
||||
&st.handshake.randoms.client,
|
||||
&exporter_secret);
|
||||
.derive_logged_secret(SecretKind::ExporterMasterSecret,
|
||||
&handshake_hash,
|
||||
&*sess.config.key_log,
|
||||
sess.common.protocol.labels().exporter_secret,
|
||||
&st.handshake.randoms.client);
|
||||
sess.common
|
||||
.get_mut_key_schedule()
|
||||
.current_exporter_secret = exporter_secret;
|
||||
.current_exporter_secret = Some(exporter_secret);
|
||||
|
||||
/* The EndOfEarlyData message to server is still encrypted with early data keys,
|
||||
* but appears in the transcript after the server Finished. */
|
||||
|
@ -869,10 +878,7 @@ impl hs::State for ExpectFinished {
|
|||
sess.common.early_traffic = false;
|
||||
sess.early_data.finished();
|
||||
sess.common.set_message_encrypter(cipher::new_tls13_write(suite, &write_key));
|
||||
sess.config.key_log.log(sess.common.protocol.labels().client_handshake_traffic_secret,
|
||||
&st.handshake.randoms.client,
|
||||
&write_key);
|
||||
sess.common.get_mut_key_schedule().current_client_traffic_secret = write_key;
|
||||
sess.common.get_mut_key_schedule().current_client_traffic_secret = Some(write_key);
|
||||
}
|
||||
|
||||
/* Send our authentication/finished messages. These are still encrypted
|
||||
|
@ -892,14 +898,15 @@ impl hs::State for ExpectFinished {
|
|||
hs::check_aligned_handshake(sess)?;
|
||||
let write_key = sess.common
|
||||
.get_key_schedule()
|
||||
.derive_bytes(SecretKind::ClientApplicationTrafficSecret, &handshake_hash);
|
||||
sess.config.key_log.log(sess.common.protocol.labels().client_traffic_secret_0,
|
||||
&st.handshake.randoms.client,
|
||||
&write_key);
|
||||
.derive_logged_secret(SecretKind::ClientApplicationTrafficSecret,
|
||||
&handshake_hash,
|
||||
&*sess.config.key_log,
|
||||
sess.common.protocol.labels().client_traffic_secret_0,
|
||||
&st.handshake.randoms.client);
|
||||
sess.common.set_message_encrypter(cipher::new_tls13_write(suite, &write_key));
|
||||
sess.common
|
||||
.get_mut_key_schedule()
|
||||
.current_client_traffic_secret = write_key;
|
||||
.current_client_traffic_secret = Some(write_key);
|
||||
|
||||
sess.common.we_now_encrypting();
|
||||
sess.common.start_traffic();
|
||||
|
|
|
@ -4,6 +4,7 @@ use ring::{aead, hkdf::{self, KeyType as _}, hmac, digest};
|
|||
use crate::error::TLSError;
|
||||
use crate::cipher::{Iv, IvLen};
|
||||
use crate::msgs::base::PayloadU8;
|
||||
use crate::KeyLog;
|
||||
|
||||
/// The kinds of secret we can extract from `KeySchedule`.
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
|
@ -41,9 +42,9 @@ impl SecretKind {
|
|||
pub struct KeySchedule {
|
||||
current: hkdf::Prk,
|
||||
algorithm: ring::hkdf::Algorithm,
|
||||
pub current_client_traffic_secret: Vec<u8>,
|
||||
pub current_server_traffic_secret: Vec<u8>,
|
||||
pub current_exporter_secret: Vec<u8>,
|
||||
pub current_client_traffic_secret: Option<hkdf::Prk>,
|
||||
pub current_server_traffic_secret: Option<hkdf::Prk>,
|
||||
pub current_exporter_secret: Option<hkdf::Prk>,
|
||||
}
|
||||
|
||||
impl KeySchedule {
|
||||
|
@ -54,9 +55,9 @@ impl KeySchedule {
|
|||
KeySchedule {
|
||||
current: salt.extract(secret),
|
||||
algorithm,
|
||||
current_server_traffic_secret: Vec::new(),
|
||||
current_client_traffic_secret: Vec::new(),
|
||||
current_exporter_secret: Vec::new(),
|
||||
current_server_traffic_secret: None,
|
||||
current_client_traffic_secret: None,
|
||||
current_exporter_secret: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,10 +90,14 @@ impl KeySchedule {
|
|||
hkdf_expand(&self.current, key_type, kind.to_bytes(), hs_hash)
|
||||
}
|
||||
|
||||
pub fn derive_bytes(&self, kind: SecretKind, hs_hash: &[u8]) -> Vec<u8> {
|
||||
let payload: PayloadU8 =
|
||||
self.derive(PayloadU8Len(self.algorithm.len()), kind, hs_hash);
|
||||
payload.into_inner()
|
||||
pub fn derive_logged_secret(&self, kind: SecretKind, hs_hash: &[u8],
|
||||
key_log: &dyn KeyLog, log_label: &str, client_random: &[u8; 32])
|
||||
-> hkdf::Prk
|
||||
{
|
||||
let secret = self.derive::<PayloadU8, _>(PayloadU8Len(self.algorithm.len()), kind, hs_hash)
|
||||
.into_inner();
|
||||
key_log.log(log_label, client_random, &secret);
|
||||
hkdf::Prk::new_less_safe(self.algorithm, &secret)
|
||||
}
|
||||
|
||||
/// Derive a secret of given `kind` using the hash of the empty string
|
||||
|
@ -109,13 +114,15 @@ impl KeySchedule {
|
|||
}
|
||||
|
||||
/// Return the current traffic secret, of given `kind`.
|
||||
fn current_traffic_secret(&self, kind: SecretKind) -> &[u8] {
|
||||
fn current_traffic_secret(&self, kind: SecretKind) -> &hkdf::Prk {
|
||||
match kind {
|
||||
SecretKind::ServerHandshakeTrafficSecret |
|
||||
SecretKind::ServerApplicationTrafficSecret => &self.current_server_traffic_secret,
|
||||
SecretKind::ServerApplicationTrafficSecret =>
|
||||
&self.current_server_traffic_secret.as_ref().unwrap(),
|
||||
SecretKind::ClientEarlyTrafficSecret |
|
||||
SecretKind::ClientHandshakeTrafficSecret |
|
||||
SecretKind::ClientApplicationTrafficSecret => &self.current_client_traffic_secret,
|
||||
SecretKind::ClientApplicationTrafficSecret =>
|
||||
&self.current_client_traffic_secret.as_ref().unwrap(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
@ -124,8 +131,7 @@ impl KeySchedule {
|
|||
/// traffic secret.
|
||||
pub fn sign_finish(&self, kind: SecretKind, hs_hash: &[u8]) -> Vec<u8> {
|
||||
let base_key = self.current_traffic_secret(kind);
|
||||
let base_key = hkdf::Prk::new_less_safe(self.algorithm, base_key);
|
||||
self.sign_verify_data(&base_key, hs_hash)
|
||||
self.sign_verify_data(base_key, hs_hash)
|
||||
}
|
||||
|
||||
/// Sign the finished message consisting of `hs_hash` using the key material
|
||||
|
@ -140,12 +146,9 @@ impl KeySchedule {
|
|||
|
||||
/// Derive the next application traffic secret of given `kind`, returning
|
||||
/// it.
|
||||
pub fn derive_next(&self, kind: SecretKind) -> Vec<u8> {
|
||||
pub fn derive_next(&self, kind: SecretKind) -> hkdf::Prk {
|
||||
let base_key = self.current_traffic_secret(kind);
|
||||
let base_key = hkdf::Prk::new_less_safe(self.algorithm, &base_key);
|
||||
let payload: PayloadU8 =
|
||||
hkdf_expand(&base_key, PayloadU8Len(self.algorithm.len()), b"traffic upd", &[]);
|
||||
payload.into_inner()
|
||||
hkdf_expand(&base_key, self.algorithm, b"traffic upd", &[])
|
||||
}
|
||||
|
||||
/// Derive the PSK to use given a resumption_master_secret and
|
||||
|
@ -158,17 +161,13 @@ impl KeySchedule {
|
|||
pub fn export_keying_material(&self, out: &mut [u8],
|
||||
label: &[u8],
|
||||
context: Option<&[u8]>) -> Result<(), TLSError> {
|
||||
if self.current_exporter_secret.is_empty() {
|
||||
return Err(TLSError::HandshakeNotComplete);
|
||||
}
|
||||
|
||||
let current_exporter_secret =
|
||||
self.current_exporter_secret.as_ref().ok_or(TLSError::HandshakeNotComplete)?;
|
||||
let digest_alg = self.algorithm.hmac_algorithm().digest_algorithm();
|
||||
|
||||
let h_empty = digest::digest(digest_alg, &[]);
|
||||
let current_exporter_secret =
|
||||
hkdf::Prk::new_less_safe(self.algorithm, &self.current_exporter_secret);
|
||||
let secret: hkdf::Prk =
|
||||
hkdf_expand(¤t_exporter_secret, self.algorithm, label, h_empty.as_ref());
|
||||
hkdf_expand(current_exporter_secret, self.algorithm, label, h_empty.as_ref());
|
||||
|
||||
let h_context = digest::digest(digest_alg, context.unwrap_or(&[]));
|
||||
|
||||
|
@ -232,6 +231,7 @@ pub(crate) fn derive_traffic_iv(secret: &hkdf::Prk) -> Iv {
|
|||
mod test {
|
||||
use super::{KeySchedule, SecretKind, derive_traffic_key, derive_traffic_iv};
|
||||
use ring::{aead, hkdf};
|
||||
use crate::KeyLog;
|
||||
|
||||
#[test]
|
||||
fn test_vectors() {
|
||||
|
@ -361,9 +361,14 @@ mod test {
|
|||
expected_key: &[u8],
|
||||
expected_iv: &[u8],
|
||||
) {
|
||||
let traffic_secret = ks.derive_bytes(kind, &hash);
|
||||
assert_eq!(expected_traffic_secret, &traffic_secret[..]);
|
||||
let traffic_secret = hkdf::Prk::new_less_safe(ks.algorithm(), &traffic_secret);
|
||||
struct Log<'a>(&'a [u8]);
|
||||
impl KeyLog for Log<'_> {
|
||||
fn log(&self, _label: &str, _client_random: &[u8], secret: &[u8]) {
|
||||
assert_eq!(self.0, secret);
|
||||
}
|
||||
}
|
||||
let log = Log(expected_traffic_secret);
|
||||
let traffic_secret = ks.derive_logged_secret(kind, &hash, &log, "", &[0; 32]);
|
||||
|
||||
// Since we can't test key equality, we test the output of sealing with the key instead.
|
||||
let aead_alg = &aead::AES_128_GCM;
|
||||
|
|
31
src/quic.rs
31
src/quic.rs
|
@ -9,17 +9,16 @@ use crate::key_schedule;
|
|||
use crate::session::{SessionCommon, Protocol};
|
||||
|
||||
use std::sync::Arc;
|
||||
use ring::hkdf::{self, KeyType as _};
|
||||
use ring::hkdf;
|
||||
use webpki;
|
||||
use crate::msgs::base::PayloadU8;
|
||||
|
||||
/// Secrets used to encrypt/decrypt traffic
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Secrets {
|
||||
/// Secret used to encrypt packets transmitted by the client
|
||||
pub client: Vec<u8>,
|
||||
pub client: Option<hkdf::Prk>,
|
||||
/// Secret used to encrypt packets transmitted by the server
|
||||
pub server: Vec<u8>,
|
||||
pub server: Option<hkdf::Prk>,
|
||||
}
|
||||
|
||||
/// Generic methods for QUIC sessions
|
||||
|
@ -28,7 +27,7 @@ pub trait QuicExt {
|
|||
fn get_quic_transport_parameters(&self) -> Option<&[u8]>;
|
||||
|
||||
/// Return the early traffic secret, used to encrypt 0-RTT data.
|
||||
fn get_early_secret(&self) -> Option<&[u8]>;
|
||||
fn get_early_secret(&self) -> Option<&hkdf::Prk>;
|
||||
|
||||
/// Consume unencrypted TLS handshake data.
|
||||
///
|
||||
|
@ -55,8 +54,8 @@ impl QuicExt for ClientSession {
|
|||
self.imp.common.quic.params.as_ref().map(|v| v.as_ref())
|
||||
}
|
||||
|
||||
fn get_early_secret(&self) -> Option<&[u8]> {
|
||||
self.imp.common.quic.early_secret.as_ref().map(|x| &x[..])
|
||||
fn get_early_secret(&self) -> Option<&hkdf::Prk> {
|
||||
self.imp.common.quic.early_secret.as_ref()
|
||||
}
|
||||
|
||||
fn read_hs(&mut self, plaintext: &[u8]) -> Result<(), TLSError> {
|
||||
|
@ -75,8 +74,8 @@ impl QuicExt for ServerSession {
|
|||
self.imp.common.quic.params.as_ref().map(|v| v.as_ref())
|
||||
}
|
||||
|
||||
fn get_early_secret(&self) -> Option<&[u8]> {
|
||||
self.imp.common.quic.early_secret.as_ref().map(|x| &x[..])
|
||||
fn get_early_secret(&self) -> Option<&hkdf::Prk> {
|
||||
self.imp.common.quic.early_secret.as_ref()
|
||||
}
|
||||
|
||||
fn read_hs(&mut self, plaintext: &[u8]) -> Result<(), TLSError> {
|
||||
|
@ -126,20 +125,20 @@ fn write_hs(this: &mut SessionCommon, buf: &mut Vec<u8>) -> Option<Secrets> {
|
|||
|
||||
fn update_secrets(this: &SessionCommon, client: &[u8], server: &[u8]) -> Secrets {
|
||||
let hkdf_alg= this.get_suite_assert().hkdf_algorithm;
|
||||
let client: PayloadU8 = key_schedule::hkdf_expand(
|
||||
let client = key_schedule::hkdf_expand(
|
||||
&hkdf::Prk::new_less_safe(hkdf_alg, client),
|
||||
key_schedule::PayloadU8Len(hkdf_alg.len()),
|
||||
hkdf_alg,
|
||||
b"traffic upd",
|
||||
&[]);
|
||||
let server: PayloadU8 = key_schedule::hkdf_expand(
|
||||
let server = key_schedule::hkdf_expand(
|
||||
&hkdf::Prk::new_less_safe(hkdf_alg, server),
|
||||
key_schedule::PayloadU8Len(hkdf_alg.len()),
|
||||
hkdf_alg,
|
||||
b"traffic upd",
|
||||
&[]);
|
||||
|
||||
Secrets {
|
||||
client: client.into_inner(),
|
||||
server: server.into_inner(),
|
||||
client: Some(client),
|
||||
server: Some(server),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -160,10 +160,12 @@ impl CompleteClientHelloHandling {
|
|||
#[cfg(feature = "quic")] {
|
||||
if sess.common.protocol == Protocol::Quic {
|
||||
let client_early_traffic_secret = key_schedule
|
||||
.derive_bytes(SecretKind::ClientEarlyTrafficSecret, &client_hello_hash);
|
||||
sess.config.key_log.log(sess.common.protocol.labels().client_early_traffic_secret,
|
||||
&self.handshake.randoms.client,
|
||||
&client_early_traffic_secret);
|
||||
.derive_logged_secret(
|
||||
SecretKind::ClientEarlyTrafficSecret,
|
||||
&client_hello_hash,
|
||||
&*sess.config.key_log,
|
||||
sess.common.protocol.labels().client_early_traffic_secret,
|
||||
&self.handshake.randoms.client);
|
||||
// If 0-RTT should be rejected, this will be clobbered by ExtensionProcessing
|
||||
// before the application can see.
|
||||
sess.common.quic.early_secret = Some(client_early_traffic_secret);
|
||||
|
@ -175,26 +177,31 @@ impl CompleteClientHelloHandling {
|
|||
key_schedule.input_secret(&kxr.premaster_secret);
|
||||
|
||||
let handshake_hash = self.handshake.transcript.get_current_hash();
|
||||
let write_key = key_schedule.derive_bytes(SecretKind::ServerHandshakeTrafficSecret, &handshake_hash);
|
||||
let read_key = key_schedule.derive_bytes(SecretKind::ClientHandshakeTrafficSecret, &handshake_hash);
|
||||
let write_key = key_schedule.derive_logged_secret(
|
||||
SecretKind::ServerHandshakeTrafficSecret,
|
||||
&handshake_hash,
|
||||
&*sess.config.key_log,
|
||||
sess.common.protocol.labels().server_handshake_traffic_secret,
|
||||
&self.handshake.randoms.client);
|
||||
sess.common.set_message_encrypter(cipher::new_tls13_write(suite, &write_key));
|
||||
|
||||
let read_key = key_schedule.derive_logged_secret(
|
||||
SecretKind::ClientHandshakeTrafficSecret,
|
||||
&handshake_hash,
|
||||
&*sess.config.key_log,
|
||||
sess.common.protocol.labels().client_handshake_traffic_secret,
|
||||
&self.handshake.randoms.client);
|
||||
sess.common.set_message_decrypter(cipher::new_tls13_read(suite, &read_key));
|
||||
sess.config.key_log.log(sess.common.protocol.labels().server_handshake_traffic_secret,
|
||||
&self.handshake.randoms.client,
|
||||
&write_key);
|
||||
sess.config.key_log.log(sess.common.protocol.labels().client_handshake_traffic_secret,
|
||||
&self.handshake.randoms.client,
|
||||
&read_key);
|
||||
|
||||
#[cfg(feature = "quic")] {
|
||||
sess.common.quic.hs_secrets = Some(quic::Secrets {
|
||||
client: read_key.clone(),
|
||||
server: write_key.clone(),
|
||||
client: Some(write_key.clone()),
|
||||
server: Some(read_key.clone()),
|
||||
});
|
||||
}
|
||||
|
||||
key_schedule.current_client_traffic_secret = read_key;
|
||||
key_schedule.current_server_traffic_secret = write_key;
|
||||
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(())
|
||||
|
@ -406,40 +413,37 @@ impl CompleteClientHelloHandling {
|
|||
sess.common.get_mut_key_schedule().input_empty();
|
||||
let write_key = sess.common
|
||||
.get_key_schedule()
|
||||
.derive_bytes(SecretKind::ServerApplicationTrafficSecret,
|
||||
&self.handshake.hash_at_server_fin);
|
||||
.derive_logged_secret(SecretKind::ServerApplicationTrafficSecret,
|
||||
&self.handshake.hash_at_server_fin,
|
||||
&*sess.config.key_log,
|
||||
sess.common.protocol.labels().server_traffic_secret_0,
|
||||
&self.handshake.randoms.client);
|
||||
let suite = sess.common.get_suite_assert();
|
||||
sess.common.set_message_encrypter(cipher::new_tls13_write(suite, &write_key));
|
||||
sess.config.key_log.log(sess.common.protocol.labels().server_traffic_secret_0,
|
||||
&self.handshake.randoms.client,
|
||||
&write_key);
|
||||
|
||||
#[cfg(feature = "quic")] {
|
||||
let read_key = sess.common
|
||||
.get_key_schedule()
|
||||
.derive_bytes(SecretKind::ClientApplicationTrafficSecret,
|
||||
&self.handshake.hash_at_server_fin);
|
||||
let read_key = sess.common.get_key_schedule()
|
||||
.derive(sess.common.get_key_schedule().algorithm(),
|
||||
SecretKind::ClientApplicationTrafficSecret,
|
||||
&self.handshake.hash_at_server_fin);
|
||||
sess.common.quic.traffic_secrets = Some(quic::Secrets {
|
||||
client: read_key,
|
||||
server: write_key.clone(),
|
||||
client: Some(read_key),
|
||||
server: Some(write_key.clone()),
|
||||
});
|
||||
}
|
||||
|
||||
sess.common
|
||||
.get_mut_key_schedule()
|
||||
.current_server_traffic_secret = write_key;
|
||||
|
||||
|
||||
sess.common.get_mut_key_schedule()
|
||||
.current_server_traffic_secret = Some(write_key);
|
||||
let exporter_secret = sess.common
|
||||
.get_key_schedule()
|
||||
.derive_bytes(SecretKind::ExporterMasterSecret,
|
||||
&self.handshake.hash_at_server_fin);
|
||||
sess.config.key_log.log(sess.common.protocol.labels().exporter_secret,
|
||||
&self.handshake.randoms.client,
|
||||
&exporter_secret);
|
||||
.derive_logged_secret(SecretKind::ExporterMasterSecret,
|
||||
&self.handshake.hash_at_server_fin,
|
||||
&*sess.config.key_log,
|
||||
sess.common.protocol.labels().exporter_secret,
|
||||
&self.handshake.randoms.client);
|
||||
sess.common
|
||||
.get_mut_key_schedule()
|
||||
.current_exporter_secret = exporter_secret;
|
||||
.current_exporter_secret = Some(exporter_secret);
|
||||
}
|
||||
|
||||
fn attempt_tls13_ticket_decryption(&mut self,
|
||||
|
@ -842,18 +846,18 @@ impl hs::State for ExpectFinished {
|
|||
// Server traffic is already done.
|
||||
let read_key = sess.common
|
||||
.get_key_schedule()
|
||||
.derive_bytes(SecretKind::ClientApplicationTrafficSecret,
|
||||
&self.handshake.hash_at_server_fin);
|
||||
sess.config.key_log.log(sess.common.protocol.labels().client_traffic_secret_0,
|
||||
&self.handshake.randoms.client,
|
||||
&read_key);
|
||||
.derive_logged_secret(SecretKind::ClientApplicationTrafficSecret,
|
||||
&self.handshake.hash_at_server_fin,
|
||||
&*sess.config.key_log,
|
||||
sess.common.protocol.labels().client_traffic_secret_0,
|
||||
&self.handshake.randoms.client);
|
||||
|
||||
let suite = sess.common.get_suite_assert();
|
||||
hs::check_aligned_handshake(sess)?;
|
||||
sess.common.set_message_decrypter(cipher::new_tls13_read(suite, &read_key));
|
||||
sess.common
|
||||
.get_mut_key_schedule()
|
||||
.current_client_traffic_secret = read_key;
|
||||
.current_client_traffic_secret = Some(read_key);
|
||||
|
||||
if self.send_ticket {
|
||||
if sess.config.ticketer.enabled() {
|
||||
|
|
|
@ -628,9 +628,9 @@ impl SessionCommon {
|
|||
self.set_message_encrypter(cipher::new_tls13_write(scs, &write_key));
|
||||
|
||||
if self.is_client {
|
||||
self.get_mut_key_schedule().current_client_traffic_secret = write_key;
|
||||
self.get_mut_key_schedule().current_client_traffic_secret = Some(write_key);
|
||||
} else {
|
||||
self.get_mut_key_schedule().current_server_traffic_secret = write_key;
|
||||
self.get_mut_key_schedule().current_server_traffic_secret = Some(write_key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -898,9 +898,9 @@ impl SessionCommon {
|
|||
self.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 = new_read_key;
|
||||
self.get_mut_key_schedule().current_server_traffic_secret = Some(new_read_key);
|
||||
} else {
|
||||
self.get_mut_key_schedule().current_client_traffic_secret = new_read_key;
|
||||
self.get_mut_key_schedule().current_client_traffic_secret = Some(new_read_key);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -941,7 +941,7 @@ pub(crate) struct Quic {
|
|||
pub params: Option<Vec<u8>>,
|
||||
pub alert: Option<AlertDescription>,
|
||||
pub hs_queue: VecDeque<(bool, Vec<u8>)>,
|
||||
pub early_secret: Option<Vec<u8>>,
|
||||
pub early_secret: Option<ring::hkdf::Prk>,
|
||||
pub hs_secrets: Option<quic::Secrets>,
|
||||
pub traffic_secrets: Option<quic::Secrets>,
|
||||
}
|
||||
|
|
|
@ -1952,6 +1952,6 @@ fn assert_lt(left: usize, right: usize) {
|
|||
#[test]
|
||||
fn session_types_are_not_huge() {
|
||||
// Arbitrary sizes
|
||||
assert_lt(mem::size_of::<ServerSession>(), 1536);
|
||||
assert_lt(mem::size_of::<ClientSession>(), 1536);
|
||||
assert_lt(mem::size_of::<ServerSession>(), 2300);
|
||||
assert_lt(mem::size_of::<ClientSession>(), 2300);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue