use crate::encoder::core::DataEncoder;
use crate::errors::DataParseError;
use crate::options::{EncodingOptions, ParseOptions};
use crate::parser::core::DataParser;
use crate::utils::ParseResult;
use aes::Aes256;
use aes::cipher::block_padding::Pkcs7;
use aes::cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit};
type Aes256CbcEnc = cbc::Encryptor<Aes256>;
type Aes256CbcDec = cbc::Decryptor<Aes256>;
fn map_crypto_err<E: std::fmt::Display>(e: E) -> DataParseError {
DataParseError::CryptoError { e: e.to_string() }
}
pub(crate) fn aes_decrypt(
raw_data: &mut [u8],
key: &[u8],
iv: &[u8],
) -> Result<Vec<u8>, DataParseError> {
let dc = Aes256CbcDec::new_from_slices(key, iv).map_err(map_crypto_err)?;
let pt = dc
.decrypt_padded_mut::<Pkcs7>(raw_data)
.map_err(map_crypto_err)?;
Ok(pt.to_vec())
}
pub(crate) fn aes_encrypt(
raw_data: &mut [u8],
key: &[u8],
iv: &[u8],
) -> Result<Vec<u8>, DataParseError> {
let enc = Aes256CbcEnc::new_from_slices(key, iv).map_err(map_crypto_err)?;
let pt = enc
.encrypt_padded_mut::<Pkcs7>(raw_data, raw_data.len())
.map_err(map_crypto_err)?;
Ok(pt.to_vec())
}
#[cfg(feature = "crypto")]
impl DataParser<'_> {
pub fn encrypt(&mut self) -> ParseResult<()> {
aes_encrypt(&mut self.buffer, &self.options.key, &self.options.iv)?;
Ok(())
}
pub fn decrypt(&mut self) -> ParseResult<()> {
aes_decrypt(&mut self.buffer, &self.options.key, &self.options.iv)?;
Ok(())
}
}
#[cfg(feature = "crypto")]
impl DataEncoder {
pub fn encrypt(&mut self) -> ParseResult<()> {
aes_encrypt(&mut self.buffer, &self.options.key, &self.options.iv)?;
Ok(())
}
pub fn decrypt(&mut self) -> ParseResult<()> {
aes_decrypt(&mut self.buffer, &self.options.key, &self.options.iv)?;
Ok(())
}
}
#[cfg(feature = "crypto")]
impl ParseOptions {
pub fn with_encryption(mut self, key: Vec<u8>, iv: Vec<u8>) -> Self {
self.key = key;
self.iv = iv;
self
}
}
#[cfg(feature = "crypto")]
impl EncodingOptions {
pub fn with_encryption(mut self, key: Vec<u8>, iv: Vec<u8>) -> Self {
self.key = key;
self.iv = iv;
self
}
}