From 9ceda952a1c0d42b11a67dd7d00178c720f9c601 Mon Sep 17 00:00:00 2001 From: Katharina Fey Date: Sun, 16 Sep 2018 18:41:49 +0100 Subject: Starting work on Keyfold The idea here is the following: You don't want to have to write encryption code for keys all the time especially if there are many and maybe lots of interactions. Also...maybe you doN't have the raw key anymore. It's kept in the vault in encrypted form and you just cache it from time to time. So you get it, decrypt it, store it in the Engine again, do some crypto. The user forgets about you, the key is cleared..etc. The keyfold comes in right there! It takes care of decrypting and re-encrypting any keychanges made by the user, so that the Vault backend only ever gets encrypted keys to work with. --- lockchain-crypto/src/engine.rs | 68 ++++++++++++++++++++++++++--------------- lockchain-crypto/src/keyfold.rs | 48 +++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 25 deletions(-) create mode 100644 lockchain-crypto/src/keyfold.rs diff --git a/lockchain-crypto/src/engine.rs b/lockchain-crypto/src/engine.rs index 45470c1..e80c846 100644 --- a/lockchain-crypto/src/engine.rs +++ b/lockchain-crypto/src/engine.rs @@ -17,53 +17,71 @@ impl Encryptable for DataBody {} pub struct AesEngine { ctx: Aes256Siv, - _key: Key, + _key: Option, iv: Vec, } impl AesEngine { - /// Generate new key and encryption engine - #[deprecated] - pub fn generate() -> Self { - let key = Key::new(KeyType::Aes256); - let len = key.len(); + /// Initialise an AesEngine and take ownership of a raw key + pub fn new(key: Key) -> Self { + assert!(key.len() == 64); + Self { ctx: Aes256Siv::new(&key.as_slice()), - _key: key, - iv: random::bytes(len), + _key: Some(key), + iv: random::bytes(64), } } + /// Generate new key and encryption engine + #[deprecated] + pub fn generate() -> Self { + // let key = Key::new(KeyType::Aes256); + // let len = key.len(); + // Self { + // ctx: Aes256Siv::new(&key.as_slice()), + // _key: key, + // new_key: None, + // iv: random::bytes(len), + // } + unimplemented!() + } + /// Generate an Aes context from password #[deprecated] pub fn from_pw(pw: &str, salt: &str) -> Self { - let key = Key::from_pw(KeyType::Aes256, pw, salt); - let len = key.len(); - Self { - ctx: Aes256Siv::new(&key.as_slice()), - _key: key, - iv: random::bytes(len), - } + // let key = Key::from_pw(KeyType::Aes256, pw, salt); + // let len = key.len(); + // Self { + // ctx: Aes256Siv::new(&key.as_slice()), + // _key: key, + // new_key: None, + // iv: random::bytes(len), + // } + unimplemented!() } /// Load a packed data object which contains an Aes context #[deprecated] pub fn load(packed: PackedData, pw: &str, salt: &str) -> Option { - let mut temp = Self::from_pw(pw, salt); - let k: Key = Key::decode(&String::from_utf8(temp.decrypt_primitive(&packed)?).ok()?).ok()?; - - Some(Self { - ctx: Aes256Siv::new(&k.as_slice()), - _key: k, - iv: packed.iv, - }) + // let mut temp = Self::from_pw(pw, salt); + // let k: Key = Key::decode(&String::from_utf8(temp.decrypt_primitive(&packed)?).ok()?).ok()?; + + // Some(Self { + // ctx: Aes256Siv::new(&k.as_slice()), + // _key: k, + // new_key: None, + // iv: packed.iv, + // }) + unimplemented!() } /// Serialise the current context to save it somewhere #[deprecated] pub fn save(&mut self) -> PackedData { - let k = self._key.as_slice().into(); - self.encrypt_primitive(&k) + // let k = self._key.as_slice().into(); + // self.encrypt_primitive(&k) + unimplemented!() } fn encrypt_primitive(&mut self, data: &Vec) -> PackedData { diff --git a/lockchain-crypto/src/keyfold.rs b/lockchain-crypto/src/keyfold.rs new file mode 100644 index 0000000..2339a32 --- /dev/null +++ b/lockchain-crypto/src/keyfold.rs @@ -0,0 +1,48 @@ +//! Keyfolds map keys to encrypted keys + +use lcc::crypto::{Key, KeyType}; +use lcc::traits::EncryptionHandler; +use lcc::EncryptedBody; + +use AesEngine; + +/// Transparent key-encrypter utility +/// +/// This structure acts as a mapper between the +/// encrypted keys that are stored in a vault and +/// the decrypted keys that need to exist in order +/// for the `AesEngine` (and similar) to work. +/// +/// This means that it is initialised with a +/// user passphrase (and name for salt purposes) +/// and is subsequently able to encrypt keys +/// to be stored in a vault persistence medium +/// or decrypt keys that are retrieved via a +/// Vault metadata API. +pub struct Keyfold { + engine: Option, +} + +impl Keyfold { + /// Take ownership of the AesEngine for transactions + pub fn begin(&mut self, engine: AesEngine) { + self.engine = Some(engine); + } + + /// Return ownership o the AesEngine + pub fn end(mut self) -> AesEngine { + let engine = self.engine.unwrap(); + self.engine = None; + engine + } +} + +impl EncryptionHandler for Keyfold { + fn encrypt(&mut self, item: Key) -> EncryptedBody { + unimplemented!() + } + + fn decrypt(&mut self, item: EncryptedBody) -> Option { + unimplemented!() + } +} -- cgit v1.2.3