session: server hello key calc update
This commit is contained in:
parent
27800091d4
commit
ab5719ed44
|
@ -1198,6 +1198,14 @@ impl<'a> Session<'a> {
|
|||
self.state = TlsState::NEGOTIATED;
|
||||
}
|
||||
|
||||
pub(crate) fn server_update_for_server_hello(
|
||||
&mut self,
|
||||
server_ecdhe_secret: DiffieHellmanPrivateKey,
|
||||
server_hello_slice: &[u8]
|
||||
) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub(crate) fn verify_session_id_echo(&self, session_id_echo: &[u8]) -> bool {
|
||||
if let Some(session_id_inner) = self.session_id {
|
||||
session_id_inner == session_id_echo
|
||||
|
@ -1206,6 +1214,30 @@ impl<'a> Session<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_session_id(&self) -> &[u8] {
|
||||
if let Some(session_id) = &self.session_id {
|
||||
session_id
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_cipher_suite(&self) -> CipherSuite {
|
||||
if let Some(cipher_suite) = self.server_selected_cipher {
|
||||
cipher_suite
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_server_ecdhe_public_key(&self) -> DiffieHellmanPublicKey {
|
||||
if let Some(server_ecdhe_public_key) = self.ecdhe_public {
|
||||
server_ecdhe_public_key
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_tls_state(&self) -> TlsState {
|
||||
self.state
|
||||
}
|
||||
|
@ -1963,6 +1995,7 @@ pub enum CertificatePrivateKey {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum DiffieHellmanPublicKey {
|
||||
SECP256R1 {
|
||||
encoded_point: p256::EncodedPoint
|
||||
|
@ -1971,3 +2004,12 @@ pub enum DiffieHellmanPublicKey {
|
|||
public_key: x25519_dalek::PublicKey
|
||||
}
|
||||
}
|
||||
|
||||
pub enum DiffieHellmanPrivateKey {
|
||||
SECP256R1 {
|
||||
ephemeral_secret: p256::ecdh::EphemeralSecret
|
||||
},
|
||||
X25519 {
|
||||
ephemeral_secret: x25519_dalek::EphemeralSecret
|
||||
}
|
||||
}
|
||||
|
|
44
src/tls.rs
44
src/tls.rs
|
@ -429,6 +429,50 @@ impl<'s> TlsSocket<'s> {
|
|||
// There is nothing to send
|
||||
TlsState::SERVER_START => {}
|
||||
|
||||
// Respond to a Client Hello initiation with:
|
||||
// - Server Hello
|
||||
// - Encrypted Extensions
|
||||
// - (Possible) Certificate Request
|
||||
// - Certificate
|
||||
// - CertificateVerify
|
||||
// - Finished
|
||||
TlsState::NEGOTIATED => {
|
||||
let mut session = self.session.borrow_mut();
|
||||
let mut random: [u8; 32] = [0; 32];
|
||||
self.rng.fill_bytes(&mut random);
|
||||
// Relay session id
|
||||
let session_id = session.get_session_id();
|
||||
let cipher_suite = session.get_cipher_suite();
|
||||
let ecdhe_key = session.get_server_ecdhe_public_key();
|
||||
|
||||
let repr = TlsRepr::new().server_hello(
|
||||
&random,
|
||||
session_id,
|
||||
cipher_suite,
|
||||
ecdhe_key
|
||||
);
|
||||
|
||||
{
|
||||
let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle);
|
||||
tcp_socket.send(
|
||||
|data| {
|
||||
// Enqueue the TLS representation
|
||||
let mut buffer = TlsBuffer::new(data);
|
||||
if buffer.enqueue_tls_repr(repr).is_err() {
|
||||
return (0, ())
|
||||
}
|
||||
let slice: &[u8] = buffer.into();
|
||||
|
||||
// Update session
|
||||
todo!();
|
||||
|
||||
// Send the data
|
||||
(slice.len(), ())
|
||||
}
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
// Other states regarding server role
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ use core::convert::TryInto;
|
|||
use alloc::vec::Vec;
|
||||
|
||||
use crate::certificate::Certificate as Asn1DerCertificate;
|
||||
use crate::session::DiffieHellmanPublicKey;
|
||||
|
||||
pub(crate) const HRR_RANDOM: [u8; 32] = [
|
||||
0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
|
||||
|
@ -59,7 +60,13 @@ impl<'a> TlsRepr<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn client_hello(mut self, p256_secret: &EphemeralSecret, x25519_secret: &x25519_dalek::EphemeralSecret, random: [u8; 32], session_id: [u8; 32]) -> Self {
|
||||
pub(crate) fn client_hello(
|
||||
mut self,
|
||||
p256_secret: &EphemeralSecret,
|
||||
x25519_secret: &x25519_dalek::EphemeralSecret,
|
||||
random: [u8; 32],
|
||||
session_id: [u8; 32]
|
||||
) -> Self {
|
||||
self.content_type = TlsContentType::Handshake;
|
||||
self.version = TlsVersion::Tls10;
|
||||
let handshake_repr = {
|
||||
|
@ -76,6 +83,35 @@ impl<'a> TlsRepr<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
pub(crate) fn server_hello(
|
||||
mut self,
|
||||
random: &'a [u8],
|
||||
session_id: &'a [u8],
|
||||
cipher_suite: CipherSuite,
|
||||
server_ecdhe_public_key: DiffieHellmanPublicKey
|
||||
) -> Self {
|
||||
self.content_type = TlsContentType::Handshake;
|
||||
self.version = TlsVersion::Tls12;
|
||||
let handshake_repr = {
|
||||
let mut repr = HandshakeRepr::new();
|
||||
repr.msg_type = HandshakeType::ServerHello;
|
||||
repr.handshake_data = HandshakeData::ServerHello(
|
||||
{
|
||||
ServerHello::new(
|
||||
random,
|
||||
session_id,
|
||||
cipher_suite,
|
||||
server_ecdhe_public_key
|
||||
)
|
||||
}
|
||||
);
|
||||
repr
|
||||
};
|
||||
self.length = handshake_repr.get_length();
|
||||
self.handshake = Some(handshake_repr);
|
||||
self
|
||||
}
|
||||
|
||||
// TODO: Consider replace all these boolean function
|
||||
// into a single function that returns the HandshakeType.
|
||||
pub(crate) fn is_server_hello(&self) -> bool {
|
||||
|
@ -256,7 +292,7 @@ impl<'a> HandshakeData<'a> {
|
|||
pub(crate) fn get_length(&self) -> usize {
|
||||
match self {
|
||||
HandshakeData::ClientHello(data) => data.get_length(),
|
||||
HandshakeData::ServerHello(_data) => todo!(),
|
||||
HandshakeData::ServerHello(data) => data.get_length(),
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
@ -489,6 +525,121 @@ pub(crate) struct ServerHello<'a> {
|
|||
pub(crate) extensions: Vec<Extension>,
|
||||
}
|
||||
|
||||
impl<'a> ServerHello<'a> {
|
||||
pub(crate) fn new(
|
||||
random: &'a[u8],
|
||||
session_id_echo: &'a[u8],
|
||||
cipher_suite: CipherSuite,
|
||||
server_ecdhe_public_key: DiffieHellmanPublicKey,
|
||||
) -> Self {
|
||||
let server_hello = Self {
|
||||
version: TlsVersion::Tls12,
|
||||
random,
|
||||
session_id_echo_length: 32,
|
||||
session_id_echo,
|
||||
cipher_suite,
|
||||
compression_method: 0,
|
||||
extension_length: 0,
|
||||
extensions: Vec::new()
|
||||
};
|
||||
|
||||
server_hello.add_sh_supported_versions()
|
||||
.add_key_share(server_ecdhe_public_key)
|
||||
.finalise()
|
||||
}
|
||||
|
||||
pub(crate) fn add_sh_supported_versions(mut self) -> Self {
|
||||
let supported_version_server_hello = SupportedVersions::ServerHello {
|
||||
selected_version: TlsVersion::Tls13
|
||||
};
|
||||
let extension_data = ExtensionData::SupportedVersions(
|
||||
supported_version_server_hello
|
||||
);
|
||||
let extension = Extension {
|
||||
extension_type: ExtensionType::SupportedVersions,
|
||||
length: 2,
|
||||
extension_data
|
||||
};
|
||||
|
||||
// Push the extension into the vector
|
||||
self.extensions.push(extension);
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn add_key_share(
|
||||
mut self,
|
||||
server_ecdh_public_key: DiffieHellmanPublicKey
|
||||
) -> Self {
|
||||
let mut key_exchange: Vec<u8> = Vec::new();
|
||||
use DiffieHellmanPublicKey::*;
|
||||
let group = match server_ecdh_public_key {
|
||||
SECP256R1 { encoded_point } => {
|
||||
// Convert EncodedPoint into untagged bytes
|
||||
// In the format of x || y
|
||||
// Then put 0x04 before the bytes ( 0x04 || x || y )
|
||||
key_exchange.push(0x04);
|
||||
key_exchange.extend_from_slice(
|
||||
&encoded_point.to_untagged_bytes().unwrap()
|
||||
);
|
||||
NamedGroup::secp256r1
|
||||
},
|
||||
X25519 { public_key } => {
|
||||
key_exchange.extend_from_slice(
|
||||
public_key.as_bytes()
|
||||
);
|
||||
NamedGroup::x25519
|
||||
}
|
||||
};
|
||||
|
||||
let length = u16::try_from(key_exchange.len()).unwrap();
|
||||
|
||||
let server_share = KeyShareEntry {
|
||||
group,
|
||||
length,
|
||||
key_exchange
|
||||
};
|
||||
|
||||
let key_share_entry_content = KeyShareEntryContent::KeyShareServerHello {
|
||||
server_share
|
||||
};
|
||||
|
||||
let extension_data = ExtensionData::KeyShareEntry(
|
||||
key_share_entry_content
|
||||
);
|
||||
|
||||
let extension = Extension {
|
||||
extension_type: ExtensionType::KeyShare,
|
||||
length: length + 2 + 2, // 4 bytes precedes key_exchange, length(2) and group(2)
|
||||
extension_data
|
||||
};
|
||||
|
||||
self.extensions.push(extension);
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn finalise(mut self) -> Self {
|
||||
let mut sum = 0;
|
||||
for extension in self.extensions.iter() {
|
||||
// TODO: Add up the extension length
|
||||
sum += extension.get_length();
|
||||
}
|
||||
self.extension_length = sum.try_into().unwrap();
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn get_length(&self) -> usize {
|
||||
let mut length: usize = 2; // TlsVersion size
|
||||
length += 32; // Random size
|
||||
length += 1; // Legacy session_id length size
|
||||
length += 32; // Legacy session_id size
|
||||
length += 2; // cipher_suites size
|
||||
length += 1; // Compression method: 0
|
||||
length += 2; // Extension_length
|
||||
length += usize::try_from(self.extension_length).unwrap();
|
||||
length
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct EncryptedExtensions {
|
||||
pub(crate) length: u16,
|
||||
|
|
Loading…
Reference in New Issue