crypt_config/config/
cipher.rs

1extern crate base64;
2extern crate serde;
3extern crate serde_json;
4
5use std::collections::HashMap;
6
7use serde::{Deserialize, Serialize};
8
9use crate::cipher::aes::{CBCCipher, CFB1Cipher, ECBCipher};
10use crate::cipher::{generate_salt, ICipher};
11use crate::error::{CryptError, CryptResult};
12
13#[derive(Serialize, Deserialize)]
14pub struct CipherConfig {
15  algorithm: String,
16  secret:    Vec<u8>
17}
18
19#[allow(dead_code)]
20pub struct CipherData {
21  configurations: HashMap<String, Box<CipherConfig>>,
22  latest_version: String
23}
24
25impl CipherConfig {
26  #[allow(dead_code)]
27  pub fn new(algorithm: String, secret: Vec<u8>) -> CipherConfig {
28    CipherConfig { algorithm: algorithm, secret: secret }
29  }
30}
31
32impl CipherData {
33  #[allow(dead_code)]
34  pub fn new() -> CipherData {
35    CipherData { configurations: HashMap::new(), latest_version: "0".to_string() }
36  }
37
38  pub fn contains_configuration(&self, version: &str) -> bool {
39    self.configurations.contains_key(version)
40  }
41
42  pub fn insert_configuration(&mut self, version: &str, cfg: Box<CipherConfig>) {
43    self.configurations.insert(version.to_string(), cfg);
44    self.update_version(version);
45  }
46
47  pub fn get_latest_version(&self) -> &str {
48    self.latest_version.as_str()
49  }
50
51  pub fn get_config<'a>(&'a self, version: &str) -> Option<&'a Box<CipherConfig>> {
52    self.configurations.get(version)
53  }
54
55  fn update_version(&mut self, version: &str) {
56    if self.latest_version.as_str() < version {
57      self.latest_version = version.to_string()
58    }
59  }
60}
61
62#[allow(dead_code)]
63pub fn generate_cipher_from_config(cfg: &CipherConfig) -> CryptResult<Box<dyn ICipher>> {
64  let salt = generate_salt();
65
66  match cfg.algorithm.as_ref() {
67    "aes_cbc" => Ok(Box::new(CBCCipher::new(&cfg.secret, &salt))),
68    "aes_cfb1" => Ok(Box::new(CFB1Cipher::new(&cfg.secret, &salt))),
69    "aes_ecb" => Ok(Box::new(ECBCipher::new(&cfg.secret, &salt))),
70    _ => Err(CryptError::CipherNotFound(cfg.algorithm.clone()))
71  }
72}
73
74#[cfg(test)]
75mod tests {
76  use super::generate_cipher_from_config;
77  use super::CipherConfig;
78  #[test]
79  fn aes_cbc_algorithm() {
80    let secret = [11u8, 16].to_vec();
81    let cfg = CipherConfig { algorithm: "aes_cbc".to_string(), secret: secret };
82
83    let cipher = generate_cipher_from_config(&cfg).unwrap();
84    let data = "very secured data";
85    let crypted = cipher.encrypt(data).unwrap();
86
87    assert_eq!(data, cipher.decrypt(&crypted).unwrap());
88  }
89  #[test]
90  fn aes_cfb1_algorithm() {
91    let secret = [11u8, 16].to_vec();
92    let cfg = CipherConfig { algorithm: "aes_cfb1".to_string(), secret: secret };
93
94    let cipher = generate_cipher_from_config(&cfg).unwrap();
95    let data = "very secured data";
96    let crypted = cipher.encrypt(data).unwrap();
97
98    assert_eq!(data, cipher.decrypt(&crypted).unwrap());
99  }
100  #[test]
101  fn aes_ecb_algorithm() {
102    let secret = [11u8, 16].to_vec();
103    let cfg = CipherConfig { algorithm: "aes_ecb".to_string(), secret: secret };
104
105    let cipher = generate_cipher_from_config(&cfg).unwrap();
106    let data = "very secured data";
107    let crypted = cipher.encrypt(data).unwrap();
108
109    assert_eq!(data, cipher.decrypt(&crypted).unwrap());
110  }
111  #[test]
112  fn unknown_algorithm() {
113    let secret = [11u8, 16].to_vec();
114    let cfg = CipherConfig { algorithm: "unknown".to_string(), secret: secret };
115
116    assert!(generate_cipher_from_config(&cfg).is_err());
117  }
118}