test(core): integration tests for attachments (round-trip, AID, caps)
Also derives Debug on EncryptedAttachment (required by the test's panic arm). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -46,6 +46,7 @@ use crate::crypto::{decrypt, encrypt};
|
||||
use crate::error::{IdfotoError, Result};
|
||||
|
||||
/// Encrypted attachment with the AID derived from plaintext content.
|
||||
#[derive(Debug)]
|
||||
pub struct EncryptedAttachment {
|
||||
pub id: AttachmentId,
|
||||
pub bytes: Vec<u8>,
|
||||
|
||||
52
crates/idfoto-core/tests/attachments.rs
Normal file
52
crates/idfoto-core/tests/attachments.rs
Normal file
@@ -0,0 +1,52 @@
|
||||
//! Attachment encrypt/decrypt + content-addressed AID + cap enforcement.
|
||||
|
||||
use idfoto_core::{
|
||||
AttachmentId, IdfotoError,
|
||||
crypto::KdfParams,
|
||||
decrypt_attachment, derive_master_key, encrypt_attachment,
|
||||
};
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
fn fast_params() -> KdfParams { KdfParams { argon2_m: 256, argon2_t: 1, argon2_p: 1 } }
|
||||
|
||||
fn make_key() -> Zeroizing<[u8; 32]> {
|
||||
derive_master_key(b"x", &[0u8; 32], &[0u8; 32], &fast_params()).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn attachment_round_trip_5kb() {
|
||||
let plaintext: Vec<u8> = (0..5000u32).map(|i| (i & 0xff) as u8).collect();
|
||||
let key = make_key();
|
||||
let enc = encrypt_attachment(&plaintext, &key, 10 * 1024 * 1024).unwrap();
|
||||
assert_eq!(enc.id, AttachmentId::from_plaintext(&plaintext));
|
||||
|
||||
let dec = decrypt_attachment(&enc.bytes, &key).unwrap();
|
||||
assert_eq!(&*dec, &plaintext);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn identical_plaintexts_yield_identical_aids() {
|
||||
let plaintext = b"hello world";
|
||||
let key = make_key();
|
||||
let a = encrypt_attachment(plaintext, &key, 1024).unwrap();
|
||||
let b = encrypt_attachment(plaintext, &key, 1024).unwrap();
|
||||
assert_eq!(a.id, b.id);
|
||||
// (Bytes will differ because nonce is random per-encryption — that's expected.)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cap_enforcement_at_exact_max() {
|
||||
let plaintext = vec![0u8; 1024];
|
||||
let key = make_key();
|
||||
// Exactly at max — should pass
|
||||
let _ = encrypt_attachment(&plaintext, &key, 1024).unwrap();
|
||||
// One byte over — should fail
|
||||
let err = encrypt_attachment(&plaintext, &key, 1023);
|
||||
match err {
|
||||
Err(IdfotoError::AttachmentTooLarge { size, max }) => {
|
||||
assert_eq!(size, 1024);
|
||||
assert_eq!(max, 1023);
|
||||
}
|
||||
other => panic!("expected AttachmentTooLarge, got {other:?}"),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user