Split up emit_client_hello_for_retry

This commit is contained in:
Joseph Birr-Pixton 2019-05-08 19:56:22 +01:00 committed by ctz
parent aac0bbafcc
commit e6e04f421a
2 changed files with 49 additions and 42 deletions

View File

@ -5,7 +5,6 @@ use crate::msgs::base::Payload;
use crate::msgs::handshake::{HandshakePayload, HandshakeMessagePayload, ClientHelloPayload};
use crate::msgs::handshake::{SessionID, Random, ServerHelloPayload};
use crate::msgs::handshake::{ClientExtension, HasServerExtensions};
use crate::msgs::handshake::KeyShareEntry;
use crate::msgs::handshake::{ECPointFormatList, SupportedPointFormats};
use crate::msgs::handshake::{ProtocolNameList, ConvertProtocolNameList};
use crate::msgs::handshake::{PresharedKeyIdentity, PresharedKeyOffer, HelloRetryRequest};
@ -117,14 +116,6 @@ fn find_session(sess: &mut ClientSessionImpl, dns_name: webpki::DNSNameRef)
}
}
fn find_kx_hint(sess: &mut ClientSessionImpl, dns_name: webpki::DNSNameRef) -> Option<NamedGroup> {
let key = persist::ClientSessionKey::hint_for_dns_name(dns_name);
let key_buf = key.get_encoding();
let maybe_value = sess.config.session_persistence.get(&key_buf);
maybe_value.and_then(|enc| NamedGroup::read_bytes(&enc))
}
fn save_kx_hint(sess: &mut ClientSessionImpl, dns_name: webpki::DNSNameRef, group: NamedGroup) {
let key = persist::ClientSessionKey::hint_for_dns_name(dns_name);
@ -279,37 +270,6 @@ fn emit_client_hello_for_retry(sess: &mut ClientSessionImpl,
supported_versions.push(ProtocolVersion::TLSv1_2);
}
let mut key_shares = vec![];
if support_tls13 {
// Choose our groups:
// - if we've been asked via HelloRetryRequest for a specific
// one, do that.
// - if not, we might have a hint of what the server supports
// - if not, send just X25519.
//
let groups = retryreq.and_then(HelloRetryRequest::get_requested_key_share_group)
.or_else(|| find_kx_hint(sess, handshake.dns_name.as_ref()))
.or_else(|| Some(NamedGroup::X25519))
.map(|grp| vec![ grp ])
.unwrap();
for group in groups {
// in reply to HelloRetryRequest, we must not alter any existing key
// shares
if let Some(already_offered_share) = hello.find_key_share(group) {
key_shares.push(KeyShareEntry::new(group, already_offered_share.pubkey.as_ref()));
hello.offered_key_shares.push(already_offered_share);
continue;
}
if let Some(key_share) = suites::KeyExchange::start_ecdhe(group) {
key_shares.push(KeyShareEntry::new(group, key_share.pubkey.as_ref()));
hello.offered_key_shares.push(key_share);
}
}
}
let mut exts = Vec::new();
if !supported_versions.is_empty() {
exts.push(ClientExtension::SupportedVersions(supported_versions));
@ -328,7 +288,7 @@ fn emit_client_hello_for_retry(sess: &mut ClientSessionImpl,
}
if support_tls13 {
exts.push(ClientExtension::KeyShare(key_shares));
tls13::choose_kx_groups(sess, &mut exts, &mut hello, &mut handshake, retryreq);
}
if let Some(cookie) = retryreq.and_then(HelloRetryRequest::get_cookie) {

View File

@ -1,9 +1,10 @@
use crate::msgs::enums::{ContentType, HandshakeType, ExtensionType, SignatureScheme};
use crate::msgs::enums::{ProtocolVersion, AlertDescription};
use crate::msgs::enums::{ProtocolVersion, AlertDescription, NamedGroup};
use crate::msgs::message::{Message, MessagePayload};
use crate::msgs::base::{Payload, PayloadU8};
use crate::msgs::handshake::{HandshakePayload, HandshakeMessagePayload};
use crate::msgs::handshake::{SessionID, ServerHelloPayload, HasServerExtensions};
use crate::msgs::handshake::{ClientExtension, HelloRetryRequest, KeyShareEntry};
use crate::msgs::handshake::EncryptedExtensions;
use crate::msgs::handshake::{CertificatePayloadTLS13, CertificateEntry};
use crate::msgs::handshake::DigitallySignedStruct;
@ -14,6 +15,7 @@ use crate::key_schedule::SecretKind;
use crate::cipher;
use crate::verify;
use crate::sign;
use crate::suites;
use crate::ticketer;
#[cfg(feature = "logging")]
use crate::log::{debug, warn};
@ -62,6 +64,51 @@ pub fn validate_server_hello(sess: &mut ClientSessionImpl,
Ok(())
}
fn find_kx_hint(sess: &mut ClientSessionImpl, dns_name: webpki::DNSNameRef) -> Option<NamedGroup> {
let key = persist::ClientSessionKey::hint_for_dns_name(dns_name);
let key_buf = key.get_encoding();
let maybe_value = sess.config.session_persistence.get(&key_buf);
maybe_value.and_then(|enc| NamedGroup::read_bytes(&enc))
}
pub fn choose_kx_groups(sess: &mut ClientSessionImpl,
exts: &mut Vec<ClientExtension>,
hello: &mut ClientHelloDetails,
handshake: &mut HandshakeDetails,
retryreq: Option<&HelloRetryRequest>) {
// Choose our groups:
// - if we've been asked via HelloRetryRequest for a specific
// one, do that.
// - if not, we might have a hint of what the server supports
// - if not, send just X25519.
//
let groups = retryreq.and_then(HelloRetryRequest::get_requested_key_share_group)
.or_else(|| find_kx_hint(sess, handshake.dns_name.as_ref()))
.or_else(|| Some(NamedGroup::X25519))
.map(|grp| vec![ grp ])
.unwrap();
let mut key_shares = vec![];
for group in groups {
// in reply to HelloRetryRequest, we must not alter any existing key
// shares
if let Some(already_offered_share) = hello.find_key_share(group) {
key_shares.push(KeyShareEntry::new(group, already_offered_share.pubkey.as_ref()));
hello.offered_key_shares.push(already_offered_share);
continue;
}
if let Some(key_share) = suites::KeyExchange::start_ecdhe(group) {
key_shares.push(KeyShareEntry::new(group, key_share.pubkey.as_ref()));
hello.offered_key_shares.push(key_share);
}
}
exts.push(ClientExtension::KeyShare(key_shares));
}
fn validate_encrypted_extensions(sess: &mut ClientSessionImpl,
hello: &ClientHelloDetails,
exts: &EncryptedExtensions) -> Result<(), TLSError> {