aboutsummaryrefslogtreecommitdiff
path: root/src/security
diff options
context:
space:
mode:
authorKatharina Fey <kookie@spacekookie.de>2018-04-02 12:05:59 +0200
committerKatharina Fey <kookie@spacekookie.de>2018-04-02 12:05:59 +0200
commit5fe943efec2f7c0210d9b12767876ef3a251dfac (patch)
treebee7828484fbad19e7680915a3505398ebd98a6b /src/security
parent9526f691b5a2cb65aff132b2d96d95ec77c6c088 (diff)
Making a small crypto example work
Diffstat (limited to 'src/security')
-rw-r--r--src/security/crypto.rs74
-rw-r--r--src/security/random.rs1
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();