#[macro_use]
extern crate serde_derive;
extern crate bincode;
extern crate crypto;
extern crate rand;
use crypto::buffer::{BufferResult, ReadBuffer, WriteBuffer};
use crypto::{aes, blockmodes, buffer};
use rand::rngs::OsRng;
use rand::Rng;
use std::error;
const BUFFER_SIZE: usize = 8192;
const KEY_LEN: usize = 32;
const IV_LEN: usize = 16;
#[derive(Serialize, Deserialize)]
pub struct EncryptedData(Vec<u8>);
#[derive(Serialize, Deserialize)]
pub struct IV(Vec<u8>);
pub struct Key(Vec<u8>);
pub struct BincodeCryptor {
key: Key,
}
#[derive(Serialize, Deserialize)]
enum CryptorStrategy<T> {
AES256CBC(T),
}
pub enum CryptorError {
InvalidKeySize,
}
#[derive(Serialize, Deserialize)]
struct SerializedResult {
iv: Option<IV>,
encrypted_data: CryptorStrategy<EncryptedData>,
}
pub fn with_key(key: Key) -> BincodeCryptor {
BincodeCryptor { key }
}
impl BincodeCryptor {
pub fn serialize<T: ?Sized>(&self, value: &T) -> Result<Vec<u8>, Box<error::Error>>
where
T: serde::Serialize,
{
let iv = random_iv()?;
let bincoded_value = bincode::serialize(value)?;
let encrypted_value = encrypt(bincoded_value.as_slice(), &self.key, &iv)?;
let encrypted_data = CryptorStrategy::AES256CBC(EncryptedData(encrypted_value));
let iv = Some(iv);
let serialized_result = SerializedResult { iv, encrypted_data };
let result = bincode::serialize(&serialized_result)?;
Ok(result)
}
pub fn deserialize<'a, T>(&'a self, bytes: &'a mut Vec<u8>) -> Result<T, Box<error::Error>>
where
T: serde::de::Deserialize<'a>,
{
let serialized_result: SerializedResult = bincode::deserialize(&bytes[..])?;
let CryptorStrategy::AES256CBC(encrypted_data) = serialized_result.encrypted_data;
let iv = serialized_result.iv.unwrap();
let decrypted_data = decrypt(&encrypted_data.0.as_slice(), &self.key, &iv)?;
bytes.clear();
bytes.extend_from_slice(decrypted_data.as_slice());
Ok(bincode::deserialize(&bytes[..])?)
}
}
pub fn random_key() -> Result<Key, Box<error::Error>> {
let mut key = vec![0; KEY_LEN];
let mut rng = OsRng::new()?;
rng.fill(&mut key[..]);
Ok(Key(key))
}
pub fn create_key(key_bytes: Vec<u8>) -> Result<Key, CryptorError> {
if key_bytes.len() != KEY_LEN {
return Err(CryptorError::InvalidKeySize);
}
Ok(Key(key_bytes))
}
fn random_iv() -> Result<IV, Box<error::Error>> {
let mut iv = vec![0; IV_LEN];
let mut rng = OsRng::new()?;
rng.fill(&mut iv[..]);
Ok(IV(iv))
}
fn encrypt(data: &[u8], key: &Key, iv: &IV) -> Result<Vec<u8>, Box<error::Error>> {
let mut encryptor = aes::cbc_encryptor(
aes::KeySize::KeySize256,
&key.0[..],
&iv.0[..],
blockmodes::PkcsPadding,
);
let mut final_result = Vec::<u8>::new();
let mut read_buffer = buffer::RefReadBuffer::new(data);
let mut buffer = [0; BUFFER_SIZE];
let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);
loop {
let result = encryptor
.encrypt(&mut read_buffer, &mut write_buffer, true)
.unwrap();
final_result.extend(
write_buffer
.take_read_buffer()
.take_remaining()
.iter()
.cloned(),
);
match result {
BufferResult::BufferUnderflow => break,
BufferResult::BufferOverflow => {}
}
}
Ok(final_result)
}
fn decrypt(encrypted_data: &[u8], key: &Key, iv: &IV) -> Result<Vec<u8>, Box<error::Error>> {
let mut decryptor = aes::cbc_decryptor(
aes::KeySize::KeySize256,
&key.0[..],
&iv.0[..],
blockmodes::PkcsPadding,
);
let mut final_result = Vec::<u8>::new();
let mut read_buffer = buffer::RefReadBuffer::new(encrypted_data);
let mut buffer = [0; BUFFER_SIZE];
let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);
loop {
let result = decryptor
.decrypt(&mut read_buffer, &mut write_buffer, true)
.unwrap();
final_result.extend(
write_buffer
.take_read_buffer()
.take_remaining()
.iter()
.cloned(),
);
match result {
BufferResult::BufferUnderflow => break,
BufferResult::BufferOverflow => {}
}
}
Ok(final_result)
}