use crate::transport::Deserializable;
use crate::transport::Serializable;
use libmilkyway_derive::{Deserializable, Serializable};
use crate::pki::certificate::Certificate;
use crate::pki::hash::HashType;
use crate::pki::impls::certificates::falcon1024::Falcon1024Certificate;
use crate::pki::impls::certificates::kyber1024::Kyber1024Certificate;
use crate::pki::impls::CryptoError;
use crate::pki::signature::Signature;
use crate::serialization::error::SerializationError;
use crate::serialization::serializable::Serialized;
use crate::transport::TransportTransformer;
pub struct CryptoTransformer{
local_signing_cert: Falcon1024Certificate,
local_encryption_cert: Kyber1024Certificate,
remote_signing_cert: Falcon1024Certificate,
remote_encryption_cert: Kyber1024Certificate,
}
#[derive(Serializable, Deserializable, Debug)]
pub struct CryptoMessage{
signature: Signature,
data: Serialized,
}
impl CryptoTransformer {
#[inline]
pub fn new(local_signing_cert: Falcon1024Certificate,
local_encryption_cert: Kyber1024Certificate,
remote_signing_cert: Falcon1024Certificate,
remote_encryption_cert: Kyber1024Certificate) -> CryptoTransformer{
CryptoTransformer{
local_signing_cert,
local_encryption_cert,
remote_signing_cert,
remote_encryption_cert,
}
}
}
impl TransportTransformer for CryptoTransformer{
fn detransform(&self, data: &Serialized) -> Result<Serialized, SerializationError> {
let message_result = CryptoMessage::from_serialized(data);
if message_result.is_err(){
return Err(message_result.err().unwrap());
}
let (message, _) = message_result.unwrap();
if !self.remote_signing_cert.verify_signature(&message.data, &message.signature){
return Err(SerializationError::CryptographicError(CryptoError::DataTampered));
}
let decrypted_data_result =
self.local_encryption_cert.decrypt::<Vec<u8>>(&message.data);
decrypted_data_result
}
fn transform(&self, data: &Serialized) -> Serialized {
let encrypted_data = self.remote_encryption_cert.encrypt(data)
.expect("Can not encrypt local packet");
let signature = self.local_signing_cert
.sign_data(&encrypted_data, HashType::None).expect("Can not sign local packet");
let message = CryptoMessage{
signature,
data: encrypted_data,
};
message.serialize()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::pki::impls::certificates::falcon1024::Falcon1024Certificate;
use crate::pki::impls::certificates::kyber1024::Kyber1024Certificate;
use crate::serialization::serializable::{Serializable, Serialized};
use crate::serialization::deserializable::Deserializable;
use crate::serialization::error::SerializationError;
use crate::pki::impls::CryptoError;
use crate::pki::impls::keys::falcon1024::generate_falcon1024_keypair;
use crate::pki::impls::keys::kyber1024::generate_kyber1024_keypair;
use crate::transport::TransportTransformer;
#[derive(Serializable, Deserializable, PartialEq, Debug)]
struct TestData {
message: String,
}
fn generate_falcon1024_certificate() -> Falcon1024Certificate {
let (public_key, secret_key) = generate_falcon1024_keypair();
Falcon1024Certificate {
serial_number: 1,
parent_serial_number: 0,
secret_key: Some(secret_key),
public_key,
signature: None,
name: "test".to_string(),
flags: 0,
}
}
fn generate_kyber1024_certificate() -> Kyber1024Certificate {
let (public_key, secret_key) = generate_kyber1024_keypair();
Kyber1024Certificate {
serial_number: 1,
parent_serial_number: 0,
secret_key: Some(secret_key),
public_key,
signature: None,
name: "test".to_string(),
flags: 0,
}
}
#[test]
fn test_crypto_transformer_transform_and_detransform() {
let local_signing_cert = generate_falcon1024_certificate();
let local_encryption_cert = generate_kyber1024_certificate();
let remote_signing_cert = generate_falcon1024_certificate();
let remote_encryption_cert = generate_kyber1024_certificate();
let transformer = CryptoTransformer::new(
local_signing_cert.clone(),
local_encryption_cert.clone(),
remote_signing_cert.clone_without_signature_and_sk(),
remote_encryption_cert.clone_without_signature_and_sk(),
);
let detransformer = CryptoTransformer::new(
remote_signing_cert.clone(),
remote_encryption_cert.clone(),
local_signing_cert.clone_without_signature_and_sk(),
local_encryption_cert.clone_without_signature_and_sk(),
);
let test_data = "Hello, world!".as_bytes().to_vec();
let serialized_data = test_data.serialize();
let transformed_data = transformer.transform(&serialized_data);
let detransformed_data = detransformer.detransform(&transformed_data).unwrap();
let deserialized_data = Vec::<u8>::from_serialized(&detransformed_data).unwrap().0;
assert_eq!(test_data, deserialized_data);
}
#[test]
fn test_crypto_transformer_detransform_with_tampering() {
let local_signing_cert = generate_falcon1024_certificate();
let local_encryption_cert = generate_kyber1024_certificate();
let remote_signing_cert = generate_falcon1024_certificate();
let remote_encryption_cert = generate_kyber1024_certificate();
let transformer = CryptoTransformer::new(
local_signing_cert.clone(),
local_encryption_cert.clone(),
remote_signing_cert.clone_without_signature_and_sk(),
remote_encryption_cert.clone_without_signature_and_sk(),
);
let detransformer = CryptoTransformer::new(
remote_signing_cert.clone(),
remote_encryption_cert.clone(),
local_signing_cert.clone_without_signature_and_sk(),
local_encryption_cert.clone_without_signature_and_sk(),
);
let test_data = TestData {
message: "Hello, World!".to_string(),
};
let serialized_data = test_data.serialize();
let mut transformed_data = transformer.transform(&serialized_data);
transformed_data[10] ^= 0xFF;
let detransform_result = detransformer.detransform(&transformed_data);
assert!(detransform_result.is_err());
assert_eq!(detransform_result.err().unwrap(), SerializationError::CryptographicError(CryptoError::DataTampered));
}
#[test]
fn test_crypto_transformer_detransform_with_invalid_data() {
let local_signing_cert = generate_falcon1024_certificate();
let local_encryption_cert = generate_kyber1024_certificate();
let remote_signing_cert = generate_falcon1024_certificate();
let remote_encryption_cert = generate_kyber1024_certificate();
let detransformer = CryptoTransformer::new(
remote_signing_cert.clone(),
remote_encryption_cert.clone(),
local_signing_cert.clone_without_signature_and_sk(),
local_encryption_cert.clone_without_signature_and_sk(),
);
let invalid_data: Serialized = vec![1, 2, 3, 4, 5];
let detransform_result = detransformer.detransform(&invalid_data);
assert!(detransform_result.is_err());
}
}