Compare commits
6 Commits
ab5719ed44
...
4b644aafe9
Author | SHA1 | Date |
---|---|---|
occheung | 4b644aafe9 | |
occheung | 73f95555eb | |
occheung | e55b2e266b | |
occheung | ccc257aeb9 | |
occheung | 81d52e9ec4 | |
occheung | 3ba03819d4 |
1161
src/session.rs
1161
src/session.rs
File diff suppressed because it is too large
Load Diff
218
src/tls.rs
218
src/tls.rs
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue