-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split Encryptable/Decryptable trait into encryption and key retrieval (…
…#297) ## Type of change ``` - [ ] Bug fix - [ ] New feature development - [x] Tech debt (refactoring, code cleanup, dependency upgrades, etc) - [ ] Build/deploy pipeline (DevOps) - [ ] Other ``` ## Objective At the moment, the `Encryptable`/`Decryptable` trait handles both encryption/decryption and key retrieval. The goal of this PR is to split this trait into two parts, one part that only handles encryption/decryption (and thus will be able to be moved into a separate `bitwarden-crypto` crate, if we want), and another part that handles retrieving the corresponding encryption key for each model object. ## Code changes What was the `Encryptable`/`Decryptable` trait has been split into multiple parts: - `KeyEncryptable`/`KeyDecryptable`: This receives only the encryption key and handles encryption/decryption only. The name of the interface was chosen to match the current `EncString::decrypt_with_key`, which this replaces. - `LocateKey`, which is implemented by types that know the type of key they need. For example a `Folder` always uses the user key and a `Cipher` uses the user key or one of the organization keys depending on its `organization_id` field. - `Encryptable`/`Decryptable`, this is now a thin compatibility layer between the previously mentioned two, to keep the existing API for the moment and keep the changes in this PR to a minimum. In the future we might decide that it's not necessary. With these changes, any models should implement `KeyEncryptable`/`KeyDecryptable` only, and `LocateKey` if applicable, but never `Encryptable`/`Decryptable` directly. Some of these changes will be more fleshed out in the future to avoid cluttering this PR, so I expect this won't look perfect: - Both `LocateKey` and `Encryptable` have an interface like `enc: &EncryptionSettings, org_id: &Option<Uuid>`. The organization parameter is mostly superfluous now and will be removed in the future: Objects that implement `LocateKey` do not use it, while objects which don't implement it should be provided the keys directly. - `EncString` is implementing `LocateKey` now, which goes against the explanation above. This is to avoid refactoring some secrets manager code, which I'll do on a later PR. - `EncryptionSettings` will change in the future, specially the `get_key` implementation, to be more generic. It also contains an `encrypt` function that shouldn't be there, but is used in a couple of spots of the code base and I'll remove on a later PR. - `KeyEncryptable`/`KeyDecryptable` only handles `SymmetricCryptoKey`, this will be made more generic over key type.
- Loading branch information
1 parent
ba49283
commit b2ae272
Showing
20 changed files
with
398 additions
and
333 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
use std::{collections::HashMap, hash::Hash}; | ||
|
||
use crate::error::Result; | ||
|
||
use super::SymmetricCryptoKey; | ||
|
||
pub trait KeyEncryptable<Output> { | ||
fn encrypt_with_key(self, key: &SymmetricCryptoKey) -> Result<Output>; | ||
} | ||
|
||
pub trait KeyDecryptable<Output> { | ||
fn decrypt_with_key(&self, key: &SymmetricCryptoKey) -> Result<Output>; | ||
} | ||
|
||
impl<T: KeyEncryptable<Output>, Output> KeyEncryptable<Option<Output>> for Option<T> { | ||
fn encrypt_with_key(self, key: &SymmetricCryptoKey) -> Result<Option<Output>> { | ||
self.map(|e| e.encrypt_with_key(key)).transpose() | ||
} | ||
} | ||
|
||
impl<T: KeyDecryptable<Output>, Output> KeyDecryptable<Option<Output>> for Option<T> { | ||
fn decrypt_with_key(&self, key: &SymmetricCryptoKey) -> Result<Option<Output>> { | ||
self.as_ref().map(|e| e.decrypt_with_key(key)).transpose() | ||
} | ||
} | ||
|
||
impl<T: KeyEncryptable<Output>, Output> KeyEncryptable<Output> for Box<T> { | ||
fn encrypt_with_key(self, key: &SymmetricCryptoKey) -> Result<Output> { | ||
(*self).encrypt_with_key(key) | ||
} | ||
} | ||
|
||
impl<T: KeyDecryptable<Output>, Output> KeyDecryptable<Output> for Box<T> { | ||
fn decrypt_with_key(&self, key: &SymmetricCryptoKey) -> Result<Output> { | ||
(**self).decrypt_with_key(key) | ||
} | ||
} | ||
|
||
impl<T: KeyEncryptable<Output>, Output> KeyEncryptable<Vec<Output>> for Vec<T> { | ||
fn encrypt_with_key(self, key: &SymmetricCryptoKey) -> Result<Vec<Output>> { | ||
self.into_iter().map(|e| e.encrypt_with_key(key)).collect() | ||
} | ||
} | ||
|
||
impl<T: KeyDecryptable<Output>, Output> KeyDecryptable<Vec<Output>> for Vec<T> { | ||
fn decrypt_with_key(&self, key: &SymmetricCryptoKey) -> Result<Vec<Output>> { | ||
self.iter().map(|e| e.decrypt_with_key(key)).collect() | ||
} | ||
} | ||
|
||
impl<T: KeyEncryptable<Output>, Output, Id: Hash + Eq> KeyEncryptable<HashMap<Id, Output>> | ||
for HashMap<Id, T> | ||
{ | ||
fn encrypt_with_key(self, key: &SymmetricCryptoKey) -> Result<HashMap<Id, Output>> { | ||
self.into_iter() | ||
.map(|(id, e)| Ok((id, e.encrypt_with_key(key)?))) | ||
.collect() | ||
} | ||
} | ||
|
||
impl<T: KeyDecryptable<Output>, Output, Id: Hash + Eq + Copy> KeyDecryptable<HashMap<Id, Output>> | ||
for HashMap<Id, T> | ||
{ | ||
fn decrypt_with_key(&self, key: &SymmetricCryptoKey) -> Result<HashMap<Id, Output>> { | ||
self.iter() | ||
.map(|(id, e)| Ok((*id, e.decrypt_with_key(key)?))) | ||
.collect() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.