use crate::errors::*;
use ring::{agreement, digest, hmac, hkdf, rand};
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct SessionKeys {
pub enc_key: Vec<u8>,
pub mac_key: Vec<u8>,
}
pub fn generate_keypair() -> Result<(agreement::EphemeralPrivateKey, Vec<u8>)> {
let rng = rand::SystemRandom::new();
let private_key = agreement::EphemeralPrivateKey::generate(&agreement::X25519, &rng)
.map_err(|_| "Failed to generate private key")?;
let public_key = private_key.compute_public_key()
.map_err(|_| "Failed to compute public key")?;
Ok((private_key, public_key.as_ref().to_vec()))
}
pub fn derive_session_keys(
server_identity_public: &[u8],
expected_hmac: &[u8],
encrypted_keys: &[u8],
) -> Result<SessionKeys> {
let (our_private_key, our_public_key) = generate_keypair()?;
let server_public = agreement::UnparsedPublicKey::new(&agreement::X25519, server_identity_public);
let shared_secret = agreement::agree_ephemeral(
our_private_key,
&server_public,
|shared_secret| shared_secret.to_vec(),
).map_err(|_| "Failed to compute shared secret")?;
let verifier_key = hmac::Key::new(hmac::HMAC_SHA256, &[0u8; 32]); let verification_data = [server_identity_public, encrypted_keys].concat();
let computed_hmac = hmac::sign(&verifier_key, &verification_data);
if computed_hmac.as_ref() != expected_hmac {
return Err("HMAC verification failed".into());
}
let salt = [0u8; 32]; let hkdf_salt = hkdf::Salt::new(hkdf::HKDF_SHA256, &salt);
let pseudo_random_key = hkdf_salt.extract(&shared_secret);
let mut expanded_secret = [0u8; 112]; pseudo_random_key.expand(&[], &mut expanded_secret)
.map_err(|_| "Failed to expand secret")?;
let enc_key = expanded_secret[0..32].to_vec();
let mac_key = expanded_secret[32..64].to_vec();
Ok(SessionKeys {
enc_key,
mac_key,
})
}
pub fn encrypt_message(enc_key: &[u8], mac_key: &[u8], message: &[u8]) -> Result<Vec<u8>> {
Ok(message.to_vec())
}
pub fn decrypt_message(enc_key: &[u8], mac_key: &[u8], encrypted_message: &[u8]) -> Result<Vec<u8>> {
Ok(encrypted_message.to_vec())
}
pub fn sign_message(mac_key: &[u8], message: &[u8]) -> Vec<u8> {
let signing_key = hmac::Key::new(hmac::HMAC_SHA256, mac_key);
hmac::sign(&signing_key, message).as_ref().to_vec()
}
pub fn sign_and_encrypt_message(enc_key: &[u8], mac_key: &[u8], message: &[u8]) -> Vec<u8> {
let encrypted = encrypt_message(enc_key, mac_key, message).unwrap_or(message.to_vec());
let signature = sign_message(mac_key, &encrypted);
[signature, encrypted].concat()
}
pub fn verify_and_decrypt_message(enc_key: &[u8], mac_key: &[u8], message: &[u8]) -> Result<Vec<u8>> {
if message.len() < 32 {
return Err("Message too short".into());
}
let received_hmac = &message[0..32];
let encrypted_content = &message[32..];
let computed_hmac = sign_message(mac_key, encrypted_content);
if received_hmac != computed_hmac {
return Err("HMAC verification failed".into());
}
decrypt_message(enc_key, mac_key, encrypted_content)
}
pub fn create_temporary_key() -> Result<[u8; 32]> {
let mut key = [0u8; 32];
rand::SystemRandom::new().fill(&mut key)
.map_err(|_| "Failed to generate random key")?;
Ok(key)
}