Skip to content

Commit

Permalink
HRR changes in draft 19
Browse files Browse the repository at this point in the history
- This now has the selected ciphersuite in.
- The transcript hashing also now more complex.
  • Loading branch information
ctz committed Mar 30, 2017
1 parent bc262d3 commit 8a8fc4b
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 1 deletion.
15 changes: 14 additions & 1 deletion src/client_hs.rs
Expand Up @@ -615,7 +615,6 @@ pub static EXPECT_SERVER_HELLO: State = State {
fn handle_hello_retry_request(sess: &mut ClientSessionImpl,
m: Message) -> StateResult {
let hrr = extract_handshake!(m, HandshakePayload::HelloRetryRequest).unwrap();
sess.handshake_data.transcript.add_message(&m);
debug!("Got HRR {:?}", hrr);

let has_cookie = hrr.get_cookie().is_some();
Expand Down Expand Up @@ -665,6 +664,20 @@ fn handle_hello_retry_request(sess: &mut ClientSessionImpl,
}
}

// Or asks us to use a ciphersuite we didn't offer.
let maybe_cs = sess.find_cipher_suite(hrr.cipher_suite);
let cs = match maybe_cs {
Some(cs) => cs,
None => {
return Err(illegal_param(sess, "server requested unsupported cs in hrr"));
}
};

// This is the draft19 change where the transcript became a tree
sess.handshake_data.transcript.start_hash(cs.get_hash());
sess.handshake_data.transcript.rollup_for_hrr();
sess.handshake_data.transcript.add_message(&m);

Ok(emit_client_hello_for_retry(sess, Some(hrr)))
}

Expand Down
12 changes: 12 additions & 0 deletions src/hash_hs.rs
Expand Up @@ -2,6 +2,7 @@ use ring::digest;
use std::mem;
use msgs::codec::Codec;
use msgs::message::{Message, MessagePayload};
use msgs::handshake::HandshakeMessagePayload;

/// This deals with keeping a running hash of the handshake
/// payloads. This is computed by buffering initially. Once
Expand Down Expand Up @@ -128,6 +129,17 @@ impl HandshakeHash {
ret
}

/// Take the current hash value, and encapsulate it in a
/// 'handshake_hash' handshake message. Start this hash
/// again, with that message at the front.
pub fn rollup_for_hrr(&mut self) {
let old_hash = self.ctx.take().unwrap().finish();
let old_handshake_hash_msg = HandshakeMessagePayload::build_handshake_hash(old_hash.as_ref());

self.ctx = Some(digest::Context::new(self.alg.unwrap()));
self.update_raw(&old_handshake_hash_msg.get_encoding());
}

/// Get the current hash value.
pub fn get_current_hash(&self) -> Vec<u8> {
let hash = self.ctx.as_ref().unwrap().clone().finish();
Expand Down
16 changes: 16 additions & 0 deletions src/msgs/handshake.rs
Expand Up @@ -996,18 +996,21 @@ impl Codec for HelloRetryExtension {
#[derive(Debug)]
pub struct HelloRetryRequest {
pub server_version: ProtocolVersion,
pub cipher_suite: CipherSuite,
pub extensions: Vec<HelloRetryExtension>,
}

impl Codec for HelloRetryRequest {
fn encode(&self, bytes: &mut Vec<u8>) {
self.server_version.encode(bytes);
self.cipher_suite.encode(bytes);
codec::encode_vec_u16(bytes, &self.extensions);
}

fn read(r: &mut Reader) -> Option<HelloRetryRequest> {
Some(HelloRetryRequest {
server_version: try_ret!(ProtocolVersion::read(r)),
cipher_suite: try_ret!(CipherSuite::read(r)),
extensions: try_ret!(codec::read_vec_u16::<HelloRetryExtension>(r)),
})
}
Expand Down Expand Up @@ -1837,6 +1840,7 @@ pub enum HandshakePayload {
EncryptedExtensions(EncryptedExtensions),
KeyUpdate(KeyUpdateRequest),
Finished(Payload),
MessageHash(Payload),
Unknown(Payload),
}

Expand All @@ -1860,6 +1864,7 @@ impl HandshakePayload {
HandshakePayload::EncryptedExtensions(ref x) => x.encode(bytes),
HandshakePayload::KeyUpdate(ref x) => x.encode(bytes),
HandshakePayload::Finished(ref x) => x.encode(bytes),
HandshakePayload::MessageHash(ref x) => x.encode(bytes),
HandshakePayload::Unknown(ref x) => x.encode(bytes),
}
}
Expand Down Expand Up @@ -1959,6 +1964,10 @@ impl HandshakeMessagePayload {
HandshakeType::Finished => {
HandshakePayload::Finished(try_ret!(Payload::read(&mut sub)))
}
HandshakeType::MessageHash => {
// does not appear on the wire
return None;
}
_ => HandshakePayload::Unknown(try_ret!(Payload::read(&mut sub))),
};

Expand Down Expand Up @@ -1997,4 +2006,11 @@ impl HandshakeMessagePayload {
ret.truncate(ret_len);
ret
}

pub fn build_handshake_hash(hash: &[u8]) -> HandshakeMessagePayload {
HandshakeMessagePayload {
typ: HandshakeType::MessageHash,
payload: HandshakePayload::MessageHash(Payload::new(hash.to_vec()))
}
}
}
2 changes: 2 additions & 0 deletions src/server_hs.rs
Expand Up @@ -390,6 +390,7 @@ fn emit_server_hello_tls13(sess: &mut ServerSessionImpl,
fn emit_hello_retry_request(sess: &mut ServerSessionImpl, group: NamedGroup) {
let mut req = HelloRetryRequest {
server_version: ProtocolVersion::Unknown(TLS13_DRAFT),
cipher_suite: sess.common.get_suite().suite,
extensions: Vec::new(),
};

Expand All @@ -405,6 +406,7 @@ fn emit_hello_retry_request(sess: &mut ServerSessionImpl, group: NamedGroup) {
};

debug!("Requesting retry {:?}", m);
sess.handshake_data.transcript.rollup_for_hrr();
sess.handshake_data.transcript.add_message(&m);
sess.common.send_msg(m, false);
}
Expand Down

0 comments on commit 8a8fc4b

Please sign in to comment.