crypt-config 0.2.2

A crypt module that encrypt/decrypt json data based on the configuration. This might be used as a layer before saving data in Mongo DB or after fetching the data from the DB in order to decrypt them.
Documentation
extern crate openssl;

use openssl::symm::{decrypt, encrypt, Cipher};

use crate::cipher::{generate_salt, ICipher};
use crate::error::CryptResult;

pub struct ECBCipher {
  secret: Vec<u8>,
  salt:   Vec<u8>,
  cipher: Cipher
}

impl ECBCipher {
  #[allow(dead_code)]
  pub fn new(secret: &[u8], salt: &[u8]) -> ECBCipher {
    let mut secret = secret.to_vec();
    let mut salt = salt.to_vec();
    let cipher = match secret.len() {
      16 => Cipher::aes_128_ecb(),
      24 => Cipher::aes_192_ecb(),
      32 => Cipher::aes_256_ecb(),
      _ => {
        println!("[crypt-config][WARNING] incorrect secret length. Expected 16, 24 or 32, got {}. Secret will be resized to 32 with value 0.", secret.len());
        secret.resize(32, 0);
        Cipher::aes_256_ecb()
      }
    };

    if salt.is_empty() {
      salt = generate_salt();
    }

    salt.resize(secret.len(), 0);

    ECBCipher { secret: secret, salt: salt, cipher: cipher }
  }
}

impl ICipher for ECBCipher {
  fn encrypt(&self, data: &str) -> CryptResult<Vec<u8>> {
    Ok(encrypt(self.cipher, &self.secret, Some(&self.salt), data.as_bytes())?)
  }

  fn encrypt_with_salt(&self, data: &str, salt: &[u8]) -> CryptResult<Vec<u8>> {
    Ok(encrypt(self.cipher, &self.secret, Some(salt), data.as_bytes())?)
  }

  fn decrypt(&self, data: &[u8]) -> CryptResult<String> {
    let plain = decrypt(self.cipher, &self.secret, Some(&self.salt), data)?;
    Ok(String::from_utf8(plain)?)
  }

  fn decrypt_with_salt(&self, data: &[u8], salt: &[u8]) -> CryptResult<String> {
    let plain = decrypt(self.cipher, &self.secret, Some(salt), data)?;
    Ok(String::from_utf8(plain)?)
  }

  fn get_salt(&self) -> &Vec<u8> {
    &self.salt
  }
}

#[cfg(test)]
mod tests {
  use crate::cipher::ICipher;
  use rand::Rng;

  #[test]
  fn ecb_encrypt_decrypt_128() {
    let secret = rand::thread_rng().gen::<[u8; 16]>();
    let salt = rand::thread_rng().gen::<[u8; 16]>();

    let data = "this is a data that will be encrypted";

    let cipher = super::ECBCipher::new(&secret, &salt);
    let crypted_data = cipher.encrypt(data).unwrap();
    let uncrypted_data = cipher.decrypt(&crypted_data).unwrap();

    assert_eq!(data, uncrypted_data);
  }

  #[test]
  fn ecb_encrypt_decrypt_192() {
    let secret = rand::thread_rng().gen::<[u8; 24]>();
    let salt = rand::thread_rng().gen::<[u8; 24]>();

    let data = "this is a data that will be encrypted";

    let cipher = super::ECBCipher::new(&secret, &salt);
    let crypted_data = cipher.encrypt(data).unwrap();
    let uncrypted_data = cipher.decrypt(&crypted_data).unwrap();

    assert_eq!(data, uncrypted_data);
  }

  #[test]
  fn ecb_encrypt_decrypt_256() {
    let secret = rand::thread_rng().gen::<[u8; 32]>();
    let salt = rand::thread_rng().gen::<[u8; 32]>();

    let data = "this is a data that will be encrypted";

    let cipher = super::ECBCipher::new(&secret, &salt);
    let crypted_data = cipher.encrypt(data).unwrap();
    let uncrypted_data = cipher.decrypt(&crypted_data).unwrap();

    assert_eq!(data, uncrypted_data);
  }

  #[test]
  fn ecb_encrypt_decrypt_other() {
    let secret = rand::thread_rng().gen::<[u8; 30]>();
    let salt = rand::thread_rng().gen::<[u8; 10]>();

    let data = "this is a data that will be encrypted";

    let cipher = super::ECBCipher::new(&secret, &salt);
    let crypted_data = cipher.encrypt(data).unwrap();
    let uncrypted_data = cipher.decrypt(&crypted_data).unwrap();

    assert_eq!(data, uncrypted_data);
  }
}