server ee: init
This commit is contained in:
parent
3ba03819d4
commit
81d52e9ec4
402
src/session.rs
402
src/session.rs
@ -1203,7 +1203,362 @@ impl<'a> Session<'a> {
|
|||||||
server_ecdhe_secret: DiffieHellmanPrivateKey,
|
server_ecdhe_secret: DiffieHellmanPrivateKey,
|
||||||
server_hello_slice: &[u8]
|
server_hello_slice: &[u8]
|
||||||
) {
|
) {
|
||||||
todo!()
|
// Hash update
|
||||||
|
self.hash.update(server_hello_slice);
|
||||||
|
|
||||||
|
let mut shared_secret_bytes: [u8; 32] = [0; 32];
|
||||||
|
match (self.ecdhe_public.unwrap(), server_ecdhe_secret) {
|
||||||
|
(
|
||||||
|
DiffieHellmanPublicKey::SECP256R1 { encoded_point },
|
||||||
|
DiffieHellmanPrivateKey::SECP256R1 { ephemeral_secret }
|
||||||
|
) => {
|
||||||
|
shared_secret_bytes.clone_from_slice(
|
||||||
|
ephemeral_secret.diffie_hellman(
|
||||||
|
&encoded_point
|
||||||
|
).unwrap().as_bytes()
|
||||||
|
)
|
||||||
|
},
|
||||||
|
(
|
||||||
|
DiffieHellmanPublicKey::X25519 { public_key },
|
||||||
|
DiffieHellmanPrivateKey::X25519 { ephemeral_secret }
|
||||||
|
) => {
|
||||||
|
shared_secret_bytes.clone_from_slice(
|
||||||
|
ephemeral_secret.diffie_hellman(
|
||||||
|
&public_key
|
||||||
|
).as_bytes()
|
||||||
|
)
|
||||||
|
},
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
|
let server_selected_cipher = self.server_selected_cipher.take().unwrap();
|
||||||
|
|
||||||
|
// Find handshake keys and IV
|
||||||
|
match server_selected_cipher {
|
||||||
|
CipherSuite::TLS_AES_128_CCM_SHA256 |
|
||||||
|
CipherSuite::TLS_CHACHA20_POLY1305_SHA256 |
|
||||||
|
CipherSuite::TLS_AES_128_GCM_SHA256 => {
|
||||||
|
// Find early secret wrapped in HKDF
|
||||||
|
let empty_psk: GenericArray<u8, <Sha256 as FixedOutput>::OutputSize> = Default::default();
|
||||||
|
let early_secret_hkdf = Hkdf::<Sha256>::new(None, &empty_psk);
|
||||||
|
|
||||||
|
// Find handshake secret
|
||||||
|
let empty_hash = Sha256::new().chain("");
|
||||||
|
let derived_secret = derive_secret(
|
||||||
|
&early_secret_hkdf,
|
||||||
|
"derived",
|
||||||
|
empty_hash
|
||||||
|
);
|
||||||
|
|
||||||
|
let (handshake_secret, handshake_secret_hkdf) =
|
||||||
|
Hkdf::<Sha256>::extract(
|
||||||
|
Some(&derived_secret),
|
||||||
|
&shared_secret_bytes
|
||||||
|
);
|
||||||
|
|
||||||
|
// Store the handshake secret
|
||||||
|
self.latest_secret.replace(
|
||||||
|
Vec::from_slice(&handshake_secret)
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
let client_handshake_traffic_secret = derive_secret(
|
||||||
|
&handshake_secret_hkdf,
|
||||||
|
"c hs traffic",
|
||||||
|
self.hash.get_sha256_clone().unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
let server_handshake_traffic_secret = derive_secret(
|
||||||
|
&handshake_secret_hkdf,
|
||||||
|
"s hs traffic",
|
||||||
|
self.hash.get_sha256_clone().unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Store client_handshake_traffic_secret and
|
||||||
|
// server_handshake_traffic_secret
|
||||||
|
// Initial values of both secrets don't matter
|
||||||
|
self.client_handshake_traffic_secret.replace(
|
||||||
|
Vec::from_slice(&client_handshake_traffic_secret).unwrap()
|
||||||
|
);
|
||||||
|
self.server_handshake_traffic_secret.replace(
|
||||||
|
Vec::from_slice(&server_handshake_traffic_secret).unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
let client_handshake_traffic_secret_hkdf = Hkdf::<Sha256>::from_prk(&client_handshake_traffic_secret).unwrap();
|
||||||
|
let server_handshake_traffic_secret_hkdf = Hkdf::<Sha256>::from_prk(&server_handshake_traffic_secret).unwrap();
|
||||||
|
|
||||||
|
// Prepare holder for key and IV
|
||||||
|
let client_handshake_key: Vec<u8, U64> = {
|
||||||
|
let mut client_handshake_key_holder: Vec<u8, U64> = match server_selected_cipher {
|
||||||
|
// 16 bytes key size
|
||||||
|
CipherSuite::TLS_AES_128_GCM_SHA256 |
|
||||||
|
CipherSuite::TLS_AES_128_CCM_SHA256 => {
|
||||||
|
Vec::from_slice(&[0; 16]).unwrap()
|
||||||
|
},
|
||||||
|
// 32 bytes key size
|
||||||
|
CipherSuite::TLS_CHACHA20_POLY1305_SHA256 => {
|
||||||
|
Vec::from_slice(&[0; 32]).unwrap()
|
||||||
|
},
|
||||||
|
// Not using Sha256 (AES_GCM_256) / not supported (CCM_8)
|
||||||
|
_ => unreachable!()
|
||||||
|
};
|
||||||
|
hkdf_expand_label(
|
||||||
|
&client_handshake_traffic_secret_hkdf,
|
||||||
|
"key",
|
||||||
|
"",
|
||||||
|
&mut client_handshake_key_holder
|
||||||
|
);
|
||||||
|
client_handshake_key_holder
|
||||||
|
};
|
||||||
|
|
||||||
|
let client_handshake_iv: Vec<u8, U12> = {
|
||||||
|
let mut client_handshake_iv_holder = Vec::from_slice(&[0; 12]).unwrap();
|
||||||
|
hkdf_expand_label(
|
||||||
|
&client_handshake_traffic_secret_hkdf,
|
||||||
|
"iv",
|
||||||
|
"",
|
||||||
|
&mut client_handshake_iv_holder
|
||||||
|
);
|
||||||
|
client_handshake_iv_holder
|
||||||
|
};
|
||||||
|
|
||||||
|
let server_handshake_key: Vec<u8, U64> = {
|
||||||
|
let mut server_handshake_key_holder: Vec<u8, U64> = match server_selected_cipher {
|
||||||
|
// 16 bytes key size
|
||||||
|
CipherSuite::TLS_AES_128_GCM_SHA256 |
|
||||||
|
CipherSuite::TLS_AES_128_CCM_SHA256 => {
|
||||||
|
Vec::from_slice(&[0; 16]).unwrap()
|
||||||
|
},
|
||||||
|
// 32 bytes key size
|
||||||
|
CipherSuite::TLS_CHACHA20_POLY1305_SHA256 => {
|
||||||
|
Vec::from_slice(&[0; 32]).unwrap()
|
||||||
|
},
|
||||||
|
// Not using Sha256 (AES_GCM_256) / not supported (CCM_8)
|
||||||
|
_ => unreachable!()
|
||||||
|
};
|
||||||
|
hkdf_expand_label(
|
||||||
|
&server_handshake_traffic_secret_hkdf,
|
||||||
|
"key",
|
||||||
|
"",
|
||||||
|
&mut server_handshake_key_holder
|
||||||
|
);
|
||||||
|
server_handshake_key_holder
|
||||||
|
};
|
||||||
|
|
||||||
|
let server_handshake_iv: Vec<u8, U12> = {
|
||||||
|
let mut server_handshake_iv_holder = Vec::from_slice(&[0; 12]).unwrap();
|
||||||
|
hkdf_expand_label(
|
||||||
|
&server_handshake_traffic_secret_hkdf,
|
||||||
|
"iv",
|
||||||
|
"",
|
||||||
|
&mut server_handshake_iv_holder
|
||||||
|
);
|
||||||
|
server_handshake_iv_holder
|
||||||
|
};
|
||||||
|
|
||||||
|
// Store nonce
|
||||||
|
self.client_handshake_nonce = Some(client_handshake_iv);
|
||||||
|
self.server_handshake_nonce = Some(server_handshake_iv);
|
||||||
|
|
||||||
|
// Construct cipher from key & IV for client & server
|
||||||
|
// Store the ciphers
|
||||||
|
match server_selected_cipher {
|
||||||
|
CipherSuite::TLS_AES_128_GCM_SHA256 => {
|
||||||
|
let client_handshake_cipher = Aes128Gcm::new(
|
||||||
|
GenericArray::from_slice(&client_handshake_key)
|
||||||
|
);
|
||||||
|
let server_handshake_cipher = Aes128Gcm::new(
|
||||||
|
GenericArray::from_slice(&server_handshake_key)
|
||||||
|
);
|
||||||
|
self.client_handshake_cipher = Some(
|
||||||
|
Cipher::Aes128Gcm {
|
||||||
|
aes128gcm: client_handshake_cipher
|
||||||
|
}
|
||||||
|
);
|
||||||
|
self.server_handshake_cipher = Some(
|
||||||
|
Cipher::Aes128Gcm {
|
||||||
|
aes128gcm: server_handshake_cipher
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
CipherSuite::TLS_CHACHA20_POLY1305_SHA256 => {
|
||||||
|
let client_handshake_cipher = ChaCha20Poly1305::new(
|
||||||
|
GenericArray::from_slice(&client_handshake_key)
|
||||||
|
);
|
||||||
|
let server_handshake_cipher = ChaCha20Poly1305::new(
|
||||||
|
GenericArray::from_slice(&server_handshake_key)
|
||||||
|
);
|
||||||
|
self.client_handshake_cipher = Some(
|
||||||
|
Cipher::Chacha20poly1305 {
|
||||||
|
chacha20poly1305: client_handshake_cipher
|
||||||
|
}
|
||||||
|
);
|
||||||
|
self.server_handshake_cipher = Some(
|
||||||
|
Cipher::Chacha20poly1305 {
|
||||||
|
chacha20poly1305: server_handshake_cipher
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
CipherSuite::TLS_AES_128_CCM_SHA256 => {
|
||||||
|
let client_handshake_cipher = Aes128Ccm::new(
|
||||||
|
GenericArray::from_slice(&client_handshake_key)
|
||||||
|
);
|
||||||
|
let server_handshake_cipher = Aes128Ccm::new(
|
||||||
|
GenericArray::from_slice(&server_handshake_key)
|
||||||
|
);
|
||||||
|
self.client_handshake_cipher = Some(
|
||||||
|
Cipher::Ccm {
|
||||||
|
ccm: client_handshake_cipher
|
||||||
|
}
|
||||||
|
);
|
||||||
|
self.server_handshake_cipher = Some(
|
||||||
|
Cipher::Ccm {
|
||||||
|
ccm: server_handshake_cipher
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
CipherSuite::TLS_AES_256_GCM_SHA384 => {
|
||||||
|
// Find early secret in terms wrapped in HKDF
|
||||||
|
let empty_psk: GenericArray<u8, <Sha384 as FixedOutput>::OutputSize> = Default::default();
|
||||||
|
let early_secret_hkdf =
|
||||||
|
Hkdf::<Sha384>::new(None, &empty_psk);
|
||||||
|
|
||||||
|
// Find handshake secret
|
||||||
|
let empty_hash = Sha384::new().chain("");
|
||||||
|
let derived_secret = derive_secret(
|
||||||
|
&early_secret_hkdf,
|
||||||
|
"derived",
|
||||||
|
empty_hash
|
||||||
|
);
|
||||||
|
|
||||||
|
let (handshake_secret, handshake_secret_hkdf) =
|
||||||
|
Hkdf::<Sha384>::extract(
|
||||||
|
Some(&derived_secret),
|
||||||
|
&shared_secret_bytes
|
||||||
|
);
|
||||||
|
|
||||||
|
// Store the handshake secret
|
||||||
|
self.latest_secret.replace(
|
||||||
|
Vec::from_slice(&handshake_secret)
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
let client_handshake_traffic_secret = derive_secret(
|
||||||
|
&handshake_secret_hkdf,
|
||||||
|
"c hs traffic",
|
||||||
|
self.hash.get_sha384_clone().unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
let server_handshake_traffic_secret = derive_secret(
|
||||||
|
&handshake_secret_hkdf,
|
||||||
|
"s hs traffic",
|
||||||
|
self.hash.get_sha384_clone().unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Store client_handshake_traffic_secret and
|
||||||
|
// server_handshake_traffic_secret
|
||||||
|
// Initial values of both secrets don't matter
|
||||||
|
self.client_handshake_traffic_secret.replace(
|
||||||
|
Vec::from_slice(&client_handshake_traffic_secret).unwrap()
|
||||||
|
);
|
||||||
|
self.server_handshake_traffic_secret.replace(
|
||||||
|
Vec::from_slice(&server_handshake_traffic_secret).unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
let client_handshake_traffic_secret_hkdf = Hkdf::<Sha384>::from_prk(&client_handshake_traffic_secret).unwrap();
|
||||||
|
let server_handshake_traffic_secret_hkdf = Hkdf::<Sha384>::from_prk(&server_handshake_traffic_secret).unwrap();
|
||||||
|
|
||||||
|
// Prepare holder for key and IV
|
||||||
|
let client_handshake_key: Vec<u8, U64> = {
|
||||||
|
// 32 bytes key size
|
||||||
|
let mut client_handshake_key_holder: Vec<u8, U64> =
|
||||||
|
Vec::from_slice(&[0; 32]).unwrap();
|
||||||
|
|
||||||
|
hkdf_expand_label(
|
||||||
|
&client_handshake_traffic_secret_hkdf,
|
||||||
|
"key",
|
||||||
|
"",
|
||||||
|
&mut client_handshake_key_holder
|
||||||
|
);
|
||||||
|
client_handshake_key_holder
|
||||||
|
};
|
||||||
|
|
||||||
|
let client_handshake_iv: Vec<u8, U12> = {
|
||||||
|
let mut client_handshake_iv_holder = Vec::from_slice(&[0; 12]).unwrap();
|
||||||
|
hkdf_expand_label(
|
||||||
|
&client_handshake_traffic_secret_hkdf,
|
||||||
|
"iv",
|
||||||
|
"",
|
||||||
|
&mut client_handshake_iv_holder
|
||||||
|
);
|
||||||
|
client_handshake_iv_holder
|
||||||
|
};
|
||||||
|
|
||||||
|
let server_handshake_key: Vec<u8, U64> = {
|
||||||
|
// 32 bytes key size
|
||||||
|
let mut server_handshake_key_holder: Vec<u8, U64> =
|
||||||
|
Vec::from_slice(&[0; 32]).unwrap();
|
||||||
|
|
||||||
|
hkdf_expand_label(
|
||||||
|
&server_handshake_traffic_secret_hkdf,
|
||||||
|
"key",
|
||||||
|
"",
|
||||||
|
&mut server_handshake_key_holder
|
||||||
|
);
|
||||||
|
server_handshake_key_holder
|
||||||
|
};
|
||||||
|
|
||||||
|
let server_handshake_iv: Vec<u8, U12> = {
|
||||||
|
let mut server_handshake_iv_holder = Vec::from_slice(&[0; 12]).unwrap();
|
||||||
|
hkdf_expand_label(
|
||||||
|
&server_handshake_traffic_secret_hkdf,
|
||||||
|
"iv",
|
||||||
|
"",
|
||||||
|
&mut server_handshake_iv_holder
|
||||||
|
);
|
||||||
|
server_handshake_iv_holder
|
||||||
|
};
|
||||||
|
|
||||||
|
// Store nonce
|
||||||
|
self.client_handshake_nonce = Some(client_handshake_iv);
|
||||||
|
self.server_handshake_nonce = Some(server_handshake_iv);
|
||||||
|
|
||||||
|
let client_handshake_cipher = Aes256Gcm::new(
|
||||||
|
GenericArray::from_slice(&client_handshake_key)
|
||||||
|
);
|
||||||
|
let server_handshake_cipher = Aes256Gcm::new(
|
||||||
|
GenericArray::from_slice(&server_handshake_key)
|
||||||
|
);
|
||||||
|
self.client_handshake_cipher = Some(
|
||||||
|
Cipher::Aes256Gcm {
|
||||||
|
aes256gcm: client_handshake_cipher
|
||||||
|
}
|
||||||
|
);
|
||||||
|
self.server_handshake_cipher = Some(
|
||||||
|
Cipher::Aes256Gcm {
|
||||||
|
aes256gcm: server_handshake_cipher
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
CipherSuite::TLS_AES_128_CCM_8_SHA256 => unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Will send EE, {CR}, Cert, CV FIN in the same state
|
||||||
|
// No need to mutate FSM
|
||||||
|
|
||||||
|
// Ensure that the sequence numbers start from 0
|
||||||
|
self.client_sequence_number = 0;
|
||||||
|
self.server_sequence_number = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn server_update_for_encrypted_extension(
|
||||||
|
&mut self,
|
||||||
|
encryption_extension_slice: &[u8],
|
||||||
|
) {
|
||||||
|
self.hash.update(encryption_extension_slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn verify_session_id_echo(&self, session_id_echo: &[u8]) -> bool {
|
pub(crate) fn verify_session_id_echo(&self, session_id_echo: &[u8]) -> bool {
|
||||||
@ -1214,9 +1569,9 @@ impl<'a> Session<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_session_id(&self) -> &[u8] {
|
pub(crate) fn get_session_id(&self) -> [u8; 32] {
|
||||||
if let Some(session_id) = &self.session_id {
|
if let Some(session_id) = &self.session_id {
|
||||||
session_id
|
*session_id
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
@ -1730,6 +2085,30 @@ impl<'a> Session<'a> {
|
|||||||
self.server_sequence_number += 1;
|
self.server_sequence_number += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn increment_local_sequence_number(&mut self) {
|
||||||
|
match self.role {
|
||||||
|
TlsRole::Client => {
|
||||||
|
self.client_sequence_number += 1;
|
||||||
|
},
|
||||||
|
TlsRole::Server => {
|
||||||
|
self.server_sequence_number += 1;
|
||||||
|
},
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn increment_remote_sequence_number(&mut self) {
|
||||||
|
match self.role {
|
||||||
|
TlsRole::Client => {
|
||||||
|
self.server_sequence_number += 1;
|
||||||
|
},
|
||||||
|
TlsRole::Server => {
|
||||||
|
self.client_sequence_number += 1;
|
||||||
|
},
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn get_session_role(&self) -> TlsRole {
|
pub(crate) fn get_session_role(&self) -> TlsRole {
|
||||||
self.role
|
self.role
|
||||||
}
|
}
|
||||||
@ -2013,3 +2392,20 @@ pub enum DiffieHellmanPrivateKey {
|
|||||||
ephemeral_secret: x25519_dalek::EphemeralSecret
|
ephemeral_secret: x25519_dalek::EphemeralSecret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DiffieHellmanPrivateKey {
|
||||||
|
pub fn to_public_key(&self) -> DiffieHellmanPublicKey {
|
||||||
|
match self {
|
||||||
|
Self::SECP256R1 { ephemeral_secret } => {
|
||||||
|
DiffieHellmanPublicKey::SECP256R1 {
|
||||||
|
encoded_point: p256::EncodedPoint::from(ephemeral_secret)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Self::X25519 { ephemeral_secret } => {
|
||||||
|
DiffieHellmanPublicKey::X25519 {
|
||||||
|
public_key: x25519_dalek::PublicKey::from(ephemeral_secret)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
75
src/tls.rs
75
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)]
|
||||||
@ -437,23 +437,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 +484,35 @@ 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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Other states regarding server role
|
// Other states regarding server role
|
||||||
@ -1222,16 +1264,19 @@ impl<'s> TlsSocket<'s> {
|
|||||||
// TODO: Rename this function. It is only good for client finished
|
// TODO: Rename this function. It is only good for client finished
|
||||||
fn send_application_slice(&self, sockets: &mut SocketSet, slice: &mut [u8]) -> Result<()> {
|
fn send_application_slice(&self, sockets: &mut SocketSet, slice: &mut [u8]) -> Result<()> {
|
||||||
let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle);
|
let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle);
|
||||||
|
log::info!("Got socket");
|
||||||
if !tcp_socket.can_send() {
|
if !tcp_socket.can_send() {
|
||||||
return Err(Error::Illegal);
|
return Err(Error::Illegal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log::info!("Socket usable");
|
||||||
// Borrow session in advance
|
// Borrow session in advance
|
||||||
let mut client_session = self.session.borrow_mut();
|
let mut session = self.session.borrow_mut();
|
||||||
|
log::info!("Got session");
|
||||||
|
|
||||||
// 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 +1291,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 +1300,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(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user