From 648bf7457156f7364b13e4db3107143db4214648 Mon Sep 17 00:00:00 2001 From: oupson Date: Mon, 10 Oct 2022 14:37:59 +0200 Subject: [PATCH] Add test for content enc --- rustcryptfs-lib/src/content/mod.rs | 45 +++++++++++++++++++++++++++++ test-data/test.bin | Bin 0 -> 22738 bytes 2 files changed, 45 insertions(+) create mode 100644 test-data/test.bin diff --git a/rustcryptfs-lib/src/content/mod.rs b/rustcryptfs-lib/src/content/mod.rs index f5d1811..561c255 100644 --- a/rustcryptfs-lib/src/content/mod.rs +++ b/rustcryptfs-lib/src/content/mod.rs @@ -91,6 +91,10 @@ impl ContentEnc { #[cfg(test)] mod test { + use std::io::{Cursor, Read}; + + use sha2::{Sha256, Digest}; + use super::ContentEnc; #[test] @@ -105,4 +109,45 @@ mod test { assert_eq!(real_size, ContentEnc::get_real_size(encrypted_size)); } } + + #[test] + fn test_decrypt_empty_file() { + let content = include_bytes!( + concat!(env!("CARGO_MANIFEST_DIR"), + "/../test-data/test.bin")); + let master_key = base64::decode("9gtUW9XiiefEgEXEkbONI6rnUsd2yh5UZZLG0V8Bxgk=").unwrap(); + let file_cipher = ContentEnc::new(&master_key, 16).unwrap(); + + let res = file_cipher.decrypt_block(&[], 1, None).expect("Failed to decrypt empty block"); + assert_eq!(res, Vec::::new()); + + let mut reader= Cursor::new(content); + + let mut hasher = Sha256::new(); + + + let mut buf = [0u8; 18]; + let n = reader.read(&mut buf).unwrap(); + let id = if n < 18 { None } else { Some(&buf[2..]) }; + + let mut buf = [0u8; 4096 + 32]; + + let mut block_index = 0; + loop { + let n = reader.read(&mut buf).unwrap(); + let res = file_cipher.decrypt_block(&buf[..n], block_index, id).unwrap(); + + hasher.update(&res); + + if res.is_empty() { + break; + } + + block_index += 1; + } + + let checksum = base64::encode_config(hasher.finalize(), base64::URL_SAFE); + + assert_eq!(checksum, "YKLFv04l2iqHo3hyObExyj7eURrtJry2T227YQ1pcEg="); + } } diff --git a/test-data/test.bin b/test-data/test.bin new file mode 100644 index 0000000000000000000000000000000000000000..41cc03efb5a2e57a91be8004f383d5f6d41eb0ad GIT binary patch literal 22738 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 literal 0 HcmV?d00001