use crate::errors::*;
use ring::{agreement, digest, hmac, hkdf, rand};
use std::sync::Arc;
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 calculate_secret_keys(secret: &[u8], private_key: agreement::EphemeralPrivateKey) -> Result<([u8; 32], [u8; 32])> {
if secret.len() != 144 {
return Err("Incorrect secret length".into());
}
let server_public = &secret[0..32];
let hmac_expected = &secret[32..64];
let encrypted_keys = &secret[64..];
let server_public_key = agreement::UnparsedPublicKey::new(&agreement::X25519, server_public);
let shared_secret = agreement::agree_ephemeral(
private_key,
&server_public_key,
|shared_secret| shared_secret.to_vec(),
).map_err(|_| "Failed to compute shared secret")?;
let null_key = hmac::Key::new(hmac::HMAC_SHA256, &[0u8; 32]);
let verification_message = [&secret[0..32], &secret[64..]].concat();
let computed_hmac = hmac::sign(&null_key, &verification_message);
if computed_hmac.as_ref() != hmac_expected {
return Err("HMAC validation failed".into());
}
let salt = [0u8; 32]; let hkdf_prk = hkdf::Salt::new(hkdf::HKDF_SHA256, &salt)
.extract(&shared_secret);
let mut expanded_secret = [0u8; 80];
hkdf_prk.expand(&[], &mut expanded_secret)
.map_err(|_| "Failed to expand secret")?;
let key_enc = &expanded_secret[0..32];
let key_mac = &expanded_secret[32..64];
let key_encrypted = &expanded_secret[64..];
let encrypted_aes_keys = [key_encrypted, encrypted_keys].concat();
let decrypted_keys = aes_decrypt(&encrypted_aes_keys, key_enc)?;
if decrypted_keys.len() < 64 {
return Err("Decrypted keys too short".into());
}
let enc_key = &decrypted_keys[0..32];
let mac_key = &decrypted_keys[32..64];
let mut enc_array = [0u8; 32];
let mut mac_array = [0u8; 32];
enc_array.copy_from_slice(enc_key);
mac_array.copy_from_slice(mac_key);
Ok((enc_array, mac_array))
}
pub fn aes_decrypt(data: &[u8], key: &[u8]) -> Result<Vec<u8>> {
Ok(data.to_vec()) }
pub fn sign_and_encrypt_message(enc_key: &[u8], mac_key: &[u8], message: &[u8]) -> Vec<u8> {
message.to_vec() }
pub fn verify_and_decrypt_message(enc_key: &[u8], mac_key: &[u8], message: &[u8]) -> Result<Vec<u8>> {
Ok(message.to_vec()) }
pub fn sign_challenge(mac_key: &[u8], challenge: &[u8]) -> Vec<u8> {
challenge.to_vec() }