mirror of
https://github.com/sbrow/envr.git
synced 2026-06-28 02:58:33 -04:00
feat: Added age-ffi.
This commit is contained in:
337
zig-vendor/age-ffi/src/tests.rs
Normal file
337
zig-vendor/age-ffi/src/tests.rs
Normal file
@@ -0,0 +1,337 @@
|
||||
//! Tests for the age-ffi library.
|
||||
|
||||
use crate::*;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::os::raw::c_char;
|
||||
|
||||
#[test]
|
||||
fn test_keygen() {
|
||||
let mut keypair = AgeKeypair::null();
|
||||
let result = age_generate_x25519(&mut keypair);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
assert!(!keypair.public_key.is_null());
|
||||
assert!(!keypair.private_key.is_null());
|
||||
|
||||
unsafe {
|
||||
let public = CStr::from_ptr(keypair.public_key).to_str().unwrap();
|
||||
let private = CStr::from_ptr(keypair.private_key).to_str().unwrap();
|
||||
assert!(public.starts_with("age1"));
|
||||
assert!(private.starts_with("AGE-SECRET-KEY-1"));
|
||||
}
|
||||
|
||||
age_free_keypair(&mut keypair);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encrypt_decrypt() {
|
||||
let mut keypair = AgeKeypair::null();
|
||||
age_generate_x25519(&mut keypair);
|
||||
|
||||
let plaintext = b"Hello, world!";
|
||||
let mut encrypted = AgeBuffer::null();
|
||||
|
||||
let result = age_encrypt(
|
||||
plaintext.as_ptr(),
|
||||
plaintext.len(),
|
||||
keypair.public_key,
|
||||
&mut encrypted,
|
||||
);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
assert!(!encrypted.data.is_null());
|
||||
assert!(encrypted.len > 0);
|
||||
|
||||
let mut decrypted = AgeBuffer::null();
|
||||
let result = age_decrypt(
|
||||
encrypted.data,
|
||||
encrypted.len,
|
||||
keypair.private_key,
|
||||
&mut decrypted,
|
||||
);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
|
||||
let decrypted_slice = unsafe { std::slice::from_raw_parts(decrypted.data, decrypted.len) };
|
||||
assert_eq!(decrypted_slice, plaintext);
|
||||
|
||||
age_free_buffer(&mut encrypted);
|
||||
age_free_buffer(&mut decrypted);
|
||||
age_free_keypair(&mut keypair);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_passphrase_encrypt_decrypt() {
|
||||
let plaintext = b"Secret message";
|
||||
let passphrase = CString::new("my-secret-passphrase").unwrap();
|
||||
|
||||
let mut encrypted = AgeBuffer::null();
|
||||
let result = age_encrypt_passphrase(
|
||||
plaintext.as_ptr(),
|
||||
plaintext.len(),
|
||||
passphrase.as_ptr(),
|
||||
false,
|
||||
&mut encrypted,
|
||||
);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
|
||||
let mut decrypted = AgeBuffer::null();
|
||||
let result = age_decrypt_passphrase(
|
||||
encrypted.data,
|
||||
encrypted.len,
|
||||
passphrase.as_ptr(),
|
||||
&mut decrypted,
|
||||
);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
|
||||
let decrypted_slice = unsafe { std::slice::from_raw_parts(decrypted.data, decrypted.len) };
|
||||
assert_eq!(decrypted_slice, plaintext);
|
||||
|
||||
age_free_buffer(&mut encrypted);
|
||||
age_free_buffer(&mut decrypted);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validation() {
|
||||
let invalid = CString::new("not-a-key").unwrap();
|
||||
assert!(!age_is_valid_x25519_recipient(invalid.as_ptr()));
|
||||
|
||||
let mut keypair = AgeKeypair::null();
|
||||
age_generate_x25519(&mut keypair);
|
||||
assert!(age_is_valid_x25519_recipient(keypair.public_key));
|
||||
assert!(age_is_valid_x25519_identity(keypair.private_key));
|
||||
assert_eq!(age_recipient_type(keypair.public_key), 1);
|
||||
age_free_keypair(&mut keypair);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_armor_encrypt_decrypt() {
|
||||
let mut keypair = AgeKeypair::null();
|
||||
age_generate_x25519(&mut keypair);
|
||||
|
||||
let plaintext = b"Armored message";
|
||||
let mut armored: *mut c_char = std::ptr::null_mut();
|
||||
|
||||
let result = age_encrypt_armor(
|
||||
plaintext.as_ptr(),
|
||||
plaintext.len(),
|
||||
keypair.public_key,
|
||||
&mut armored,
|
||||
);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
assert!(!armored.is_null());
|
||||
|
||||
let armored_str = unsafe { CStr::from_ptr(armored).to_str().unwrap() };
|
||||
assert!(armored_str.contains("-----BEGIN AGE ENCRYPTED FILE-----"));
|
||||
|
||||
let mut dearmored = AgeBuffer::null();
|
||||
let result = age_dearmor(armored, &mut dearmored);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
|
||||
let mut decrypted = AgeBuffer::null();
|
||||
let result = age_decrypt(
|
||||
dearmored.data,
|
||||
dearmored.len,
|
||||
keypair.private_key,
|
||||
&mut decrypted,
|
||||
);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
|
||||
let decrypted_slice = unsafe { std::slice::from_raw_parts(decrypted.data, decrypted.len) };
|
||||
assert_eq!(decrypted_slice, plaintext);
|
||||
|
||||
age_free_string(armored);
|
||||
age_free_buffer(&mut dearmored);
|
||||
age_free_buffer(&mut decrypted);
|
||||
age_free_keypair(&mut keypair);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_derive_public_key() {
|
||||
let mut keypair = AgeKeypair::null();
|
||||
age_generate_x25519(&mut keypair);
|
||||
|
||||
let mut derived_public: *mut c_char = std::ptr::null_mut();
|
||||
let result = age_x25519_to_public(keypair.private_key, &mut derived_public);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
|
||||
let original = unsafe { CStr::from_ptr(keypair.public_key).to_str().unwrap() };
|
||||
let derived = unsafe { CStr::from_ptr(derived_public).to_str().unwrap() };
|
||||
assert_eq!(original, derived);
|
||||
|
||||
age_free_string(derived_public);
|
||||
age_free_keypair(&mut keypair);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_recipient_encrypt() {
|
||||
let mut keypair1 = AgeKeypair::null();
|
||||
let mut keypair2 = AgeKeypair::null();
|
||||
age_generate_x25519(&mut keypair1);
|
||||
age_generate_x25519(&mut keypair2);
|
||||
|
||||
let plaintext = b"Message for multiple recipients";
|
||||
let recipients: [*const c_char; 2] = [
|
||||
keypair1.public_key as *const c_char,
|
||||
keypair2.public_key as *const c_char,
|
||||
];
|
||||
let mut encrypted = AgeBuffer::null();
|
||||
|
||||
let result = age_encrypt_multi(
|
||||
plaintext.as_ptr(),
|
||||
plaintext.len(),
|
||||
recipients.as_ptr(),
|
||||
recipients.len(),
|
||||
false,
|
||||
&mut encrypted,
|
||||
);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
|
||||
// Decrypt with first key
|
||||
let mut decrypted1 = AgeBuffer::null();
|
||||
let result = age_decrypt(
|
||||
encrypted.data,
|
||||
encrypted.len,
|
||||
keypair1.private_key,
|
||||
&mut decrypted1,
|
||||
);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
let slice1 = unsafe { std::slice::from_raw_parts(decrypted1.data, decrypted1.len) };
|
||||
assert_eq!(slice1, plaintext);
|
||||
|
||||
// Decrypt with second key
|
||||
let mut decrypted2 = AgeBuffer::null();
|
||||
let result = age_decrypt(
|
||||
encrypted.data,
|
||||
encrypted.len,
|
||||
keypair2.private_key,
|
||||
&mut decrypted2,
|
||||
);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
let slice2 = unsafe { std::slice::from_raw_parts(decrypted2.data, decrypted2.len) };
|
||||
assert_eq!(slice2, plaintext);
|
||||
|
||||
age_free_buffer(&mut encrypted);
|
||||
age_free_buffer(&mut decrypted1);
|
||||
age_free_buffer(&mut decrypted2);
|
||||
age_free_keypair(&mut keypair1);
|
||||
age_free_keypair(&mut keypair2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_version_functions() {
|
||||
let version = age_version();
|
||||
assert!(!version.is_null());
|
||||
let version_str = unsafe { CStr::from_ptr(version).to_str().unwrap() };
|
||||
assert!(!version_str.is_empty());
|
||||
|
||||
let lib_version = age_lib_version();
|
||||
assert!(!lib_version.is_null());
|
||||
let lib_version_str = unsafe { CStr::from_ptr(lib_version).to_str().unwrap() };
|
||||
assert!(lib_version_str.starts_with("0.11"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_passphrase_with_armor() {
|
||||
let plaintext = b"Armored passphrase message";
|
||||
let passphrase = CString::new("test-passphrase-123").unwrap();
|
||||
|
||||
let mut encrypted = AgeBuffer::null();
|
||||
let result = age_encrypt_passphrase(
|
||||
plaintext.as_ptr(),
|
||||
plaintext.len(),
|
||||
passphrase.as_ptr(),
|
||||
true, // armor = true
|
||||
&mut encrypted,
|
||||
);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
|
||||
// Verify it's armored
|
||||
let encrypted_slice = unsafe { std::slice::from_raw_parts(encrypted.data, encrypted.len) };
|
||||
let encrypted_str = std::str::from_utf8(encrypted_slice).unwrap();
|
||||
assert!(encrypted_str.contains("-----BEGIN AGE ENCRYPTED FILE-----"));
|
||||
|
||||
// Dearmor first, then decrypt
|
||||
let armored_cstr = CString::new(encrypted_str).unwrap();
|
||||
let mut dearmored = AgeBuffer::null();
|
||||
let result = age_dearmor(armored_cstr.as_ptr(), &mut dearmored);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
|
||||
let mut decrypted = AgeBuffer::null();
|
||||
let result = age_decrypt_passphrase(
|
||||
dearmored.data,
|
||||
dearmored.len,
|
||||
passphrase.as_ptr(),
|
||||
&mut decrypted,
|
||||
);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
|
||||
let decrypted_slice = unsafe { std::slice::from_raw_parts(decrypted.data, decrypted.len) };
|
||||
assert_eq!(decrypted_slice, plaintext);
|
||||
|
||||
age_free_buffer(&mut encrypted);
|
||||
age_free_buffer(&mut dearmored);
|
||||
age_free_buffer(&mut decrypted);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_plaintext() {
|
||||
let mut keypair = AgeKeypair::null();
|
||||
age_generate_x25519(&mut keypair);
|
||||
|
||||
let plaintext = b"";
|
||||
let mut encrypted = AgeBuffer::null();
|
||||
|
||||
let result = age_encrypt(
|
||||
plaintext.as_ptr(),
|
||||
plaintext.len(),
|
||||
keypair.public_key,
|
||||
&mut encrypted,
|
||||
);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
|
||||
let mut decrypted = AgeBuffer::null();
|
||||
let result = age_decrypt(
|
||||
encrypted.data,
|
||||
encrypted.len,
|
||||
keypair.private_key,
|
||||
&mut decrypted,
|
||||
);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
assert_eq!(decrypted.len, 0);
|
||||
|
||||
age_free_buffer(&mut encrypted);
|
||||
age_free_buffer(&mut decrypted);
|
||||
age_free_keypair(&mut keypair);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_large_plaintext() {
|
||||
let mut keypair = AgeKeypair::null();
|
||||
age_generate_x25519(&mut keypair);
|
||||
|
||||
// 1MB of data
|
||||
let plaintext: Vec<u8> = (0..1024 * 1024).map(|i| (i % 256) as u8).collect();
|
||||
let mut encrypted = AgeBuffer::null();
|
||||
|
||||
let result = age_encrypt(
|
||||
plaintext.as_ptr(),
|
||||
plaintext.len(),
|
||||
keypair.public_key,
|
||||
&mut encrypted,
|
||||
);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
|
||||
let mut decrypted = AgeBuffer::null();
|
||||
let result = age_decrypt(
|
||||
encrypted.data,
|
||||
encrypted.len,
|
||||
keypair.private_key,
|
||||
&mut decrypted,
|
||||
);
|
||||
assert_eq!(result, AgeResult::Success);
|
||||
|
||||
let decrypted_slice = unsafe { std::slice::from_raw_parts(decrypted.data, decrypted.len) };
|
||||
assert_eq!(decrypted_slice, plaintext.as_slice());
|
||||
|
||||
age_free_buffer(&mut encrypted);
|
||||
age_free_buffer(&mut decrypted);
|
||||
age_free_keypair(&mut keypair);
|
||||
}
|
||||
Reference in New Issue
Block a user