Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split Encryptable/Decryptable trait into encryption and key retrieval #297

Merged
merged 5 commits into from
Oct 30, 2023

Conversation

dani-garcia
Copy link
Member

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.

@bitwarden-bot
Copy link

bitwarden-bot commented Oct 19, 2023

Logo
Checkmarx One – Scan Summary & Details01948998-fe3a-4823-ad44-127f15aae416

No New Or Fixed Issues Found

@MGibson1 MGibson1 self-assigned this Oct 23, 2023
Copy link
Member

@MGibson1 MGibson1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good, nothing pressing here. Let me know you're thoughts on these small nits and we can move forward

crates/bitwarden/src/client/encryption_settings.rs Outdated Show resolved Hide resolved
crates/bitwarden/src/crypto/key_encryptable.rs Outdated Show resolved Hide resolved
impl<T: Encryptable<Output>, Output> Encryptable<Option<Output>> for Option<T> {
fn encrypt(self, enc: &EncryptionSettings, org_id: &Option<Uuid>) -> Result<Option<Output>> {
self.map(|e| e.encrypt(enc, org_id)).transpose()
impl<T: KeyEncryptable<Output> + LocateKey, Output> Encryptable<Output> for T {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

@dani-garcia dani-garcia merged commit b2ae272 into master Oct 30, 2023
45 checks passed
@dani-garcia dani-garcia deleted the ps/encryptable-refactor branch October 30, 2023 15:39
dani-garcia added a commit that referenced this pull request Nov 3, 2023
## Type of change
```
- [ ] Bug fix
- [ ] New feature development
- [x] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [ ] Other
```

## Objective
After #297, there were some places in the secrets manager parts of the
code that used EncryptionSettings to encrypt directly, instead of
dealing with the Encryptable/KeyEncryptable trait. This PR removes those
uses so that all encryption opearations have to go through
Encryptable/KeyEncryptable.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants