Compare commits

...

6 Commits

Author SHA1 Message Date
occheung 4b644aafe9 session: calculate ap key 2020-11-27 17:00:15 +08:00
occheung 73f95555eb session: code reuse handshake secret 2020-11-27 15:54:41 +08:00
occheung e55b2e266b hash: fix, exclude content byte 2020-11-27 13:55:27 +08:00
occheung ccc257aeb9 server certificate: handled 2020-11-27 13:28:27 +08:00
occheung 81d52e9ec4 server ee: init 2020-11-27 11:53:45 +08:00
occheung 3ba03819d4 server hello: fix handshake length 2020-11-27 09:43:51 +08:00
3 changed files with 1018 additions and 362 deletions

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,7 @@ use crate::parse::{
get_content_type_inner_plaintext get_content_type_inner_plaintext
}; };
use crate::buffer::TlsBuffer; use crate::buffer::TlsBuffer;
use crate::session::{Session, TlsRole, DiffieHellmanPublicKey}; use crate::session::{Session, TlsRole, DiffieHellmanPublicKey, DiffieHellmanPrivateKey};
#[derive(Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
@ -365,7 +365,10 @@ impl<'s> TlsSocket<'s> {
{ {
let session = self.session.borrow(); let session = self.session.borrow();
let (sig_alg, signature) = session let (sig_alg, signature) = session
.get_client_certificate_verify_signature(&mut self.rng); .get_certificate_verify_signature(
&mut self.rng,
TlsRole::Client
);
let signature_length: u16 = u16::try_from(signature.len()).unwrap(); let signature_length: u16 = u16::try_from(signature.len()).unwrap();
NetworkEndian::write_u24( NetworkEndian::write_u24(
@ -437,23 +440,44 @@ impl<'s> TlsSocket<'s> {
// - CertificateVerify // - CertificateVerify
// - Finished // - Finished
TlsState::NEGOTIATED => { TlsState::NEGOTIATED => {
let mut session = self.session.borrow_mut();
let mut random: [u8; 32] = [0; 32]; let mut random: [u8; 32] = [0; 32];
self.rng.fill_bytes(&mut random); self.rng.fill_bytes(&mut random);
// Relay session id let (session_id, cipher_suite, server_ecdhe_public_key) = {
let session_id = session.get_session_id(); let mut session = self.session.borrow();
let cipher_suite = session.get_cipher_suite(); (
let ecdhe_key = session.get_server_ecdhe_public_key(); session.get_session_id(),
session.get_cipher_suite(),
session.get_server_ecdhe_public_key()
)
};
let ecdhe_private_key = match server_ecdhe_public_key {
DiffieHellmanPublicKey::SECP256R1 { .. } => {
DiffieHellmanPrivateKey::SECP256R1 {
ephemeral_secret: {
p256::ecdh::EphemeralSecret::random(&mut self.rng)
}
}
},
DiffieHellmanPublicKey::X25519 { .. } => {
DiffieHellmanPrivateKey::X25519 {
ephemeral_secret: {
x25519_dalek::EphemeralSecret::new(&mut self.rng)
}
}
}
};
let ecdhe_public_key = ecdhe_private_key.to_public_key();
// Construct and send SH
let repr = TlsRepr::new().server_hello( let repr = TlsRepr::new().server_hello(
&random, &random,
session_id, &session_id,
cipher_suite, cipher_suite,
ecdhe_key ecdhe_public_key
); );
{ {
let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle); let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle);
let mut session = self.session.borrow_mut();
tcp_socket.send( tcp_socket.send(
|data| { |data| {
// Enqueue the TLS representation // Enqueue the TLS representation
@ -463,14 +487,173 @@ impl<'s> TlsSocket<'s> {
} }
let slice: &[u8] = buffer.into(); let slice: &[u8] = buffer.into();
// Update session // Update session after sending only SH
todo!(); session.server_update_for_server_hello(
ecdhe_private_key,
&slice[5..]
);
// Send the data // Send the data
(slice.len(), ()) (slice.len(), ())
} }
)?; )?;
} }
// Construct and send minimalistic EE
let inner_plaintext: [u8; 7] = [
0x08, // EE type
0x00, 0x00, 0x02, // Length: 2
0x00, 0x00, // Length of extensions: 0
22 // Content type of InnerPlainText
];
self.send_application_slice(sockets, &mut inner_plaintext.clone())?;
let inner_plaintext_length = inner_plaintext.len();
{
let mut session = self.session.borrow_mut();
session.server_update_for_encrypted_extension(
&inner_plaintext[..(inner_plaintext_length-1)]
);
}
// TODO: Option to allow a certificate request
// Construct and send server certificate handshake content
let mut inner_plaintext = {
let mut inner_plaintext: Vec<u8> = Vec::new();
let session = self.session.borrow();
let certificates = session.get_private_certificate_slices().clone();
// Handshake level, client certificate byte followed by length (u24)
// Certificate struct:
// request_context = X509: 0 (u8),
// certificate_list to be determined (u24)
let mut certificates_total_length: u32 = 0;
// Append place holder bytes (8 of them) in the buffer vector
// Simpily copy the the headers back into the vector
// when all certificates are appended into the vector
inner_plaintext.extend_from_slice(&[11, 0, 0, 0, 0, 0, 0, 0]);
// Certificate Entry struct(s)
if let Some(certificate_list) = certificates {
for cert in certificate_list.iter() {
// cert_data length, to be determined (u24)
let mut cert_data_length: [u8; 3] = [0, 0, 0];
// extensions: no extension needed
let extension: [u8; 2] = [0, 0];
let certificate_length: u32 = u32::try_from(cert.len()).unwrap();
NetworkEndian::write_u24(
&mut cert_data_length,
certificate_length
);
// Update length in Certificate struct
certificates_total_length +=
// cert_data (len & data) AND extension (len & data)
3 + certificate_length + 2 + 0;
inner_plaintext.extend_from_slice(&cert_data_length);
inner_plaintext.extend_from_slice(cert);
inner_plaintext.extend_from_slice(&extension);
}
}
// Write total certificate length into Certificate struct
NetworkEndian::write_u24(
&mut inner_plaintext[5..8],
certificates_total_length
);
// Write the length of the entire handshake
NetworkEndian::write_u24(
&mut inner_plaintext[1..4],
// 4 bytes for the Certificate struct header
certificates_total_length + 4
);
// Inner plaintext: record type
inner_plaintext.push(22);
inner_plaintext
};
self.send_application_slice(sockets, &mut inner_plaintext.clone())?;
let inner_plaintext_length = inner_plaintext.len();
// Update session
{
self.session.borrow_mut()
.server_update_for_sent_certificate(&inner_plaintext[..(inner_plaintext_length-1)]);
}
// Construct and send certificate verify
let mut inner_plaintext = {
let mut inner_plaintext = Vec::new();
inner_plaintext.extend_from_slice(&[
15,
0, 0, 0,
0, 0,
0, 0
]);
let session = self.session.borrow();
let (sig_alg, signature) = session.get_certificate_verify_signature(
&mut self.rng,
TlsRole::Server
);
let signature_length: u16 = u16::try_from(signature.len()).unwrap();
NetworkEndian::write_u24(
&mut inner_plaintext[1..4],
(signature_length + 4).into()
);
NetworkEndian::write_u16(
&mut inner_plaintext[4..6],
sig_alg.try_into().unwrap()
);
NetworkEndian::write_u16(
&mut inner_plaintext[6..8],
signature_length
);
inner_plaintext.extend_from_slice(&signature);
inner_plaintext.push(22); // Content type byte
inner_plaintext
};
self.send_application_slice(
sockets,
&mut inner_plaintext.clone()
)?;
let inner_plaintext_length = inner_plaintext.len();
{
self.session.borrow_mut()
.server_update_for_sent_certificate_verify(
&inner_plaintext[..(inner_plaintext_length-1)]
);
}
// Construct and send server finished
let inner_plaintext: HeaplessVec<u8, U64> = {
let verify_data = self.session.borrow()
.get_server_finished_verify_data();
let mut handshake_header: [u8; 4] = [20, 0, 0, 0];
NetworkEndian::write_u24(
&mut handshake_header[1..4],
u32::try_from(verify_data.len()).unwrap()
);
let mut buffer = HeaplessVec::from_slice(&handshake_header).unwrap();
buffer.extend_from_slice(&verify_data).unwrap();
// Inner plaintext: record type
buffer.push(22).unwrap();
buffer
};
self.send_application_slice(sockets, &mut inner_plaintext.clone())?;
let inner_plaintext_length = inner_plaintext.len();
// {
// self.session.borrow_mut()
// .server_update_for_server_finished(&inner_plaintext[..(inner_plaintext_length-1)]);
// }
} }
// Other states regarding server role // Other states regarding server role
@ -996,8 +1179,6 @@ impl<'s> TlsSocket<'s> {
let mut version_check = false; let mut version_check = false;
let mut offered_p256 = false; let mut offered_p256 = false;
let mut offered_x25519 = false; let mut offered_x25519 = false;
// let mut p256_public_key: Option<p256::EncodedPoint> = None;
// let mut x25519_public_key: Option<x25519_dalek::PublicKey> = None;
let mut ecdhe_public_key: Option<DiffieHellmanPublicKey> = None; let mut ecdhe_public_key: Option<DiffieHellmanPublicKey> = None;
let mut signature_algorithm: Option<SignatureScheme> = None; let mut signature_algorithm: Option<SignatureScheme> = None;
@ -1225,13 +1406,12 @@ impl<'s> TlsSocket<'s> {
if !tcp_socket.can_send() { if !tcp_socket.can_send() {
return Err(Error::Illegal); return Err(Error::Illegal);
} }
// Borrow session in advance // Borrow session in advance
let mut client_session = self.session.borrow_mut(); let mut session = self.session.borrow_mut();
// Pre-compute TLS record layer as associated_data // Pre-compute TLS record layer as associated_data
let mut associated_data: [u8; 5] = [0x17, 0x03, 0x03, 0x00, 0x00]; let mut associated_data: [u8; 5] = [0x17, 0x03, 0x03, 0x00, 0x00];
let auth_tag_length: u16 = match client_session.get_cipher_suite_type() { let auth_tag_length: u16 = match session.get_cipher_suite_type() {
Some(CipherSuite::TLS_AES_128_GCM_SHA256) | Some(CipherSuite::TLS_AES_128_GCM_SHA256) |
Some(CipherSuite::TLS_AES_256_GCM_SHA384) | Some(CipherSuite::TLS_AES_256_GCM_SHA384) |
Some(CipherSuite::TLS_AES_128_CCM_SHA256) | Some(CipherSuite::TLS_AES_128_CCM_SHA256) |
@ -1246,7 +1426,7 @@ impl<'s> TlsSocket<'s> {
auth_tag_length + u16::try_from(slice.len()).unwrap() auth_tag_length + u16::try_from(slice.len()).unwrap()
); );
let auth_tag = client_session.encrypt_in_place_detached( let auth_tag = session.encrypt_in_place_detached(
&associated_data, &associated_data,
slice slice
).map_err(|_| Error::Illegal)?; ).map_err(|_| Error::Illegal)?;
@ -1255,7 +1435,7 @@ impl<'s> TlsSocket<'s> {
tcp_socket.send_slice(&slice)?; tcp_socket.send_slice(&slice)?;
tcp_socket.send_slice(&auth_tag)?; tcp_socket.send_slice(&auth_tag)?;
client_session.increment_client_sequence_number(); session.increment_local_sequence_number();
Ok(()) Ok(())
} }

View File

@ -105,6 +105,7 @@ impl<'a> TlsRepr<'a> {
) )
} }
); );
repr.length = repr.handshake_data.get_length().try_into().unwrap();
repr repr
}; };
self.length = handshake_repr.get_length(); self.length = handshake_repr.get_length();