diff --git a/rustcryptfs-lib/src/filename.rs b/rustcryptfs-lib/src/filename.rs index 7477699..275d514 100644 --- a/rustcryptfs-lib/src/filename.rs +++ b/rustcryptfs-lib/src/filename.rs @@ -1,12 +1,13 @@ use aes::Aes256; -use cipher::{block_padding::Pkcs7, Iv, Key, KeyIvInit}; -use eme_mode::{DynamicEme}; +use cipher::{block_padding::Pkcs7, inout::InOutBufReserved, Iv, Key, KeyIvInit}; +use eme_mode::DynamicEme; use hkdf::Hkdf; use crate::error::FilenameDecryptError; -type EmeCipher = DynamicEme; +pub(crate) type EmeCipher = DynamicEme; +// TODO RENAME pub struct FilenameDecoder { filename_key: Key, } @@ -31,6 +32,7 @@ impl FilenameDecoder { } } +// TODO RENAME pub struct DirFilenameDecoder<'a, 'b> { filename_key: &'a Key, iv: &'b Iv, @@ -40,11 +42,64 @@ impl<'a, 'b> DirFilenameDecoder<'a, 'b> { pub fn decode_filename(&self, name: &str) -> Result { let cipher = EmeCipher::new(self.filename_key, self.iv); - let mut filename = base64::decode_config(name, base64::URL_SAFE)?; + let mut filename = base64::decode_config(name, base64::URL_SAFE_NO_PAD)?; let filename_decoded = cipher .decrypt_padded_mut::(&mut filename) .map_err(|_| FilenameDecryptError::DecryptError())?; Ok(String::from_utf8_lossy(filename_decoded).to_string()) } + + pub fn encrypt_filename(&self, plain_text_name: &str) -> Result { + let mut cipher = EmeCipher::new(self.filename_key, self.iv); + let mut res = [0u8; 2048]; + + let filename_encrypted = cipher + .encrypt_padded_inout_mut::( + InOutBufReserved::from_slices(plain_text_name.as_bytes(), &mut res).unwrap(), + ) + .map_err(|_| FilenameDecryptError::DecryptError())?; // TODO RENAME ERROR + + // TODO LONG FILENAME + + Ok(base64::encode_config( + filename_encrypted, + base64::URL_SAFE_NO_PAD, + )) + } +} + +#[cfg(test)] +mod test { + use super::FilenameDecoder; + + #[test] + fn test_encrypt() { + let master_key = base64::decode("9gtUW9XiiefEgEXEkbONI6rnUsd2yh5UZZLG0V8Bxgk=").unwrap(); + let dir_iv = base64::decode("6ysCeWOp2euF1x39gth8KQ==").unwrap(); + + let decoder = FilenameDecoder::new(&master_key).expect("Failed to get file decoder"); + let dir_decoder = decoder.get_decoder_for_dir(&dir_iv); + + let encoded = dir_decoder + .encrypt_filename("7.mp4") + .expect("Failed to encrypt filename"); + + assert_eq!(encoded, "vTBajRt-yCpxB7Sly0E7lQ"); + } + + #[test] + fn test_decrypt() { + let master_key = base64::decode("9gtUW9XiiefEgEXEkbONI6rnUsd2yh5UZZLG0V8Bxgk=").unwrap(); + let dir_iv = base64::decode("6ysCeWOp2euF1x39gth8KQ==").unwrap(); + + let decoder = FilenameDecoder::new(&master_key).expect("Failed to get file decoder"); + let dir_decoder = decoder.get_decoder_for_dir(&dir_iv); + + let decrypted = dir_decoder + .decode_filename("vTBajRt-yCpxB7Sly0E7lQ") + .expect("Failed to decrypt filename"); + + assert_eq!(decrypted, "7.mp4"); + } }