shadow_crypt_core/v2/
file.rs1use crate::{
2 errors::{FileError, HeaderError},
3 file::PlaintextFile,
4 memory::SecureKey,
5 v2::crypt,
6};
7
8use super::header::{AadPurpose, FileHeader, HeaderBinding};
9
10#[derive(Debug)]
12pub struct EncryptedFile {
13 header: FileHeader,
14 ciphertext: Vec<u8>,
15}
16
17impl EncryptedFile {
18 pub fn new(header: FileHeader, ciphertext: Vec<u8>) -> Self {
19 Self { header, ciphertext }
20 }
21
22 pub fn seal(
32 plaintext_file: &PlaintextFile,
33 key: &SecureKey,
34 kdf_params: super::key::KeyDerivationParams,
35 salt: [u8; 16],
36 content_nonce: [u8; 24],
37 filename_nonce: [u8; 24],
38 ) -> Result<Self, FileError> {
39 let binding = HeaderBinding::new(&salt, &kdf_params, &content_nonce, &filename_nonce);
40
41 let (filename_ciphertext, _) = crypt::encrypt_bytes(
42 plaintext_file.filename().as_str().as_bytes(),
43 key.as_bytes(),
44 &filename_nonce,
45 &binding.aad(AadPurpose::Filename),
46 )?;
47
48 let (content_ciphertext, _) = crypt::encrypt_bytes(
49 plaintext_file.content().as_slice(),
50 key.as_bytes(),
51 &content_nonce,
52 &binding.aad(AadPurpose::Content),
53 )?;
54
55 let header = FileHeader::new(
56 salt,
57 kdf_params,
58 content_nonce,
59 filename_nonce,
60 filename_ciphertext,
61 )?;
62
63 Ok(Self::new(header, content_ciphertext))
64 }
65
66 pub fn from_bytes(bytes: &[u8]) -> Result<Self, HeaderError> {
68 let header = FileHeader::try_deserialize(bytes)?;
69 let ciphertext = bytes[header.header_length()..].to_vec();
70
71 Ok(Self::new(header, ciphertext))
72 }
73
74 pub fn to_bytes(&self) -> Vec<u8> {
76 let mut bytes = self.header.serialize();
77 bytes.extend_from_slice(&self.ciphertext);
78 bytes
79 }
80
81 pub fn decrypt(&self, key: &SecureKey) -> Result<PlaintextFile, FileError> {
84 let filename = self.header.decrypt_filename(key)?;
85 let content = self.header.decrypt_content(&self.ciphertext, key)?;
86
87 Ok(PlaintextFile::new(filename, content))
88 }
89
90 pub fn header(&self) -> &FileHeader {
91 &self.header
92 }
93 pub fn ciphertext(&self) -> &[u8] {
94 &self.ciphertext
95 }
96}