diff options
author | Katharina Fey <kookie@spacekookie.de> | 2018-04-02 12:05:59 +0200 |
---|---|---|
committer | Katharina Fey <kookie@spacekookie.de> | 2018-04-02 12:05:59 +0200 |
commit | 5fe943efec2f7c0210d9b12767876ef3a251dfac (patch) | |
tree | bee7828484fbad19e7680915a3505398ebd98a6b /src/security | |
parent | 9526f691b5a2cb65aff132b2d96d95ec77c6c088 (diff) |
Making a small crypto example work
Diffstat (limited to 'src/security')
-rw-r--r-- | src/security/crypto.rs | 74 | ||||
-rw-r--r-- | src/security/random.rs | 1 |
2 files changed, 61 insertions, 14 deletions
diff --git a/src/security/crypto.rs b/src/security/crypto.rs index 6252395..da7ccdb 100644 --- a/src/security/crypto.rs +++ b/src/security/crypto.rs @@ -1,25 +1,71 @@ //! - -use miscreant::aead::{Aes128PmacSiv, Aes128Siv, Aes256PmacSiv, Aes256Siv, Algorithm}; -use security::{keys::Key, random, encoding}; -use serde::Serialize; +use miscreant::aead::{Aes256Siv, Algorithm}; +use security::{encoding, random, keys::{Key, KEY_LENGTH}}; +use serde::{Serialize, de::DeserializeOwned}; use serde_json; +use std::error::Error; -struct Encryptor { +/// The main encryption context +pub struct CryptoEngine { + ctx: Aes256Siv, + key: Key, + iv: Vec<u8>, +} +/// Represents some packed data – includes nonce and blob +#[derive(Serialize, Deserialize)] +struct PackedData { + nonce: Vec<u8>, + data: Vec<u8>, } +impl CryptoEngine { + /// Create a new encryption context with a key + pub fn new(key: Key) -> CryptoEngine { + return CryptoEngine { + ctx: Aes256Siv::new(&key.to_slice()), + key: key, + iv: random::bytes(KEY_LENGTH), + }; + } + + /// Load an existing encryption context into scope + pub fn load(key: Key, iv: Vec<u8>) -> CryptoEngine { + return CryptoEngine { + ctx: Aes256Siv::new(&key.to_slice()), + key: key, + iv: iv, + }; + } + + /// Encrypt a piece of data, returns a packed and encoded string + pub fn encrypt<T: Serialize>(&mut self, data: &T) -> Result<String, Box<Error>> { + let serial = serde_json::to_string(&data)?; + let nonce = random::bytes(64); + let iv = &self.iv.as_slice(); + let data = &serial.as_bytes(); + + let encrypted = self.ctx.seal(nonce.as_slice(), iv, data); + let packed = PackedData { + nonce: nonce, + data: encrypted, + }; + + let enc_packed = serde_json::to_string(&packed)?; + return Ok(encoding::base64_encode(&enc_packed.into_bytes())); + } -pub fn encrypt<T: Serialize>(data: &T) -> String { - let encoded: String = serde_json::to_string(&data).unwrap(); + /// Decrypt a ciphertext string into a type object + pub fn decrypt<T: DeserializeOwned>(&mut self, cipher: String) -> Result<T, Box<Error>> { + let dec_packed = String::from_utf8(encoding::base64_decode(&cipher))?; + let p: PackedData = serde_json::from_str(&dec_packed)?; - let key: Key = Key::new(); - let mut aes: Aes256Siv = Aes256Siv::new(&key.to_slice()); - - let nonce = random::bytes(64); - let ad = random::bytes(64); + let iv = &self.iv.as_slice(); + let decrypted = self.ctx.open(p.nonce.as_slice(), iv, p.data.as_slice())?; + let decr_str = String::from_utf8(decrypted)?; - let encrypted = aes.seal(nonce.as_slice(), ad.as_slice(), encoded.as_bytes()); - return encoding::base64_encode(&encrypted); + let t: T = serde_json::from_str(&decr_str)?; + return Ok(t); + } } diff --git a/src/security/random.rs b/src/security/random.rs index b98c233..eb88d99 100644 --- a/src/security/random.rs +++ b/src/security/random.rs @@ -15,6 +15,7 @@ pub fn number(bound: u64) -> u64 { /// as a vector. /// /// Can at most allocate 2048 bytes at a time +/// FIXME: That shouldn't have a limit! pub fn bytes(length: usize) -> Vec<u8> { let mut vec: Vec<u8> = Vec::new(); |