#[cfg(test)]
mod pad_binary_tests {
use crate::crypto::CryptoUtils;
#[test]
fn test_pad_binary() {
let data = b"Hello, World!";
let padded = CryptoUtils::pad_binary(data);
assert_eq!(padded.len(), data.len() + (16 - (data.len() % 16))); assert_eq!(&padded[data.len()..], &[3, 3, 3]); }
}
#[cfg(test)]
mod unpad_binary_tests {
use crate::{crypto::CryptoUtils, custom_error::KSMRError};
#[test]
fn test_unpad_binary() {
let data = b"Hello, World!\x03\x03\x03"; let unpadded = CryptoUtils::unpad_binary(data).unwrap();
assert_eq!(&unpadded, b"Hello, World!");
}
#[test]
fn test_unpad_binary_invalid() {
let data = b"Hello, World!\x05\x05\x05\x05"; let result = CryptoUtils::unpad_binary(data);
assert!(result.is_err());
assert_eq!(
result.unwrap_err(),
KSMRError::CryptoError("Invalid data length".to_string())
);
}
#[test]
fn test_unpad_binary_invalid_pad_length() {
let data = b"Hello, World!\x05\x05\x05"; let result = CryptoUtils::unpad_binary(data);
assert!(result.is_err());
assert_eq!(
result.unwrap_err(),
KSMRError::CryptoError("Invalid padding".to_string())
);
}
}
#[cfg(test)]
mod unpad_char_tests {
use crate::{crypto::CryptoUtils, custom_error::KSMRError};
#[test]
fn test_unpad_char() {
let data = b"Hello, World!\x04\x04\x04\x04"; let unpadded = CryptoUtils::unpad_char(data).unwrap();
assert_eq!(&unpadded, b"Hello, World!");
}
#[test]
fn test_unpad_char_invalid() {
let data = b"Hello, World!\x05\x05\x05\x05"; let result = CryptoUtils::unpad_char(data);
assert!(result.is_err());
assert_eq!(
result.unwrap_err(),
KSMRError::CryptoError("Invalid padding".to_string())
);
}
}
#[cfg(test)]
mod pad_data_tests {
use crate::crypto::pad_data;
#[test]
fn test_pad_data_basic() {
let data = b"Hello";
let block_size = 8; let padded = pad_data(data, block_size);
assert_eq!(padded.len(), 8);
assert_eq!(&padded[..5], data); assert_eq!(&padded[5..], &[3, 3, 3]); }
#[test]
fn test_pad_data_exact_block_size() {
let data: Vec<u8> = b"Hello!!!".to_vec(); let mut data_clone = data.clone();
let block_size = 8;
let padded = pad_data(&data, block_size);
let expected_padding: Vec<u8> = vec![8, 8, 8, 8, 8, 8, 8, 8];
let _expected_data = data_clone.extend(expected_padding);
assert_eq!(padded.len(), data.len() + block_size);
assert_eq!(&padded[..], data_clone); }
#[test]
fn test_pad_data_multiple_blocks() {
let data = b"Hello, World!"; let block_size = 16;
let padded = pad_data(data, block_size);
assert_eq!(padded.len(), 16);
assert_eq!(&padded[..13], data); assert_eq!(&padded[13..], &[3, 3, 3]); }
#[test]
fn test_pad_data_small_data() {
let data = b"Hi"; let block_size = 4;
let padded = pad_data(data, block_size);
assert_eq!(padded.len(), 4);
assert_eq!(&padded[..2], data); assert_eq!(&padded[2..], &[2, 2]); }
#[test]
fn test_pad_data_empty_data() {
let data: &[u8] = b""; let block_size = 16;
let padded = pad_data(data, block_size);
assert_eq!(padded.len(), 16);
assert_eq!(&padded[..], &[16; 16]); }
}
#[cfg(test)]
mod unpad_data_tests {
use crate::{crypto::unpad_data, custom_error::KSMRError};
#[test]
fn test_unpad_data_valid() {
let data = b"YELLOW SUBMA\x04\x04\x04\x04"; let result = unpad_data(data).unwrap();
assert_eq!(&result, b"YELLOW SUBMA"); }
#[test]
fn test_unpad_data_valid_empty_padding() {
let data = b"Hello!\x0A\x0A\x0A\x0A\x0A\x0A\x0A\x0A\x0A\x0A"; let result = unpad_data(data).unwrap();
assert_eq!(&result, b"Hello!"); }
#[test]
fn test_unpad_data_empty_input() {
let data: &[u8] = b""; let result = unpad_data(data);
assert!(result.is_err());
assert_eq!(
result.unwrap_err(),
KSMRError::CryptoError("Data is empty".to_string())
);
}
#[test]
fn test_unpad_data_invalid_padding_length() {
let data = b"Hello!\x05\x05\x05"; let result = unpad_data(data);
assert!(result.is_err());
assert_eq!(
result.unwrap_err(),
KSMRError::CryptoError("Invalid padding bytes".to_string())
);
}
#[test]
fn test_unpad_data_excessive_padding() {
let data = b"Hello!\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10"; let result = unpad_data(data);
assert!(!result.is_err());
}
#[test]
fn test_unpad_data_correct_padding_bytes_wrong_padding_length() {
let data = b"Hello, World!\x02\x02"; let result = unpad_data(data);
assert!(!result.is_err());
}
}
#[cfg(test)]
mod bytes_to_int_tests {
use std::str::FromStr;
use num_bigint::BigUint;
use crate::{crypto::CryptoUtils, custom_error::KSMRError};
#[test]
fn test_valid_input() {
assert_eq!(
CryptoUtils::bytes_to_int(&[0, 0, 0, 0, 0, 0, 0, 1]),
Ok(BigUint::from(1u16))
);
assert_eq!(
CryptoUtils::bytes_to_int(&[0, 0, 0, 0, 0, 0, 1, 0]),
Ok(BigUint::from(256u64))
);
assert_eq!(
CryptoUtils::bytes_to_int(&[0, 1, 2, 3]),
Ok(BigUint::from(66051u64))
); }
#[test]
fn test_max_length() {
let expected = BigUint::from(u128::MAX) + BigUint::from(1u128);
let bytes = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
assert_eq!(CryptoUtils::bytes_to_int(&bytes), Ok(expected));
}
#[test]
fn test_too_long_input() {
assert_eq!(
CryptoUtils::bytes_to_int(&[1; 17]),
Ok(BigUint::from_str("341616807575530379006368233343265341697").unwrap())
); }
#[test]
fn test_empty_input() {
assert_eq!(
CryptoUtils::bytes_to_int(&[]),
Err(KSMRError::InsufficientBytes("Input is empty".to_string()))
); }
}
#[cfg(test)]
mod url_safe_string_to_bytes_tests {
use crate::crypto::CryptoUtils;
use crate::custom_error::KSMRError;
#[test]
fn test_valid_input() {
let encoded_str = "ZHVtbXkxMjM";
let result = CryptoUtils::url_safe_str_to_bytes(encoded_str);
assert_eq!(result, Ok(vec![100, 117, 109, 109, 121, 49, 50, 51]));
}
#[test]
fn test_invalid_input() {
let encoded_str = "abc#def$ghi"; let result = CryptoUtils::url_safe_str_to_bytes(encoded_str);
assert_eq!(
result,
Err(KSMRError::DecodeError(
"Invalid symbol 35, offset 3.".to_string()
))
); }
}
#[cfg(test)]
mod generate_random_bytes_tests {
use crate::crypto::CryptoUtils;
#[test]
fn test_generate_random_bytes_length() {
let length = 16;
let bytes = CryptoUtils::generate_random_bytes(length);
assert_eq!(
bytes.len(),
length,
"The length of the generated bytes should be {}",
length
);
}
#[test]
fn test_generate_random_bytes_non_empty() {
let length = 16;
let bytes = CryptoUtils::generate_random_bytes(length);
assert!(!bytes.is_empty(), "The generated bytes should not be empty");
}
#[test]
fn test_generate_random_bytes_unique() {
let length = 16;
let bytes1 = CryptoUtils::generate_random_bytes(length);
let bytes2 = CryptoUtils::generate_random_bytes(length);
assert_ne!(
bytes1, bytes2,
"Generated byte arrays should not be the same"
);
}
#[test]
fn test_generate_random_bytes_varied_lengths() {
for &length in &[1, 8, 16, 32, 64] {
let bytes = CryptoUtils::generate_random_bytes(length);
assert_eq!(
bytes.len(),
length,
"The length of the generated bytes should be {}",
length
);
}
}
}
#[cfg(test)]
mod generate_encryption_key_bytes_tests {
use crate::crypto::CryptoUtils;
#[test]
fn test_generate_encryption_key_bytes_length() {
let key = CryptoUtils::generate_encryption_key_bytes();
assert_eq!(key.len(), 32);
}
#[test]
fn test_generate_encryption_key_bytes_randomness() {
let key1 = CryptoUtils::generate_encryption_key_bytes();
let key2 = CryptoUtils::generate_encryption_key_bytes();
assert_ne!(key1, key2);
}
#[test]
fn test_generate_encryption_key_bytes_non_empty() {
let key = CryptoUtils::generate_encryption_key_bytes();
assert!(!key.is_empty());
}
}
#[cfg(test)]
mod bytes_to_url_safe_string_tests {
use crate::crypto::CryptoUtils;
#[test]
fn test_empty_bytes() {
let input: &[u8] = &[];
let result = CryptoUtils::bytes_to_url_safe_str(input);
assert_eq!(result, "");
}
#[test]
fn test_single_byte() {
let input = &[1];
let result = CryptoUtils::bytes_to_url_safe_str(input);
assert_eq!(result, "AQ");
}
#[test]
fn test_multiple_bytes() {
let input = &[1, 2, 3, 4, 5];
let result = CryptoUtils::bytes_to_url_safe_str(input);
assert_eq!(result, "AQIDBAU");
}
#[test]
fn test_url_safe() {
let input = b"Hello, World!";
let result = CryptoUtils::bytes_to_url_safe_str(input);
assert_eq!(result, "SGVsbG8sIFdvcmxkIQ");
}
#[test]
fn test_padding_removal() {
let input = &[0b11111111, 0b11111111]; let result = CryptoUtils::bytes_to_url_safe_str(input);
assert_eq!(result, "__8"); }
}
#[cfg(test)]
mod url_safe_string_to_int_tests {
use num_bigint::BigUint;
use crate::crypto::CryptoUtils;
#[test]
fn test_valid_input() {
let encoded_str = "ZHVtbXkxMjM"; let result = CryptoUtils::url_safe_str_to_int(encoded_str);
assert_eq!(result, Ok(BigUint::from(7238812293020070451u64)));
}
}
#[cfg(test)]
mod generate_ecc_keys_tests {
use crate::crypto::CryptoUtils;
use crate::custom_error::KSMRError;
use p256::ecdsa::signature::{Signer, Verifier};
use p256::ecdsa::{Signature, VerifyingKey};
#[test]
fn test_generate_ecc_keys() {
let signing_key = CryptoUtils::generate_ecc_keys()
.map_err(|err| KSMRError::CryptoError(err.to_string()))
.unwrap();
let verifying_key = VerifyingKey::from(&signing_key);
let message = b"Test message";
let signature: Signature = signing_key.sign(message);
assert!(verifying_key.verify(message, &signature).is_ok());
}
#[test]
fn test_encryption_key_bytes_length() {
let encryption_key_bytes = CryptoUtils::generate_encryption_key_bytes();
assert_eq!(
encryption_key_bytes.len(),
32,
"Expected encryption key bytes to be of length 32"
);
}
#[test]
fn test_bytes_to_url_safe_str() {
let bytes = b"Test data";
let url_safe_str = CryptoUtils::bytes_to_url_safe_str(bytes);
assert!(!url_safe_str.is_empty());
}
#[test]
fn test_url_safe_str_to_int() {
let bytes = b"Test data";
let url_safe_str = CryptoUtils::bytes_to_url_safe_str(bytes);
let result = CryptoUtils::url_safe_str_to_int(&url_safe_str);
assert!(result.is_ok(), "Expected conversion to succeed");
let int_value = result.unwrap();
assert_eq!(
int_value,
CryptoUtils::bytes_to_int(bytes).unwrap(),
"The integer values should match"
);
}
}
#[cfg(test)]
mod public_key_ecc_tests {
use crate::crypto::CryptoUtils;
use p256::ecdsa::SigningKey;
use rand::rngs::OsRng;
#[test]
fn test_public_key_ecc() {
let mut rng = OsRng;
let private_key = SigningKey::random(&mut rng);
let public_key_bytes = CryptoUtils::public_key_ecc(&private_key);
assert!(
!public_key_bytes.is_empty(),
"Public key bytes should not be empty"
);
assert_eq!(
public_key_bytes.len(),
65,
"Public key bytes length should be 65 for uncompressed format"
);
assert_eq!(
public_key_bytes[0], 0x04,
"First byte should indicate uncompressed format"
);
}
#[test]
fn test_public_key_ecc_with_fixed_private_key() {
let private_key_bytes: [u8; 32] = [
0x1E, 0x90, 0x68, 0xE4, 0xA7, 0xBF, 0x4D, 0x77, 0x3A, 0x46, 0x23, 0xB2, 0xAA, 0x45,
0xA2, 0x4E, 0xB3, 0xD5, 0x6A, 0x92, 0x7F, 0x5A, 0x84, 0xC1, 0x7F, 0xC7, 0x7C, 0xE1,
0x7A, 0x73, 0x36, 0x1D,
];
let private_key = SigningKey::from_bytes((&private_key_bytes).into()).unwrap();
let public_key_bytes = CryptoUtils::public_key_ecc(&private_key);
let expected_public_key_bytes: [u8; 65] = [
4, 114, 157, 21, 90, 252, 246, 174, 130, 152, 121, 99, 41, 136, 127, 198, 106, 226, 37,
182, 222, 212, 74, 102, 55, 227, 126, 239, 129, 7, 55, 253, 34, 111, 213, 201, 10, 206,
162, 86, 175, 83, 69, 153, 145, 48, 111, 12, 223, 36, 113, 42, 167, 82, 136, 18, 140,
37, 140, 102, 74, 152, 35, 146, 2,
];
assert_eq!(
public_key_bytes.as_slice(),
&expected_public_key_bytes,
"Public key bytes do not match expected values"
);
}
}
#[cfg(test)]
mod generate_private_key_ecc_tests {
use crate::crypto::CryptoUtils;
#[test]
fn test_generate_private_key_ecc_length() {
let signing_key = CryptoUtils::generate_private_key_ecc().unwrap();
let key_bytes = signing_key.to_bytes();
assert_eq!(
key_bytes.len(),
32,
"The generated key should be 32 bytes long."
);
}
#[test]
fn test_generate_private_key_ecc_non_zero() {
let signing_key = CryptoUtils::generate_private_key_ecc().unwrap();
let key_bytes = signing_key.to_bytes();
assert!(
key_bytes.iter().any(|&byte| byte != 0),
"The generated key should not be all zeros."
);
}
#[test]
fn test_generate_multiple_private_keys() {
let key1 = CryptoUtils::generate_private_key_ecc().unwrap();
let key2 = CryptoUtils::generate_private_key_ecc().unwrap();
assert_ne!(
key1.to_bytes(),
key2.to_bytes(),
"Generated keys should be different."
);
}
#[test]
fn test_key_bytes_conversion() {
let signing_key = CryptoUtils::generate_private_key_ecc().unwrap();
let key_bytes = signing_key.to_bytes();
let expected_length = 32;
assert_eq!(
key_bytes.len(),
expected_length,
"Key bytes should be the expected length."
);
}
#[test]
fn test_url_safe_conversion() {
let signing_key = CryptoUtils::generate_private_key_ecc().unwrap();
let key_bytes = signing_key.to_bytes();
let private_key_str = CryptoUtils::bytes_to_url_safe_str(&key_bytes);
let encryption_key_int = CryptoUtils::url_safe_str_to_int(&private_key_str)
.expect("Failed to convert URL-safe Base64 string to integer");
let int_bytes = encryption_key_int.to_bytes_be();
let mut concatenated_bytes: [u8; 32] = [0u8; 32];
let offset = 32 - int_bytes.len();
concatenated_bytes[offset..].copy_from_slice(&int_bytes[..]);
assert_eq!(
concatenated_bytes.len(),
key_bytes.len(),
"Byte lengths should match."
);
let key_bytes_fixed: &[u8] = &key_bytes; assert_eq!(
&concatenated_bytes[..],
key_bytes_fixed,
"Converted integer bytes should match original key bytes."
);
}
#[test]
fn test_generate_private_key_ecc_reproducibility() {
let key1 = CryptoUtils::generate_private_key_ecc().unwrap();
let key2 = CryptoUtils::generate_private_key_ecc().unwrap();
assert_ne!(
key1.to_bytes(),
key2.to_bytes(),
"Keys generated in two calls should be different."
);
}
}
#[cfg(test)]
mod generate_private_key_der_tests {
use crate::crypto::CryptoUtils;
use p256::ecdsa::VerifyingKey;
#[test]
fn test_generate_private_key_ecc() {
let signing_key = CryptoUtils::generate_private_key_ecc().unwrap();
assert!(
signing_key.to_bytes().len() == 32,
"SigningKey should be 32 bytes long."
);
let verifying_key: VerifyingKey = signing_key.verifying_key().clone();
assert!(
verifying_key.to_encoded_point(false).as_ref().len() > 0,
"Public key should be derivable."
);
}
#[test]
fn test_generate_private_key_der() {
let private_key_der = CryptoUtils::generate_private_key_der().unwrap();
assert!(
!private_key_der.is_empty(),
"Private key DER should not be empty."
);
assert!(
private_key_der.len() > 64,
"Private key DER should be greater than 64 bytes."
);
}
#[test]
fn test_invalid_key_conversion() {
let invalid_key = "invalid_key_format";
let result = CryptoUtils::url_safe_str_to_int(invalid_key);
assert!(
result.is_err(),
"Invalid key format should return an error."
);
}
#[test]
fn test_generate_random_bytes() {
let bytes = CryptoUtils::generate_random_bytes(32);
assert_eq!(
bytes.len(),
32,
"Generated random bytes should have length of 32."
);
let another_bytes = CryptoUtils::generate_random_bytes(32);
assert_ne!(
bytes, another_bytes,
"Consecutive random byte generations should not produce the same result."
);
}
}
#[cfg(test)]
mod generate_new_ecc_key_tests {
use crate::crypto::CryptoUtils;
#[test]
fn test_generate_new_ecc_key() {
let key = CryptoUtils::generate_new_ecc_key();
assert!(
!key.to_bytes().is_empty(),
"Generated key should not be empty."
);
let public_key = key.verifying_key();
assert!(
public_key.to_encoded_point(false).as_ref().len() > 0,
"Public key should be valid and non-empty."
);
}
#[test]
fn test_generate_multiple_keys() {
let key1 = CryptoUtils::generate_new_ecc_key();
let key2 = CryptoUtils::generate_new_ecc_key();
assert_ne!(
key1.to_bytes(),
key2.to_bytes(),
"Two generated keys should be different."
);
}
}
#[cfg(test)]
mod encrypt_aes_tests {
use crate::crypto::CryptoUtils;
#[test]
fn test_encrypt_aes_gcm_success() {
let key = [0u8; 32];
let data = b"Hello, World!";
let result = CryptoUtils::encrypt_aes_gcm(data, &key, None);
assert!(result.is_ok());
let encrypted_data = result.unwrap();
assert!(encrypted_data.len() > data.len()); }
#[test]
fn test_encrypt_aes_gcm_invalid_key_length() {
let invalid_key = [0u8; 16]; let data = b"Hello, World!";
let result = CryptoUtils::encrypt_aes_gcm(data, &invalid_key, None);
assert!(result.is_err());
assert_eq!(
result.unwrap_err().to_string(),
"Cryptography module Error: Invalid key size"
);
}
#[test]
fn test_encrypt_aes_gcm_with_nonce() {
let key = [0u8; 32]; let data = b"Hello, World!";
let nonce = [0u8; 12];
let result = CryptoUtils::encrypt_aes_gcm(data, &key, Some(&nonce));
assert!(result.is_ok());
let encrypted_data = result.unwrap();
assert!(encrypted_data.len() > data.len()); }
#[test]
fn test_encrypt_aes_gcm_failure() {
let key = [0u8; 32];
let data = b"";
let result = CryptoUtils::encrypt_aes_gcm(data, &key, None);
assert!(result.is_ok());
let encrypted_data = result.unwrap();
assert_eq!(encrypted_data.len(), 12 + 16); }
#[test]
fn test_encrypt_aes_gcm_failure_2() {
let key = [0u8; 32];
let data = b"";
let nonce = [0u8; 12];
let result = CryptoUtils::encrypt_aes_gcm(data, &key, Some(&nonce));
assert!(result.is_ok());
let encrypted_data = result.unwrap();
assert_eq!(encrypted_data.len(), 12 + data.len() + 16);
}
}
#[cfg(test)]
mod decrypt_aes_tests {
use crate::crypto::CryptoUtils;
use rand::Rng;
#[test]
fn test_decrypt_aes_success() {
let key_bytes = [0u8; 32]; let data = b"Hello, world!";
let nonce: [u8; 12] = rand::thread_rng().gen(); let encrypted_data = CryptoUtils::encrypt_aes_gcm(data, &key_bytes, Some(&nonce)).unwrap();
let decrypted_data = CryptoUtils::decrypt_aes(&encrypted_data, &key_bytes).unwrap();
assert_eq!(decrypted_data, data);
}
#[test]
fn test_decrypt_aes_invalid_key_size() {
let invalid_key_bytes = [0u8; 16]; let data = b"Hello, world!";
let nonce: [u8; 12] = rand::thread_rng().gen();
let encrypted_data = CryptoUtils::encrypt_aes_gcm(data, &[0u8; 32], Some(&nonce)).unwrap();
let result = CryptoUtils::decrypt_aes(&encrypted_data, &invalid_key_bytes);
assert!(result.is_err());
assert_eq!(
result.unwrap_err().to_string(),
"Cryptography module Error: Invalid key size"
);
}
#[test]
fn test_decrypt_aes_invalid_data() {
let key_bytes = [0u8; 32]; let invalid_data = b"Invalid data";
let result = CryptoUtils::decrypt_aes(invalid_data, &key_bytes);
assert!(result.is_err());
assert_eq!(
result.unwrap_err().to_string(),
"Cryptography module Error: aead::Error"
);
}
#[test]
fn test_decrypt_aes_empty_data() {
let key_bytes = [0u8; 32];
let result = CryptoUtils::decrypt_aes(b"", &key_bytes);
assert!(result.is_err());
assert_eq!(
result.unwrap_err().to_string(),
"Cryptography module Error: Data too short to contain nonce"
);
}
}
#[cfg(test)]
mod encrypt_aes_cbc_tests {
use crate::crypto::CryptoUtils;
#[test]
fn test_encrypt_aes_cbc() {
let key = b"verysecretkey!!!verysecretkey!!!"; let data = b"Hello, World!";
let encrypted = CryptoUtils::encrypt_aes_cbc(data, key, None).unwrap();
assert_ne!(encrypted, data);
assert!(encrypted.len() > data.len());
}
#[test]
fn test_encrypt_aes_cbc_kd() {
let key = b"\xd6\x98\xc1\xde\x0f\xeb\xdf\xb8C\xbe\x88\x10\xc5.\x17\xf5Pro0[x\x888i[\xe1\xdd\x0f<\xfcm"; let data =
b"~\xf9\xd9\xaa*\xb1\x069\xec\xdei4\x8e['# '\x0c%\x94\xbfm/\xf1Q\xc6\xf3\x89\xef)";
let nonce = b"R\x00\xd2u7\x01\xae\x91\xe5h\x05\x82r\x90\xfc\xaa";
let result_expected =b"R\x00\xd2u7\x01\xae\x91\xe5h\x05\x82r\x90\xfc\xaaX\xcb\xed\n\x91\x7f\xe6\xe6w\xa3\x04z)\xdd[G\xef\xc5\x90\x97\xa5\x9a\x8d\xc8O/\x88\x1f\xe8+\xce,\tQ\xc9-r\x85_\x14\xd1D#\x14\xe1u\x8d\x02";
let encrypted = CryptoUtils::encrypt_aes_cbc(data, key, Some(nonce)).unwrap();
assert!(encrypted.len() > data.len());
assert_eq!(encrypted, result_expected);
assert_eq!(encrypted.len(), result_expected.len());
}
#[test]
fn test_encrypt_with_specific_iv() {
let key = b"verysecretkey!!!verysecretkey!!!"; let data = b"Hello, World!";
let iv = b"uniqueiv12345678";
let encrypted = CryptoUtils::encrypt_aes_cbc(data, key, Some(iv)).unwrap();
assert_ne!(encrypted, data);
assert!(encrypted.len() > data.len());
}
#[test]
fn test_encrypt_empty_data() {
let key = b"verysecretkey!!!verysecretkey!!!";
let data: &[u8] = b"";
let encrypted = CryptoUtils::encrypt_aes_cbc(data, key, None).unwrap();
assert_ne!(encrypted, data);
assert!(encrypted.len() > 0);
}
#[test]
fn test_encrypt_with_invalid_key() {
let key = b"shortkey!"; let data = b"Hello, World!";
let result = CryptoUtils::encrypt_aes_cbc(data, key, None);
assert!(result.is_err());
}
#[test]
fn test_encrypt_large_data() {
let key = b"verysecretkey!!!verysecretkey!!!";
let data =
b"This is a longer piece of data that we are going to encrypt with AES CBC mode.";
let encrypted = CryptoUtils::encrypt_aes_cbc(data, key, None).unwrap();
assert_ne!(encrypted, data);
assert!(encrypted.len() > data.len());
}
#[test]
fn test_encrypt_repeated_calls() {
let key = b"verysecretkey!!!verysecretkey!!!";
let data = b"Hello, World!";
let encrypted1 = CryptoUtils::encrypt_aes_cbc(data, key, None).unwrap();
let encrypted2 = CryptoUtils::encrypt_aes_cbc(data, key, None).unwrap();
assert_ne!(encrypted1, encrypted2);
}
}
#[cfg(test)]
mod decrypt_aes_cbc_tests {
use crate::crypto::{unpad_data, CryptoUtils};
const TEST_KEY: [u8; 32] = [0u8; 32];
#[test]
fn test_decrypt_aes_cbc_valid() {
let key = [
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
0x1C, 0x1D, 0x1E, 0x1F,
];
let iv = [
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
0x0E, 0x0F,
];
let data = b"Hello, World! This is a test!";
let encrypted_data = CryptoUtils::encrypt_aes_cbc(data, &key, Some(&iv)).unwrap();
let decrypted_data = CryptoUtils::decrypt_aes_cbc(&encrypted_data, &key).unwrap();
let unpad_decrypted_data = unpad_data(&decrypted_data).unwrap();
assert_eq!(unpad_decrypted_data, unpad_decrypted_data.to_vec()); }
#[test]
fn test_decrypt_aes_cbc_invalid_key_size() {
let data = b"Hello, World!";
let result = CryptoUtils::decrypt_aes_cbc(data, &[0u8; 16]); assert!(result.is_err());
}
#[test]
fn test_decrypt_aes_cbc_data_too_short() {
let result = CryptoUtils::decrypt_aes_cbc(&[], &TEST_KEY); assert!(result.is_err());
}
#[test]
fn test_decrypt_aes_cbc_invalid_data_length() {
let result = CryptoUtils::decrypt_aes_cbc(b"short", &TEST_KEY); assert!(result.is_err());
}
#[test]
fn test_decrypt_aes_cbc_with_invalid_padding() {
let invalid_padded_data = [0u8; 16]; let result = CryptoUtils::decrypt_aes_cbc(&invalid_padded_data, &TEST_KEY);
assert!(!result.is_err());
}
}
#[cfg(test)]
#[cfg(test)]
mod public_encrypt_tests {
use crate::crypto::CryptoUtils;
use aes_gcm::aead::rand_core;
use p256::ecdsa::SigningKey;
use rand_core::OsRng;
#[test]
fn test_public_encrypt_success() {
let data = b"Hello, world!";
let mut rng = OsRng; let server_private_key = SigningKey::random(&mut rng); let server_public_key = server_private_key.verifying_key().to_encoded_point(false);
let encrypted_result = CryptoUtils::public_encrypt(data, server_public_key.as_ref(), None);
assert!(encrypted_result.is_ok());
let result = encrypted_result.unwrap();
assert!(!result.is_empty()); assert!(result.len() > server_public_key.len()); }
#[test]
fn test_public_encrypt_with_idz() {
let data = b"Hello, world!";
let mut rng = OsRng; let server_private_key = SigningKey::random(&mut rng); let server_public_key = server_private_key.verifying_key().to_encoded_point(false);
let idz = b"additional_data";
let encrypted_result =
CryptoUtils::public_encrypt(data, server_public_key.as_ref(), Some(idz));
assert!(encrypted_result.is_ok());
let result = encrypted_result.unwrap();
assert!(!result.is_empty());
assert!(result.len() > server_public_key.len());
}
#[test]
fn test_public_encrypt_invalid_key() {
let data = b"Hello, world!";
let invalid_public_key = [0u8; 65];
let encrypted_result = CryptoUtils::public_encrypt(data, &invalid_public_key, None);
assert!(encrypted_result.is_err());
}
#[test]
fn test_public_encrypt_empty_data() {
let data = b"";
let mut rng = OsRng; let server_private_key = SigningKey::random(&mut rng); let server_public_key = server_private_key.verifying_key().to_encoded_point(false);
let encrypted_result = CryptoUtils::public_encrypt(data, server_public_key.as_ref(), None);
assert!(encrypted_result.is_ok());
let result = encrypted_result.unwrap();
assert!(!result.is_empty());
}
}
#[cfg(test)]
mod hash_of_string_tests {
use crate::{crypto::CryptoUtils, custom_error::KSMRError};
use sha2::{Digest, Sha256};
#[test]
fn test_valid_base64_string() {
let input = "VGVzdCBkYXRh"; let expected_hash = [
226, 124, 130, 20, 190, 139, 124, 245, 188, 204, 124, 8, 36, 126, 60, 176, 193, 81, 74,
72, 238, 31, 99, 25, 127, 228, 239, 62, 245, 29, 126, 111,
];
let result = CryptoUtils::hash_of_string(input).unwrap();
assert_eq!(result, expected_hash);
}
#[test]
fn test_empty_string() {
let input = ""; let expected_hash = Sha256::digest(b"");
let result = CryptoUtils::hash_of_string(input).unwrap();
assert_eq!(result, expected_hash.to_vec());
}
#[test]
fn test_base64_with_padding() {
let input = "SGVsbG8="; let _expected_hash = Sha256::digest(b"Hello");
let result = CryptoUtils::hash_of_string(input);
assert_eq!(
result,
Err(KSMRError::CryptoError(
"Base64 decoding failed: Invalid padding".to_string()
))
);
}
#[test]
fn test_invalid_base64_string() {
let input = "InvalidBase64@String";
let result = CryptoUtils::hash_of_string(input);
assert!(result.is_err());
}
#[test]
fn test_non_base64_string() {
let input = "Not a Base64 string";
let result = CryptoUtils::hash_of_string(input);
assert!(result.is_err());
}
}
#[cfg(test)]
#[cfg(test)]
mod decrypt_record_tests {
use crate::crypto::CryptoUtils;
use base64::{prelude::BASE64_URL_SAFE_NO_PAD, Engine as _};
#[test]
fn test_decrypt_record_valid_base64() {
let secret_key = CryptoUtils::generate_random_bytes(32); let original_data = b"Hello, World!";
let encrypted_data =
CryptoUtils::encrypt_aes_gcm(original_data, &secret_key, None).unwrap();
let base64_encoded = BASE64_URL_SAFE_NO_PAD.encode(&encrypted_data);
let result = CryptoUtils::decrypt_record(base64_encoded.as_bytes(), &secret_key).unwrap();
assert_eq!(result, "Hello, World!");
}
#[test]
fn test_decrypt_record_invalid_base64() {
let secret_key = CryptoUtils::generate_random_bytes(32); let invalid_base64 = "!!!invalid_base64!!!";
let result = CryptoUtils::decrypt_record(invalid_base64.as_bytes(), &secret_key);
assert!(result.is_err());
}
#[test]
fn test_decrypt_record_raw_bytes() {
let secret_key = CryptoUtils::generate_random_bytes(32); let original_data = b"Raw byte data";
let encrypted_data =
CryptoUtils::encrypt_aes_gcm(original_data, &secret_key, None).unwrap();
let result = CryptoUtils::decrypt_record(&encrypted_data, &secret_key).unwrap();
assert_eq!(result, "Raw byte data");
}
#[test]
fn test_decrypt_record_invalid_utf8() {
let secret_key = CryptoUtils::generate_random_bytes(32); let raw_bytes: Vec<u8> = vec![0, 159, 146, 150]; let encrypted_data = CryptoUtils::encrypt_aes_gcm(&raw_bytes, &secret_key, None).unwrap();
let result = CryptoUtils::decrypt_record(&encrypted_data, &secret_key);
assert!(result.is_err());
}
}
#[cfg(test)]
mod der_base64_private_key_to_private_key_tests {
use crate::{crypto::CryptoUtils, custom_error::KSMRError};
const VALID_DER_BASE64: &str = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgndw7rAhuJt5SxssfKPnP0Z3cO6wIbibeUsbLHyj5z9GhRANCAAQCwRNo15jaVxkYQM8WjMffSWxgT4OyieQ91V5WuAemZKKrV2+fV6No21GQihFs6F8pbYvRfYf8Z8i2wsXKeQW5";
#[test]
fn test_valid_der_base64() {
let result = CryptoUtils::der_base64_private_key_to_private_key(VALID_DER_BASE64);
assert!(result.is_ok());
let private_key = result.unwrap();
println!("{:?}", private_key);
}
#[test]
fn test_invalid_base64() {
let invalid_base64 = "!!!invalid_base64!!!";
let result = CryptoUtils::der_base64_private_key_to_private_key(invalid_base64);
assert!(result.is_err());
}
#[test]
fn test_empty_input() {
let result = CryptoUtils::der_base64_private_key_to_private_key("");
assert!(result.is_err());
assert_eq!(result.unwrap_err().to_string(), "Cryptography module Error: Failed to convert DER to SecretKey: PKCS#8 ASN.1 error: ASN.1 DER message is incomplete: expected 1, actual 0 at DER byte 0");
}
#[test]
fn test_whitespace_input() {
let result = CryptoUtils::der_base64_private_key_to_private_key(" ");
assert!(result.is_err());
assert_eq!(
result,
Err(KSMRError::DecodeError(
"Invalid symbol 32, offset 0.".to_string()
))
);
}
#[test]
fn test_non_base64_chars() {
let non_base64 = "abcde@#%$!"; let result = CryptoUtils::der_base64_private_key_to_private_key(non_base64);
assert!(result.is_err());
assert_eq!(
result,
Err(KSMRError::DecodeError(
"Invalid symbol 64, offset 5.".to_string()
))
);
}
#[test]
fn test_incomplete_base64() {
let incomplete_base64 = "MIIEvQIBADANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQ"; let result = CryptoUtils::der_base64_private_key_to_private_key(incomplete_base64);
assert!(result.is_err());
assert_eq!(
result,
Err(KSMRError::DecodeError("Invalid padding".to_string()))
);
}
#[test]
fn test_large_input() {
let large_base64 = "A".repeat(10000); let result = CryptoUtils::der_base64_private_key_to_private_key(&large_base64);
assert!(result.is_err());
assert_eq!(result,Err(KSMRError::CryptoError("Failed to convert DER to SecretKey: PKCS#8 ASN.1 error: unknown/unsupported ASN.1 DER tag: 0x00".to_string())));
}
#[test]
fn test_valid_der_key_length() {
let valid_length_base64 = VALID_DER_BASE64; let result = CryptoUtils::der_base64_private_key_to_private_key(valid_length_base64);
assert!(result.is_ok());
let private_key = result.unwrap();
println!("{:?}", private_key);
}
#[test]
fn test_invalid_der_key_format() {
let invalid_der_base64 = "MIIBVwIBADANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQ..."; let result = CryptoUtils::der_base64_private_key_to_private_key(invalid_der_base64);
assert!(result.is_err());
assert_eq!(
result,
Err(KSMRError::DecodeError(
"Invalid symbol 46, offset 48.".to_string()
))
);
}
}
#[cfg(test)]
mod extract_public_key_bytes_tests {
use crate::{crypto::CryptoUtils, custom_error::KSMRError};
use base64::{engine::general_purpose::STANDARD, Engine as _};
const VALID_DER_BASE64: &str = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgndw7rAhuJt5SxssfKPnP0Z3cO6wIbibeUsbLHyj5z9GhRANCAAQCwRNo15jaVxkYQM8WjMffSWxgT4OyieQ91V5WuAemZKKrV2+fV6No21GQihFs6F8pbYvRfYf8Z8i2wsXKeQW5";
#[test]
fn test_valid_der_base64() {
let public_key_bytes = CryptoUtils::extract_public_key_bytes(VALID_DER_BASE64);
assert!(public_key_bytes.is_ok());
let bytes = public_key_bytes.unwrap();
assert_eq!(bytes.len(), 65); assert_eq!(bytes[0], 0x04); }
#[test]
fn test_invalid_base64() {
let result = CryptoUtils::extract_public_key_bytes("invalid_base64");
assert!(result.is_err());
assert_eq!(
result,
Err(KSMRError::DecodeError("Invalid padding".to_string()))
);
}
#[test]
fn test_empty_string() {
let result = CryptoUtils::extract_public_key_bytes("");
assert!(result.is_err());
assert_eq!(result.unwrap_err().to_string(), "Cryptography module Error: Failed to load private key: PKCS#8 ASN.1 error: ASN.1 DER message is incomplete: expected 1, actual 0 at DER byte 0");
}
#[test]
fn test_invalid_der_format() {
let invalid_der_base64 = STANDARD.encode(&[0u8; 10]); let result = CryptoUtils::extract_public_key_bytes(&invalid_der_base64);
assert!(result.is_err());
assert_eq!(result.unwrap_err().to_string(), "Cryptography module Error: Failed to load private key: PKCS#8 ASN.1 error: unknown/unsupported ASN.1 DER tag: 0x00");
}
#[test]
fn test_valid_private_key() {
let private_key_der_base64 = VALID_DER_BASE64; let public_key_bytes = CryptoUtils::extract_public_key_bytes(private_key_der_base64);
assert!(public_key_bytes.is_ok());
let bytes = public_key_bytes.unwrap();
assert_eq!(bytes.len(), 65); assert_eq!(bytes[0], 0x04); }
}
#[cfg(test)]
mod sign_tests {
use crate::crypto::CryptoUtils;
use aes_gcm::aead::rand_core;
use ecdsa::VerifyingKey;
use p256::{
ecdsa::{signature::Verifier, SigningKey},
SecretKey,
};
use rand_core::OsRng;
const TEST_DATA: &[u8] = b"test data to sign";
pub fn _public_key_from_private(private_key: &SecretKey) -> VerifyingKey<p256::NistP256> {
let signing_key = SigningKey::from(private_key);
let public_key = VerifyingKey::from(&signing_key);
return public_key;
}
#[test]
fn test_sign_with_valid_private_key() {
let mut rng = OsRng {};
let private_key = SecretKey::random(&mut rng);
let signature = CryptoUtils::sign_data(TEST_DATA, private_key.clone());
assert!(signature.is_ok());
let signature = signature.unwrap();
let signing_key = SigningKey::from(&private_key);
let public_key = VerifyingKey::from(&signing_key);
assert!(public_key.verify(TEST_DATA, &signature).is_ok());
}
#[test]
fn test_sign_with_empty_data() {
let mut rng = OsRng {};
let private_key = SecretKey::random(&mut rng);
let signature = CryptoUtils::sign_data(b"", private_key.clone());
assert!(signature.is_ok());
let signature = signature.unwrap();
let public_key = _public_key_from_private(&private_key);
assert!(public_key.verify(b"", &signature).is_ok());
}
#[test]
fn test_sign_with_large_data() {
let mut rng = OsRng {};
let private_key = SecretKey::random(&mut rng);
let large_data = vec![b'a'; 1000];
let signature = CryptoUtils::sign_data(&large_data, private_key.clone());
assert!(signature.is_ok());
let signature = signature.unwrap();
let public_key = _public_key_from_private(&private_key);
assert!(public_key.verify(&large_data, &signature).is_ok());
}
}