Add basic filename encoding and test on filename

This commit is contained in:
oupson 2022-06-19 21:23:25 +02:00
parent 47e24be8da
commit c4d1c479aa
1 changed files with 59 additions and 4 deletions

View File

@ -1,12 +1,13 @@
use aes::Aes256; use aes::Aes256;
use cipher::{block_padding::Pkcs7, Iv, Key, KeyIvInit}; use cipher::{block_padding::Pkcs7, inout::InOutBufReserved, Iv, Key, KeyIvInit};
use eme_mode::{DynamicEme}; use eme_mode::DynamicEme;
use hkdf::Hkdf; use hkdf::Hkdf;
use crate::error::FilenameDecryptError; use crate::error::FilenameDecryptError;
type EmeCipher = DynamicEme<Aes256>; pub(crate) type EmeCipher = DynamicEme<Aes256>;
// TODO RENAME
pub struct FilenameDecoder { pub struct FilenameDecoder {
filename_key: Key<Aes256>, filename_key: Key<Aes256>,
} }
@ -31,6 +32,7 @@ impl FilenameDecoder {
} }
} }
// TODO RENAME
pub struct DirFilenameDecoder<'a, 'b> { pub struct DirFilenameDecoder<'a, 'b> {
filename_key: &'a Key<EmeCipher>, filename_key: &'a Key<EmeCipher>,
iv: &'b Iv<EmeCipher>, iv: &'b Iv<EmeCipher>,
@ -40,11 +42,64 @@ impl<'a, 'b> DirFilenameDecoder<'a, 'b> {
pub fn decode_filename(&self, name: &str) -> Result<String, FilenameDecryptError> { pub fn decode_filename(&self, name: &str) -> Result<String, FilenameDecryptError> {
let cipher = EmeCipher::new(self.filename_key, self.iv); 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 let filename_decoded = cipher
.decrypt_padded_mut::<Pkcs7>(&mut filename) .decrypt_padded_mut::<Pkcs7>(&mut filename)
.map_err(|_| FilenameDecryptError::DecryptError())?; .map_err(|_| FilenameDecryptError::DecryptError())?;
Ok(String::from_utf8_lossy(filename_decoded).to_string()) Ok(String::from_utf8_lossy(filename_decoded).to_string())
} }
pub fn encrypt_filename(&self, plain_text_name: &str) -> Result<String, FilenameDecryptError> {
let mut cipher = EmeCipher::new(self.filename_key, self.iv);
let mut res = [0u8; 2048];
let filename_encrypted = cipher
.encrypt_padded_inout_mut::<Pkcs7>(
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");
}
} }