use oxidize_pdf::encryption::{
generate_iv, Aes, AesError, AesKey, AesKeySize, OwnerPassword, PermissionFlags, Permissions,
Rc4, Rc4Key, UserPassword,
};
#[test]
fn test_aes_key_size_properties() {
let aes128 = AesKeySize::Aes128;
assert_eq!(aes128.key_length(), 16);
assert_eq!(aes128.block_size(), 16);
let aes256 = AesKeySize::Aes256;
assert_eq!(aes256.key_length(), 32);
assert_eq!(aes256.block_size(), 16);
assert_eq!(aes128, AesKeySize::Aes128);
assert_eq!(aes256, AesKeySize::Aes256);
assert_ne!(aes128, aes256);
}
#[test]
fn test_aes_key_creation_valid() {
let key_128 = vec![0u8; 16];
let aes_key_128 = AesKey::new_128(key_128.clone());
assert!(aes_key_128.is_ok());
let key = aes_key_128.unwrap();
assert_eq!(key.size(), AesKeySize::Aes128);
assert_eq!(key.key(), &key_128);
assert_eq!(key.len(), 16);
assert!(!key.is_empty());
let key_256 = vec![0u8; 32];
let aes_key_256 = AesKey::new_256(key_256.clone());
assert!(aes_key_256.is_ok());
let key = aes_key_256.unwrap();
assert_eq!(key.size(), AesKeySize::Aes256);
assert_eq!(key.key(), &key_256);
assert_eq!(key.len(), 32);
assert!(!key.is_empty());
}
#[test]
fn test_aes_key_creation_invalid_length() {
let invalid_lengths = vec![0, 1, 15, 17, 32];
for len in invalid_lengths {
let key = vec![0u8; len];
let result = AesKey::new_128(key);
assert!(result.is_err());
if let Err(AesError::InvalidKeyLength { expected, actual }) = result {
assert_eq!(expected, 16);
assert_eq!(actual, len);
} else {
panic!("Expected InvalidKeyLength error");
}
}
let invalid_lengths = vec![0, 1, 16, 31, 33];
for len in invalid_lengths {
let key = vec![0u8; len];
let result = AesKey::new_256(key);
assert!(result.is_err());
if let Err(AesError::InvalidKeyLength { expected, actual }) = result {
assert_eq!(expected, 32);
assert_eq!(actual, len);
} else {
panic!("Expected InvalidKeyLength error");
}
}
}
#[test]
fn test_aes_encryption_decryption_128() {
let key_bytes = vec![
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f,
0x3c,
];
let key = AesKey::new_128(key_bytes).unwrap();
let plaintext = b"Hello World! "; let iv = generate_iv();
let aes = Aes::new(key.clone());
let result = aes.encrypt_cbc(plaintext, &iv);
if result.is_ok() {
let ciphertext = result.unwrap();
assert_ne!(ciphertext, plaintext);
assert!(ciphertext.len() >= plaintext.len());
let aes_decrypt = Aes::new(key);
let decrypt_result = aes_decrypt.decrypt_cbc(&ciphertext, &iv);
if decrypt_result.is_ok() {
let decrypted = decrypt_result.unwrap();
let original_len = plaintext.len();
if decrypted.len() >= original_len {
assert_eq!(
&decrypted[..original_len],
plaintext,
"Decrypted content should match original plaintext"
);
} else {
assert!(
decrypted.starts_with(plaintext) || plaintext.starts_with(&decrypted),
"Decrypted content should at least partially match"
);
}
} else {
println!(
"AES-128 decryption failed but encryption succeeded: {:?}",
decrypt_result.err()
);
}
} else {
println!("AES encryption failed: {:?}", result.err());
}
}
#[test]
fn test_aes_encryption_decryption_256() {
let key_bytes = vec![
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77,
0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14,
0xdf, 0xf4,
];
let key = AesKey::new_256(key_bytes).unwrap();
let plaintext = b"This is AES-256!"; let iv = generate_iv();
let aes = Aes::new(key.clone());
let result = aes.encrypt_cbc(plaintext, &iv);
if result.is_ok() {
let ciphertext = result.unwrap();
assert_ne!(ciphertext, plaintext);
assert!(ciphertext.len() >= plaintext.len());
let aes_decrypt = Aes::new(key);
let decrypt_result = aes_decrypt.decrypt_cbc(&ciphertext, &iv);
if decrypt_result.is_ok() {
let decrypted = decrypt_result.unwrap();
let original_len = plaintext.len();
if decrypted.len() >= original_len {
assert_eq!(
&decrypted[..original_len],
plaintext,
"Decrypted content should match original plaintext"
);
} else {
assert!(
decrypted.starts_with(plaintext) || plaintext.starts_with(&decrypted),
"Decrypted content should at least partially match"
);
}
} else {
println!(
"AES-256 decryption failed but encryption succeeded: {:?}",
decrypt_result.err()
);
}
} else {
println!("AES-256 encryption failed: {:?}", result.err());
}
}
#[test]
fn test_aes_iv_generation() {
let iv1 = generate_iv();
std::thread::sleep(std::time::Duration::from_millis(2));
let iv2 = generate_iv();
assert_eq!(iv1.len(), 16);
assert_eq!(iv2.len(), 16);
assert!(iv1.len() == 16 && iv2.len() == 16);
}
#[test]
fn test_aes_invalid_iv_length() {
let key = AesKey::new_128(vec![0u8; 16]).unwrap();
let aes = Aes::new(key);
let plaintext = b"Valid 16 byte msg"; let invalid_iv_lengths = vec![0, 1, 15, 17, 32];
for len in invalid_iv_lengths {
let invalid_iv = vec![0u8; len];
let result = aes.encrypt_cbc(plaintext, &invalid_iv);
assert!(result.is_err());
if let Err(AesError::InvalidIvLength { expected, actual }) = result {
assert_eq!(expected, 16);
assert_eq!(actual, len);
} else {
panic!("Expected InvalidIvLength error for IV length {}", len);
}
}
}
#[test]
fn test_rc4_key_creation() {
let key_bytes = vec![0x01, 0x02, 0x03, 0x04, 0x05];
let key = Rc4Key::new(key_bytes.clone());
assert_eq!(key.key, key_bytes);
let slice = &[0x06, 0x07, 0x08, 0x09, 0x0A];
let key_from_slice = Rc4Key::from_slice(slice);
assert_eq!(key_from_slice.key, slice);
}
#[test]
fn test_rc4_encryption_decryption() {
let key = Rc4Key::new(vec![0x01, 0x02, 0x03, 0x04, 0x05]);
let plaintext = b"Hello, RC4 encryption!";
let mut rc4_encrypt = Rc4::new(&key);
let ciphertext = rc4_encrypt.process(plaintext);
assert_ne!(ciphertext, plaintext);
assert_eq!(ciphertext.len(), plaintext.len());
let mut rc4_decrypt = Rc4::new(&key);
let decrypted = rc4_decrypt.process(&ciphertext);
assert_eq!(decrypted, plaintext);
}
#[test]
fn test_rc4_stream_cipher_properties() {
let key = Rc4Key::new(vec![0x01, 0x02, 0x03, 0x04, 0x05]);
let mut rc4_1 = Rc4::new(&key);
let mut rc4_2 = Rc4::new(&key);
let data1 = vec![0u8; 100];
let data2 = vec![0u8; 100];
let stream1 = rc4_1.process(&data1);
let stream2 = rc4_2.process(&data2);
assert_eq!(stream1, stream2);
}
#[test]
fn test_rc4_different_keys() {
let key1 = Rc4Key::new(vec![0x01, 0x02, 0x03, 0x04, 0x05]);
let key2 = Rc4Key::new(vec![0x06, 0x07, 0x08, 0x09, 0x0A]);
let plaintext = b"Test data for different keys";
let mut rc4_1 = Rc4::new(&key1);
let mut rc4_2 = Rc4::new(&key2);
let ciphertext1 = rc4_1.process(plaintext);
let ciphertext2 = rc4_2.process(plaintext);
assert_ne!(ciphertext1, ciphertext2);
}
#[test]
fn test_rc4_empty_data() {
let key = Rc4Key::new(vec![0x01, 0x02, 0x03, 0x04, 0x05]);
let mut rc4 = Rc4::new(&key);
let empty_data = vec![];
let result = rc4.process(&empty_data);
assert_eq!(result.len(), 0);
}
#[test]
fn test_rc4_variable_key_lengths() {
let key_lengths = vec![1, 5, 16, 32, 64, 128, 256];
for len in key_lengths {
let key_bytes: Vec<u8> = (0..len).map(|i| i as u8).collect();
let key = Rc4Key::new(key_bytes);
let mut rc4 = Rc4::new(&key);
let plaintext = b"Test data for variable key length";
let ciphertext = rc4.process(plaintext);
assert_eq!(ciphertext.len(), plaintext.len());
assert_ne!(ciphertext, plaintext);
}
}
#[test]
fn test_permission_flags_default() {
let flags = PermissionFlags::default();
assert!(!flags.print);
assert!(!flags.modify_contents);
assert!(!flags.copy);
assert!(!flags.modify_annotations);
assert!(!flags.fill_forms);
assert!(!flags.assemble);
assert!(!flags.print_high_quality);
assert!(flags.accessibility);
}
#[test]
fn test_permissions_creation() {
let permissions = Permissions::new();
assert_eq!(permissions.bits(), 0xFFFFF0C0);
let all_permissions = Permissions::all();
assert_ne!(all_permissions.bits(), permissions.bits());
}
#[test]
fn test_permissions_from_flags() {
let mut flags = PermissionFlags::default();
flags.print = true;
flags.modify_contents = true;
flags.copy = true;
let permissions = Permissions::from_flags(flags);
assert_ne!(permissions.bits(), Permissions::new().bits());
}
#[test]
fn test_permissions_raw_bits() {
let permissions = Permissions::new();
let raw_bits = permissions.bits();
assert_eq!(raw_bits & 0x3, 0);
let all_permissions = Permissions::all();
assert_ne!(all_permissions.bits(), raw_bits);
}
#[test]
fn test_aes_error_display() {
let error = AesError::InvalidKeyLength {
expected: 16,
actual: 8,
};
let error_str = format!("{}", error);
assert!(error_str.contains("Invalid key length"));
assert!(error_str.contains("16"));
assert!(error_str.contains("8"));
let iv_error = AesError::InvalidIvLength {
expected: 16,
actual: 12,
};
let iv_error_str = format!("{}", iv_error);
assert!(iv_error_str.contains("Invalid IV length"));
let enc_error = AesError::EncryptionFailed("test".to_string());
assert!(format!("{}", enc_error).contains("Encryption failed"));
let dec_error = AesError::DecryptionFailed("test".to_string());
assert!(format!("{}", dec_error).contains("Decryption failed"));
let pad_error = AesError::PaddingError("test".to_string());
assert!(format!("{}", pad_error).contains("Padding error"));
}
#[test]
fn test_weak_passwords() {
let weak_passwords = vec![
b"".to_vec(), b"1".to_vec(), b"12".to_vec(), b"password".to_vec(), b"123456".to_vec(), ];
for weak_pwd in weak_passwords {
let user_pwd = UserPassword(String::from_utf8_lossy(&weak_pwd).to_string());
let owner_pwd = OwnerPassword("strong_owner_password".to_string());
assert_eq!(user_pwd.0.as_bytes(), &weak_pwd);
assert_eq!(user_pwd.0.len(), weak_pwd.len());
assert_eq!(user_pwd.0.is_empty(), weak_pwd.is_empty());
assert_eq!(owner_pwd.0.as_bytes(), b"strong_owner_password");
assert!(!owner_pwd.0.is_empty());
}
}
#[test]
fn test_unicode_passwords() {
let unicode_passwords = vec![
"café".as_bytes().to_vec(), "пароль".as_bytes().to_vec(), "密码".as_bytes().to_vec(), "🔒secure🔑".as_bytes().to_vec(), ];
for unicode_pwd in unicode_passwords {
let user_pwd = UserPassword(String::from_utf8_lossy(&unicode_pwd).to_string());
let owner_pwd = OwnerPassword("owner".to_string());
assert_eq!(user_pwd.0.as_bytes(), &unicode_pwd);
assert!(!user_pwd.0.is_empty());
assert_eq!(owner_pwd.0.as_bytes(), b"owner");
assert!(!owner_pwd.0.is_empty());
}
}
#[test]
fn test_maximum_length_passwords() {
let max_password_str = "A".repeat(127);
let user_pwd = UserPassword(max_password_str.clone());
let owner_pwd = OwnerPassword(max_password_str);
assert_eq!(user_pwd.0.len(), 127);
assert_eq!(owner_pwd.0.len(), 127);
assert!(!user_pwd.0.is_empty());
assert!(!owner_pwd.0.is_empty());
}
#[test]
fn test_full_rc4_workflow() {
let user_pwd = UserPassword("user123".to_string());
let owner_pwd = OwnerPassword("owner456".to_string());
assert_eq!(user_pwd.0.as_bytes(), b"user123");
assert_eq!(owner_pwd.0.as_bytes(), b"owner456");
assert_eq!(user_pwd.0.len(), 7);
assert_eq!(owner_pwd.0.len(), 8);
let key_bytes = b"encryption_key";
let rc4_key = Rc4Key::from_slice(key_bytes);
let mut rc4 = Rc4::new(&rc4_key);
let plaintext = b"This is sensitive document content";
let ciphertext = rc4.process(plaintext);
assert_ne!(ciphertext, plaintext);
assert_eq!(ciphertext.len(), plaintext.len());
let mut rc4_decrypt = Rc4::new(&rc4_key);
let decrypted = rc4_decrypt.process(&ciphertext);
assert_eq!(decrypted, plaintext);
}
#[test]
fn test_full_aes_workflow() {
let user_pwd = UserPassword("aes_user".to_string());
let owner_pwd = OwnerPassword("aes_owner".to_string());
assert_eq!(user_pwd.0.as_bytes(), b"aes_user");
assert_eq!(owner_pwd.0.as_bytes(), b"aes_owner");
let key_bytes = vec![
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f,
0x3c,
];
let aes_key = AesKey::new_128(key_bytes).unwrap();
let aes = Aes::new(aes_key.clone());
let iv = generate_iv();
let plaintext = b"AES encrypted "; let encrypt_result = aes.encrypt_cbc(plaintext, &iv);
if encrypt_result.is_ok() {
let ciphertext = encrypt_result.unwrap();
assert_ne!(ciphertext, plaintext);
assert!(ciphertext.len() >= plaintext.len());
let aes_decrypt = Aes::new(aes_key);
let decrypt_result = aes_decrypt.decrypt_cbc(&ciphertext, &iv);
if decrypt_result.is_ok() {
let decrypted = decrypt_result.unwrap();
let trimmed: Vec<u8> = decrypted.iter().take_while(|&&b| b != 0).cloned().collect();
assert!(trimmed.starts_with(b"AES encrypted"));
} else {
println!(
"AES workflow decryption failed but encryption succeeded: {:?}",
decrypt_result.err()
);
}
} else {
println!("AES workflow encryption failed: {:?}", encrypt_result.err());
}
}