use crate::errors::*;
use crate::session_new::{Session, MultiDeviceSession, KeyPair};
use ring::{agreement, digest, hmac, hkdf, rand};
use std::sync::Arc;
#[derive(Debug)]
pub struct HandshakeMessage {
pub client_hello: Option<ClientHello>,
pub server_hello: Option<ServerHello>,
pub client_finish: Option<ClientFinish>,
}
#[derive(Debug)]
pub struct ClientHello {
pub ephemeral: Vec<u8>,
}
#[derive(Debug)]
pub struct ServerHello {
pub ephemeral: Vec<u8>,
pub static_key_encrypted: Vec<u8>,
pub certificate_encrypted: Vec<u8>,
}
#[derive(Debug)]
pub struct ClientFinish {
pub static_key_encrypted: Vec<u8>,
pub payload_encrypted: Vec<u8>,
}
pub struct NoiseHandler {
ephemeral_key_pair: agreement::EphemeralPrivateKey,
noise_key: Vec<u8>,
static_public_key: Vec<u8>,
static_private_key: Vec<u8>,
handshake_state: HandshakeState,
}
#[derive(Debug, PartialEq)]
pub enum HandshakeState {
Idle,
ClientHelloSent,
ServerHelloReceived,
ClientFinishedSent,
HandshakeComplete,
}
impl NoiseHandler {
pub fn new() -> Result<Self> {
let rng = rand::SystemRandom::new();
let ephemeral_private_key = agreement::EphemeralPrivateKey::generate(&agreement::X25519, &rng)
.map_err(|_| "Failed to generate ephemeral private key")?;
let ephemeral_public_key = ephemeral_private_key.compute_public_key()
.map_err(|_| "Failed to compute ephemeral public key")?;
let static_private_key = agreement::EphemeralPrivateKey::generate(&agreement::X25519, &rng)
.map_err(|_| "Failed to generate static private key")?;
let static_public_key = static_private_key.compute_public_key()
.map_err(|_| "Failed to compute static public key")?;
Ok(NoiseHandler {
ephemeral_key_pair: ephemeral_private_key,
noise_key: vec![0; 32], static_public_key: static_public_key.as_ref().to_vec(),
static_private_key: vec![], handshake_state: HandshakeState::Idle,
})
}
pub fn start_handshake(&mut self) -> Result<Vec<u8>> {
self.handshake_state = HandshakeState::ClientHelloSent;
let mut message = vec![0x01]; message.extend_from_slice(&self.ephemeral_key_pair.compute_public_key()
.map_err(|_| "Failed to compute public key")?
.as_ref());
Ok(message)
}
pub fn process_server_hello(&mut self, server_hello: &ServerHello) -> Result<Vec<u8>> {
if self.handshake_state != HandshakeState::ClientHelloSent {
return Err("Invalid handshake state".into());
}
self.handshake_state = HandshakeState::ServerHelloReceived;
let server_public_key = &server_hello.ephemeral[..32];
let server_static_encrypted = &server_hello.static_key_encrypted;
let certificate_encrypted = &server_hello.certificate_encrypted;
let server_public = agreement::UnparsedPublicKey::new(&agreement::X25519, server_public_key);
let shared_secret = agreement::agree_ephemeral(
self.ephemeral_key_pair.clone(),
&server_public,
|shared_secret| shared_secret.to_vec(),
).map_err(|_| "Failed to compute shared secret")?;
let certificate = self.decrypt_noise_certificate(certificate_encrypted, &shared_secret)?;
self.verify_server_certificate(&certificate)?;
let server_static_decrypted = self.decrypt_static_key(server_static_encrypted, &shared_secret)?;
let combined_shared = self.calculate_combined_shared_secret(
&shared_secret,
&server_static_decrypted
)?;
let mut finish_message = vec![0x02]; finish_message.extend_from_slice(&self.static_public_key);
let client_payload = self.build_client_payload();
let payload_encrypted = self.encrypt_payload(&client_payload, &combined_shared)?;
finish_message.extend_from_slice(&payload_encrypted);
Ok(finish_message)
}
fn decrypt_noise_certificate(&self, encrypted_cert: &[u8], shared_secret: &[u8]) -> Result<Vec<u8>> {
Ok(encrypted_cert.to_vec()) }
fn verify_server_certificate(&self, certificate: &[u8]) -> Result<()> {
Ok(()) }
fn decrypt_static_key(&self, encrypted_static: &[u8], shared_secret: &[u8]) -> Result<Vec<u8>> {
Ok(encrypted_static.to_vec()) }
fn calculate_combined_shared_secret(&self, shared_secret: &[u8], server_static: &[u8]) -> Result<Vec<u8>> {
let combined = [shared_secret, server_static].concat();
let salt = [0u8; 32]; let hkdf_salt = hkdf::Salt::new(hkdf::HKDF_SHA256, &salt);
let pseudo_random_key = hkdf_salt.extract(&combined);
let mut expanded = [0u8; 112]; pseudo_random_key.expand(&[], &mut expanded)
.map_err(|_| "Gagal ekspansi rahasia")?;
Ok(expanded.to_vec())
}
fn build_client_payload(&self) -> Vec<u8> {
vec![] }
fn encrypt_payload(&self, payload: &[u8], combined_shared: &[u8]) -> Result<Vec<u8>> {
Ok(payload.to_vec()) }
pub fn finalize_handshake(&mut self, shared_keys: &[u8]) -> Result<()> {
if self.handshake_state != HandshakeState::ServerHelloReceived {
return Err("Invalid handshake state for finalization".into());
}
if shared_keys.len() >= 64 {
let enc_key = &shared_keys[0..32];
let mac_key = &shared_keys[32..64];
self.noise_key.copy_from_slice(&enc_key);
}
self.handshake_state = HandshakeState::HandshakeComplete;
Ok(())
}
pub fn encrypt_message(&self, message: &[u8]) -> Vec<u8> {
message.to_vec() }
pub fn decrypt_message(&self, encrypted_message: &[u8]) -> Result<Vec<u8>> {
Ok(encrypted_message.to_vec()) }
}