diff --git a/crates/bitwarden-core/src/auth/auth_client.rs b/crates/bitwarden-core/src/auth/auth_client.rs index fa56841fe..1f90ddcce 100644 --- a/crates/bitwarden-core/src/auth/auth_client.rs +++ b/crates/bitwarden-core/src/auth/auth_client.rs @@ -191,7 +191,7 @@ fn trust_device(client: &Client) -> Result Result<()> { let key_store = client.get_key_store(); let ctx = key_store.context(); #[allow(deprecated)] - if let Ok(enc_key) = ctx.dangerous_get_symmetric_key(SymmetricKeyId::User) { + if let Ok(enc_key) = ctx.dangerous_get_key(SymmetricKeyId::User) { let state = ClientState::new(r.access_token.clone(), enc_key.to_base64()); _ = state::set(state_file, access_token, state); diff --git a/crates/bitwarden-core/src/client/encryption_settings.rs b/crates/bitwarden-core/src/client/encryption_settings.rs index 8d4494484..dc834c2c7 100644 --- a/crates/bitwarden-core/src/client/encryption_settings.rs +++ b/crates/bitwarden-core/src/client/encryption_settings.rs @@ -70,9 +70,9 @@ impl EncryptionSettings { #[allow(deprecated)] { let mut ctx = store.context_mut(); - ctx.set_symmetric_key(SymmetricKeyId::User, user_key)?; + ctx.set_key(SymmetricKeyId::User, user_key)?; if let Some(private_key) = private_key { - ctx.set_asymmetric_key(AsymmetricKeyId::UserPrivateKey, private_key)?; + ctx.set_key(AsymmetricKeyId::UserPrivateKey, private_key)?; } } @@ -87,7 +87,7 @@ impl EncryptionSettings { #[allow(deprecated)] store .context_mut() - .set_symmetric_key(SymmetricKeyId::User, key) + .set_key(SymmetricKeyId::User, key) .expect("Mutable context"); } @@ -103,7 +103,7 @@ impl EncryptionSettings { return Ok(()); } - if !ctx.has_asymmetric_key(AsymmetricKeyId::UserPrivateKey) { + if !ctx.has_key(AsymmetricKeyId::UserPrivateKey) { return Err(EncryptionSettingsError::MissingPrivateKey); } @@ -113,7 +113,7 @@ impl EncryptionSettings { // Decrypt the org keys with the private key for (org_id, org_enc_key) in org_enc_keys { - ctx.decrypt_symmetric_key_with_asymmetric_key( + ctx.decrypt_key_into_store( AsymmetricKeyId::UserPrivateKey, SymmetricKeyId::Organization(org_id), &org_enc_key, diff --git a/crates/bitwarden-core/src/key_management/mod.rs b/crates/bitwarden-core/src/key_management/mod.rs index dd13ab21c..8c1ca9573 100644 --- a/crates/bitwarden-core/src/key_management/mod.rs +++ b/crates/bitwarden-core/src/key_management/mod.rs @@ -38,7 +38,7 @@ pub fn create_test_crypto_with_user_key(key: SymmetricCryptoKey) -> KeyStore Result for Data { /// fn encrypt(&self, ctx: &mut KeyStoreContext, key: SymmKeyId) -> Result { -/// let local_key_id = ctx.decrypt_symmetric_key_with_symmetric_key(key, LOCAL_KEY, &self.key)?; +/// let local_key_id = ctx.decrypt_key_into_store(key, LOCAL_KEY, &self.key)?; /// self.name.encrypt(ctx, local_key_id) /// } /// } @@ -97,6 +98,93 @@ impl GlobalKeys<'_, Ids> { } } +// TODO: We should probably unify how we handle key parsing, and implement TryFrom> and +// TryInto> for all keys +pub trait KeyBytes: Sized { + fn as_bytes(&self) -> Result>; + fn from_bytes(bytes: &[u8]) -> Result; +} +impl KeyBytes for SymmetricCryptoKey { + fn as_bytes(&self) -> Result> { + Ok(self.to_vec()) + } + fn from_bytes(bytes: &[u8]) -> Result { + SymmetricCryptoKey::try_from(bytes.to_vec()) + } +} +impl KeyBytes for AsymmetricCryptoKey { + fn as_bytes(&self) -> Result> { + Ok(self.to_der()?.as_slice().to_vec()) + } + fn from_bytes(bytes: &[u8]) -> Result { + AsymmetricCryptoKey::from_der(bytes) + } +} + +mod internal { + use super::*; + pub trait ContextHasKeys, Key: CryptoKey, ContextIds: KeyIds> { + fn internal_get_key(&self, id: Id) -> Result<&Id::KeyValue>; + fn internal_set_key(&mut self, id: Id, value: Id::KeyValue) -> Result<()>; + } +} +use internal::ContextHasKeys; + +impl ContextHasKeys + for KeyStoreContext<'_, ContextIds> +{ + fn internal_get_key(&self, id: ContextIds::Symmetric) -> Result<&SymmetricCryptoKey> { + if id.is_local() { + self.local_symmetric_keys.get(id) + } else { + self.global_keys.get().symmetric_keys.get(id) + } + .ok_or_else(|| crate::CryptoError::MissingKeyId(format!("{id:?}"))) + } + + fn internal_set_key( + &mut self, + id: ContextIds::Symmetric, + value: SymmetricCryptoKey, + ) -> Result<()> { + if id.is_local() { + self.local_symmetric_keys.upsert(id, value); + } else { + self.global_keys.get_mut()?.symmetric_keys.upsert(id, value); + } + Ok(()) + } +} + +impl ContextHasKeys + for KeyStoreContext<'_, ContextIds> +{ + fn internal_get_key(&self, id: ContextIds::Asymmetric) -> Result<&AsymmetricCryptoKey> { + if id.is_local() { + self.local_asymmetric_keys.get(id) + } else { + self.global_keys.get().asymmetric_keys.get(id) + } + .ok_or_else(|| crate::CryptoError::MissingKeyId(format!("{id:?}"))) + } + + fn internal_set_key( + &mut self, + id: ContextIds::Asymmetric, + value: AsymmetricCryptoKey, + ) -> Result<()> { + if id.is_local() { + self.local_asymmetric_keys.upsert(id, value); + } else { + self.global_keys + .get_mut()? + .asymmetric_keys + .upsert(id, value); + } + Ok(()) + } +} + impl KeyStoreContext<'_, Ids> { /// Clears all the local keys stored in this context /// This will not affect the global keys even if this context has write access. @@ -124,35 +212,33 @@ impl KeyStoreContext<'_, Ids> { self.local_asymmetric_keys.retain(f); } - // TODO: All these encrypt x key with x key look like they need to be made generic, - // but I haven't found the best way to do that yet. - - /// Decrypt a symmetric key into the context by using an already existing symmetric key + /// Decrypt a key into the context by using an already existing key /// /// # Arguments /// /// * `encryption_key` - The key id used to decrypt the `encrypted_key`. It must already exist /// in the context - /// * `new_key_id` - The key id where the decrypted key will be stored. If it already exists, it - /// will be overwritten + /// * `decrypted_key_id` - The key id where the decrypted key will be stored. If it already + /// exists, it will be overwritten /// * `encrypted_key` - The key to decrypt - pub fn decrypt_symmetric_key_with_symmetric_key( + pub fn decrypt_key_into_store( &mut self, - encryption_key: Ids::Symmetric, - new_key_id: Ids::Symmetric, - encrypted_key: &EncString, - ) -> Result { - let mut new_key_material = - self.decrypt_data_with_symmetric_key(encryption_key, encrypted_key)?; - - #[allow(deprecated)] - self.set_symmetric_key( - new_key_id, - SymmetricCryptoKey::try_from(new_key_material.as_mut_slice())?, - )?; - - // Returning the new key identifier for convenience - Ok(new_key_id) + encryption_key: EncryptionKeyId, + decrypted_key_id: DecryptedKeyId, + encrypted_key: &EncryptedKey, + ) -> Result + where + Self: ContextHasKeys, + EncryptedKey: Decryptable>, + DecryptedKeyId: KeyId, + DecryptedKeyId::KeyValue: KeyBytes, + EncryptionKeyId: KeyId, + { + let decrypted_key = encrypted_key.decrypt(self, encryption_key)?; + let decrypted_key: DecryptedKeyId::KeyValue = KeyBytes::from_bytes(&decrypted_key)?; + + self.internal_set_key(decrypted_key_id, decrypted_key)?; + Ok(decrypted_key_id) } /// Encrypt and return a symmetric key from the context by using an already existing symmetric @@ -163,125 +249,40 @@ impl KeyStoreContext<'_, Ids> { /// * `encryption_key` - The key id used to encrypt the `key_to_encrypt`. It must already exist /// in the context /// * `key_to_encrypt` - The key id to encrypt. It must already exist in the context - pub fn encrypt_symmetric_key_with_symmetric_key( - &self, - encryption_key: Ids::Symmetric, - key_to_encrypt: Ids::Symmetric, - ) -> Result { - let key_to_encrypt = self.get_symmetric_key(key_to_encrypt)?; - self.encrypt_data_with_symmetric_key(encryption_key, &key_to_encrypt.to_vec()) - } - - /// Decrypt a symmetric key into the context by using an already existing asymmetric key - /// - /// # Arguments - /// - /// * `encryption_key` - The key id used to decrypt the `encrypted_key`. It must already exist - /// in the context - /// * `new_key_id` - The key id where the decrypted key will be stored. If it already exists, it - /// will be overwritten - /// * `encrypted_key` - The key to decrypt - pub fn decrypt_symmetric_key_with_asymmetric_key( - &mut self, - encryption_key: Ids::Asymmetric, - new_key_id: Ids::Symmetric, - encrypted_key: &AsymmetricEncString, - ) -> Result { - let mut new_key_material = - self.decrypt_data_with_asymmetric_key(encryption_key, encrypted_key)?; - - #[allow(deprecated)] - self.set_symmetric_key( - new_key_id, - SymmetricCryptoKey::try_from(new_key_material.as_mut_slice())?, - )?; - - // Returning the new key identifier for convenience - Ok(new_key_id) - } - - /// Encrypt and return a symmetric key from the context by using an already existing asymmetric - /// key - /// - /// # Arguments - /// - /// * `encryption_key` - The key id used to encrypt the `key_to_encrypt`. It must already exist - /// in the context - /// * `key_to_encrypt` - The key id to encrypt. It must already exist in the context - pub fn encrypt_symmetric_key_with_asymmetric_key( - &self, - encryption_key: Ids::Asymmetric, - key_to_encrypt: Ids::Symmetric, - ) -> Result { - let key_to_encrypt = self.get_symmetric_key(key_to_encrypt)?; - self.encrypt_data_with_asymmetric_key(encryption_key, &key_to_encrypt.to_vec()) - } - - /// Decrypt an asymmetric key into the context by using an already existing asymmetric key - /// - /// # Arguments - /// - /// * `encryption_key` - The key id used to decrypt the `encrypted_key`. It must already exist - /// in the context - /// * `new_key_id` - The key id where the decrypted key will be stored. If it already exists, it - /// will be overwritten - /// * `encrypted_key` - The key to decrypt - pub fn decrypt_asymmetric_key_with_asymmetric_key( + pub fn encrypt_key_from_store( &mut self, - encryption_key: Ids::Asymmetric, - new_key_id: Ids::Asymmetric, - encrypted_key: &AsymmetricEncString, - ) -> Result { - let new_key_material = - self.decrypt_data_with_asymmetric_key(encryption_key, encrypted_key)?; - - #[allow(deprecated)] - self.set_asymmetric_key( - new_key_id, - AsymmetricCryptoKey::from_der(&new_key_material)?, - )?; - - // Returning the new key identifier for convenience - Ok(new_key_id) + encryption_key: EncryptionKeyId, + key_to_encrypt: DecryptedKeyId, + ) -> Result + where + Self: ContextHasKeys, + EncryptionKeyId: KeyId, + DecryptedKeyId: KeyId, + DecryptedKeyId::KeyValue: KeyBytes, + for<'a> &'a [u8]: Encryptable, + { + let key_to_encrypt: &DecryptedKeyId::KeyValue = self.internal_get_key(key_to_encrypt)?; + + let mut key_bytes = key_to_encrypt.as_bytes()?; + let encrypted_key = key_bytes.as_slice().encrypt(self, encryption_key)?; + + key_bytes.zeroize(); + + Ok(encrypted_key) } - /// Encrypt and return an asymmetric key from the context by using an already existing - /// asymmetric key - /// - /// # Arguments - /// - /// * `encryption_key` - The key id used to encrypt the `key_to_encrypt`. It must already exist - /// in the context - /// * `key_to_encrypt` - The key id to encrypt. It must already exist in the context - pub fn encrypt_asymmetric_key_with_asymmetric_key( - &self, - encryption_key: Ids::Asymmetric, - key_to_encrypt: Ids::Asymmetric, - ) -> Result { - let encryption_key = self.get_asymmetric_key(encryption_key)?; - let key_to_encrypt = self.get_asymmetric_key(key_to_encrypt)?; - - AsymmetricEncString::encrypt_rsa2048_oaep_sha1( - key_to_encrypt.to_der()?.as_slice(), - encryption_key, - ) - } - - /// Returns `true` if the context has a symmetric key with the given identifier - pub fn has_symmetric_key(&self, key_id: Ids::Symmetric) -> bool { - self.get_symmetric_key(key_id).is_ok() - } - - /// Returns `true` if the context has an asymmetric key with the given identifier - pub fn has_asymmetric_key(&self, key_id: Ids::Asymmetric) -> bool { - self.get_asymmetric_key(key_id).is_ok() + /// Returns `true` if the context has a key with the given identifier + pub fn has_key(&self, key_id: Id) -> bool + where + Self: ContextHasKeys, + { + self.internal_get_key(key_id).is_ok() } /// Generate a new random symmetric key and store it in the context pub fn generate_symmetric_key(&mut self, key_id: Ids::Symmetric) -> Result { let key = SymmetricCryptoKey::generate(rand::thread_rng()); - #[allow(deprecated)] - self.set_symmetric_key(key_id, key)?; + self.internal_set_key(key_id, key)?; Ok(key_id) } @@ -296,77 +297,24 @@ impl KeyStoreContext<'_, Ids> { name: &str, info: Option<&str>, ) -> Result { - #[allow(deprecated)] - self.set_symmetric_key(key_id, derive_shareable_key(secret, name, info))?; + self.internal_set_key(key_id, derive_shareable_key(secret, name, info))?; Ok(key_id) } #[deprecated(note = "This function should ideally never be used outside this crate")] - pub fn dangerous_get_symmetric_key( - &self, - key_id: Ids::Symmetric, - ) -> Result<&SymmetricCryptoKey> { - self.get_symmetric_key(key_id) + pub fn dangerous_get_key(&self, key_id: Id) -> Result<&Id::KeyValue> + where + Self: ContextHasKeys, + { + self.internal_get_key(key_id) } #[deprecated(note = "This function should ideally never be used outside this crate")] - pub fn dangerous_get_asymmetric_key( - &self, - key_id: Ids::Asymmetric, - ) -> Result<&AsymmetricCryptoKey> { - self.get_asymmetric_key(key_id) - } - - fn get_symmetric_key(&self, key_id: Ids::Symmetric) -> Result<&SymmetricCryptoKey> { - if key_id.is_local() { - self.local_symmetric_keys.get(key_id) - } else { - self.global_keys.get().symmetric_keys.get(key_id) - } - .ok_or_else(|| crate::CryptoError::MissingKeyId(format!("{key_id:?}"))) - } - - fn get_asymmetric_key(&self, key_id: Ids::Asymmetric) -> Result<&AsymmetricCryptoKey> { - if key_id.is_local() { - self.local_asymmetric_keys.get(key_id) - } else { - self.global_keys.get().asymmetric_keys.get(key_id) - } - .ok_or_else(|| crate::CryptoError::MissingKeyId(format!("{key_id:?}"))) - } - - #[deprecated(note = "This function should ideally never be used outside this crate")] - pub fn set_symmetric_key( - &mut self, - key_id: Ids::Symmetric, - key: SymmetricCryptoKey, - ) -> Result<()> { - if key_id.is_local() { - self.local_symmetric_keys.upsert(key_id, key); - } else { - self.global_keys - .get_mut()? - .symmetric_keys - .upsert(key_id, key); - } - Ok(()) - } - - #[deprecated(note = "This function should ideally never be used outside this crate")] - pub fn set_asymmetric_key( - &mut self, - key_id: Ids::Asymmetric, - key: AsymmetricCryptoKey, - ) -> Result<()> { - if key_id.is_local() { - self.local_asymmetric_keys.upsert(key_id, key); - } else { - self.global_keys - .get_mut()? - .asymmetric_keys - .upsert(key_id, key); - } - Ok(()) + pub fn set_key(&mut self, key_id: Id, key_value: Id::KeyValue) -> Result<()> + where + Self: ContextHasKeys, + { + self.internal_set_key(key_id, key_value) } pub(crate) fn decrypt_data_with_symmetric_key( @@ -374,7 +322,7 @@ impl KeyStoreContext<'_, Ids> { key: Ids::Symmetric, data: &EncString, ) -> Result> { - let key = self.get_symmetric_key(key)?; + let key = self.internal_get_key(key)?; match data { EncString::AesCbc256_B64 { iv, data } => { @@ -395,7 +343,7 @@ impl KeyStoreContext<'_, Ids> { key: Ids::Symmetric, data: &[u8], ) -> Result { - let key = self.get_symmetric_key(key)?; + let key = self.internal_get_key(key)?; EncString::encrypt_aes256_hmac( data, key.mac_key.as_ref().ok_or(CryptoError::InvalidMac)?, @@ -408,7 +356,7 @@ impl KeyStoreContext<'_, Ids> { key: Ids::Asymmetric, data: &AsymmetricEncString, ) -> Result> { - let key = self.get_asymmetric_key(key)?; + let key = self.internal_get_key(key)?; use AsymmetricEncString::*; match data { @@ -431,7 +379,7 @@ impl KeyStoreContext<'_, Ids> { key: Ids::Asymmetric, data: &[u8], ) -> Result { - let key = self.get_asymmetric_key(key)?; + let key = self.internal_get_key(key)?; AsymmetricEncString::encrypt_rsa2048_oaep_sha1(data, key) } } @@ -456,10 +404,10 @@ mod tests { store .context_mut() - .set_symmetric_key(TestSymmKey::A(0), key_a0.clone()) + .set_key(TestSymmKey::A(0), key_a0.clone()) .unwrap(); - assert!(store.context().has_symmetric_key(key_a0_id)); + assert!(store.context().has_key(key_a0_id)); // Encrypt some data with the key let data = DataView("Hello, World!".to_string(), key_a0_id); @@ -477,27 +425,25 @@ mod tests { let key_1_id = TestSymmKey::C(1); let key_1 = SymmetricCryptoKey::generate(&mut rng); - ctx.set_symmetric_key(key_1_id, key_1.clone()).unwrap(); + ctx.set_key(key_1_id, key_1.clone()).unwrap(); - assert!(ctx.has_symmetric_key(key_1_id)); + assert!(ctx.has_key(key_1_id)); // Generate and insert a new key let key_2_id = TestSymmKey::C(2); let key_2 = SymmetricCryptoKey::generate(&mut rng); - ctx.set_symmetric_key(key_2_id, key_2.clone()).unwrap(); + ctx.set_key(key_2_id, key_2.clone()).unwrap(); - assert!(ctx.has_symmetric_key(key_2_id)); + assert!(ctx.has_key(key_2_id)); // Encrypt the new key with the old key - let key_2_enc = ctx - .encrypt_symmetric_key_with_symmetric_key(key_1_id, key_2_id) - .unwrap(); + let key_2_enc = ctx.encrypt_key_from_store(key_1_id, key_2_id).unwrap(); // Decrypt the new key with the old key in a different identifier let new_key_id = TestSymmKey::C(3); - ctx.decrypt_symmetric_key_with_symmetric_key(key_1_id, new_key_id, &key_2_enc) + ctx.decrypt_key_into_store(key_1_id, new_key_id, &key_2_enc) .unwrap(); // Now `key_2_id` and `new_key_id` contain the same key, so we should be able to encrypt diff --git a/crates/bitwarden-crypto/src/store/mod.rs b/crates/bitwarden-crypto/src/store/mod.rs index 1f6fa0d01..b8433c9e2 100644 --- a/crates/bitwarden-crypto/src/store/mod.rs +++ b/crates/bitwarden-crypto/src/store/mod.rs @@ -65,7 +65,7 @@ pub use context::KeyStoreContext; /// let store: KeyStore = KeyStore::default(); /// /// #[allow(deprecated)] -/// store.context_mut().set_symmetric_key(SymmKeyId::User, SymmetricCryptoKey::generate(rand::thread_rng())); +/// store.context_mut().set_key(SymmKeyId::User, SymmetricCryptoKey::generate(rand::thread_rng())); /// /// // Define some data that needs to be encrypted /// struct Data(String); @@ -152,9 +152,7 @@ impl KeyStore { /// lead to key material being leaked, but we need to support it for backwards compatibility. /// If you want to access the key material to encrypt it or derive a new key from it, we /// provide functions for that: - /// - [KeyStoreContext::encrypt_symmetric_key_with_symmetric_key] - /// - [KeyStoreContext::encrypt_symmetric_key_with_asymmetric_key] - /// - [KeyStoreContext::encrypt_asymmetric_key_with_asymmetric_key] + /// - [KeyStoreContext::encrypt_key_from_store] /// - [KeyStoreContext::derive_shareable_key] pub fn context(&'_ self) -> KeyStoreContext<'_, Ids> { KeyStoreContext { @@ -355,7 +353,7 @@ pub(crate) mod tests { #[allow(deprecated)] store .context_mut() - .set_symmetric_key(TestSymmKey::A(n), SymmetricCryptoKey::generate(&mut rng)) + .set_key(TestSymmKey::A(n), SymmetricCryptoKey::generate(&mut rng)) .unwrap(); } diff --git a/crates/bitwarden-crypto/src/traits/decryptable.rs b/crates/bitwarden-crypto/src/traits/decryptable.rs index 20fd3658c..3b9ee4510 100644 --- a/crates/bitwarden-crypto/src/traits/decryptable.rs +++ b/crates/bitwarden-crypto/src/traits/decryptable.rs @@ -87,7 +87,7 @@ mod tests { #[allow(deprecated)] store .context_mut() - .set_symmetric_key(TestSymmKey::A(0), key.clone()) + .set_key(TestSymmKey::A(0), key.clone()) .unwrap(); store diff --git a/crates/bitwarden-crypto/src/traits/encryptable.rs b/crates/bitwarden-crypto/src/traits/encryptable.rs index afc46ec08..473f98c04 100644 --- a/crates/bitwarden-crypto/src/traits/encryptable.rs +++ b/crates/bitwarden-crypto/src/traits/encryptable.rs @@ -129,12 +129,12 @@ mod tests { #[allow(deprecated)] store .context_mut() - .set_symmetric_key(TestSymmKey::A(0), symm_key.clone()) + .set_key(TestSymmKey::A(0), symm_key.clone()) .unwrap(); #[allow(deprecated)] store .context_mut() - .set_asymmetric_key(TestAsymmKey::A(0), asymm_key.clone()) + .set_key(TestAsymmKey::A(0), asymm_key.clone()) .unwrap(); store diff --git a/crates/bitwarden-send/src/send.rs b/crates/bitwarden-send/src/send.rs index aca67fd0f..768424b78 100644 --- a/crates/bitwarden-send/src/send.rs +++ b/crates/bitwarden-send/src/send.rs @@ -429,7 +429,7 @@ mod tests { // Get the send key let send_key = Send::get_key(&mut ctx, &send_key, SymmetricKeyId::User).unwrap(); #[allow(deprecated)] - let send_key = ctx.dangerous_get_symmetric_key(send_key).unwrap(); + let send_key = ctx.dangerous_get_key(send_key).unwrap(); let send_key_b64 = send_key.to_base64(); assert_eq!(send_key_b64, "IR9ImHGm6rRuIjiN7csj94bcZR5WYTJj5GtNfx33zm6tJCHUl+QZlpNPba8g2yn70KnOHsAODLcR0um6E3MAlg=="); } diff --git a/crates/bitwarden-vault/src/cipher/attachment.rs b/crates/bitwarden-vault/src/cipher/attachment.rs index 223f054f7..d9e5c2813 100644 --- a/crates/bitwarden-vault/src/cipher/attachment.rs +++ b/crates/bitwarden-vault/src/cipher/attachment.rs @@ -84,8 +84,7 @@ impl Encryptable for Attachment // with it, and then encrypt the key with the cipher key let attachment_key = ctx.generate_symmetric_key(ATTACHMENT_KEY)?; let encrypted_contents = self.contents.encrypt(ctx, attachment_key)?; - attachment.key = - Some(ctx.encrypt_symmetric_key_with_symmetric_key(ciphers_key, attachment_key)?); + attachment.key = Some(ctx.encrypt_key_from_store(ciphers_key, attachment_key)?); let contents = encrypted_contents.to_buffer()?; @@ -120,11 +119,8 @@ impl Decryptable> for AttachmentFile { // Version 2 or 3, `AttachmentKey` or `CipherKey(AttachmentKey)` if let Some(attachment_key) = &self.attachment.key { - let content_key = ctx.decrypt_symmetric_key_with_symmetric_key( - ciphers_key, - ATTACHMENT_KEY, - attachment_key, - )?; + let content_key = + ctx.decrypt_key_into_store(ciphers_key, ATTACHMENT_KEY, attachment_key)?; self.contents.decrypt(ctx, content_key) } else { // Legacy attachment version 1, use user/org key diff --git a/crates/bitwarden-vault/src/cipher/cipher.rs b/crates/bitwarden-vault/src/cipher/cipher.rs index b4d8c7722..fdd2289f7 100644 --- a/crates/bitwarden-vault/src/cipher/cipher.rs +++ b/crates/bitwarden-vault/src/cipher/cipher.rs @@ -305,9 +305,7 @@ impl Cipher { ) -> Result { const CIPHER_KEY: SymmetricKeyId = SymmetricKeyId::Local("cipher_key"); match ciphers_key { - Some(ciphers_key) => { - ctx.decrypt_symmetric_key_with_symmetric_key(key, CIPHER_KEY, ciphers_key) - } + Some(ciphers_key) => ctx.decrypt_key_into_store(key, CIPHER_KEY, ciphers_key), None => Ok(key), } } @@ -445,7 +443,7 @@ impl CipherView { self.reencrypt_attachment_keys(ctx, old_ciphers_key, new_key)?; self.reencrypt_fido2_credentials(ctx, old_ciphers_key, new_key)?; - self.key = Some(ctx.encrypt_symmetric_key_with_symmetric_key(key, new_key)?); + self.key = Some(ctx.encrypt_key_from_store(key, new_key)?); Ok(()) } @@ -891,7 +889,7 @@ mod tests { let cipher_key = ctx.generate_symmetric_key(CIPHER_KEY).unwrap(); original_cipher.key = Some( - ctx.encrypt_symmetric_key_with_symmetric_key(SymmetricKeyId::User, cipher_key) + ctx.encrypt_key_from_store(SymmetricKeyId::User, cipher_key) .unwrap(), ); } @@ -1014,13 +1012,10 @@ mod tests { .generate_symmetric_key(SymmetricKeyId::Local("test_attachment_key")) .unwrap(); let attachment_key_enc = ctx - .encrypt_symmetric_key_with_symmetric_key(SymmetricKeyId::User, attachment_key) + .encrypt_key_from_store(SymmetricKeyId::User, attachment_key) .unwrap(); #[allow(deprecated)] - let attachment_key_val = ctx - .dangerous_get_symmetric_key(attachment_key) - .unwrap() - .clone(); + let attachment_key_val = ctx.dangerous_get_key(attachment_key).unwrap().clone(); (attachment_key_enc, attachment_key_val) }; @@ -1081,7 +1076,7 @@ mod tests { .generate_symmetric_key(SymmetricKeyId::Local("test_cipher_key")) .unwrap(); let cipher_key_enc = ctx - .encrypt_symmetric_key_with_symmetric_key(SymmetricKeyId::User, cipher_key) + .encrypt_key_from_store(SymmetricKeyId::User, cipher_key) .unwrap(); // Attachment has a key that is encrypted with the cipher key @@ -1089,7 +1084,7 @@ mod tests { .generate_symmetric_key(SymmetricKeyId::Local("test_attachment_key")) .unwrap(); let attachment_key_enc = ctx - .encrypt_symmetric_key_with_symmetric_key(cipher_key, attachment_key) + .encrypt_key_from_store(cipher_key, attachment_key) .unwrap(); let mut cipher = generate_cipher(); @@ -1121,7 +1116,7 @@ mod tests { let new_cipher_key_dec: SymmetricCryptoKey = new_cipher_key_dec.try_into().unwrap(); #[allow(deprecated)] - let cipher_key_val = ctx.dangerous_get_symmetric_key(cipher_key).unwrap(); + let cipher_key_val = ctx.dangerous_get_key(cipher_key).unwrap(); assert_eq!(new_cipher_key_dec.to_vec(), cipher_key_val.to_vec());