diff --git a/crates/bitwarden-core/src/key_management/crypto.rs b/crates/bitwarden-core/src/key_management/crypto.rs index a76ea4294..40dd237b3 100644 --- a/crates/bitwarden-core/src/key_management/crypto.rs +++ b/crates/bitwarden-core/src/key_management/crypto.rs @@ -20,7 +20,7 @@ use {tsify_next::Tsify, wasm_bindgen::prelude::*}; use crate::{ client::{encryption_settings::EncryptionSettingsError, LoginMethod, UserLoginMethod}, - key_management::{AsymmetricKeyId, SigningKeyId, SymmetricKeyId}, + key_management::{AsymmetricKeyId, SymmetricKeyId}, Client, NotAuthenticatedError, VaultLockedError, WrongPasswordError, }; @@ -596,9 +596,8 @@ pub fn make_user_signing_keys_for_enrollment( // Make new keypair and sign the public key with it let signature_keypair = SigningKey::make(SignatureAlgorithm::Ed25519); - let temporary_signature_keypair_id = SigningKeyId::Local("temporary_key_for_rotation"); - #[allow(deprecated)] - ctx.set_signing_key(temporary_signature_keypair_id, signature_keypair.clone())?; + let temporary_signature_keypair_id = ctx.add_local_signing_key(signature_keypair.clone())?; + let signed_public_key = ctx.make_signed_public_key( AsymmetricKeyId::UserPrivateKey, temporary_signature_keypair_id, diff --git a/crates/bitwarden-core/src/key_management/mod.rs b/crates/bitwarden-core/src/key_management/mod.rs index 79bbf124a..57eed5b9e 100644 --- a/crates/bitwarden-core/src/key_management/mod.rs +++ b/crates/bitwarden-core/src/key_management/mod.rs @@ -25,21 +25,21 @@ key_ids! { User, Organization(uuid::Uuid), #[local] - Local(&'static str), + Local(LocalId), } #[asymmetric] pub enum AsymmetricKeyId { UserPrivateKey, #[local] - Local(&'static str), + Local(LocalId), } #[signing] pub enum SigningKeyId { UserSigningKey, #[local] - Local(&'static str), + Local(LocalId), } pub KeyIds => SymmetricKeyId, AsymmetricKeyId, SigningKeyId; diff --git a/crates/bitwarden-crypto/src/lib.rs b/crates/bitwarden-crypto/src/lib.rs index 60428d8a4..b6009efd0 100644 --- a/crates/bitwarden-crypto/src/lib.rs +++ b/crates/bitwarden-crypto/src/lib.rs @@ -39,7 +39,7 @@ pub use signing::*; mod traits; mod xchacha20; pub use traits::{ - CompositeEncryptable, Decryptable, IdentifyKey, KeyId, KeyIds, PrimitiveEncryptable, + CompositeEncryptable, Decryptable, IdentifyKey, KeyId, KeyIds, LocalId, PrimitiveEncryptable, }; pub use zeroizing_alloc::ZeroAlloc as ZeroizingAllocator; diff --git a/crates/bitwarden-crypto/src/store/context.rs b/crates/bitwarden-crypto/src/store/context.rs index 9675cfb5e..63ec3784b 100644 --- a/crates/bitwarden-crypto/src/store/context.rs +++ b/crates/bitwarden-crypto/src/store/context.rs @@ -10,7 +10,7 @@ use super::KeyStoreInner; use crate::{ derive_shareable_key, error::UnsupportedOperation, signing, store::backend::StoreBackend, AsymmetricCryptoKey, BitwardenLegacyKeyBytes, ContentFormat, CryptoError, EncString, KeyId, - KeyIds, Result, Signature, SignatureAlgorithm, SignedObject, SignedPublicKey, + KeyIds, LocalId, Result, Signature, SignatureAlgorithm, SignedObject, SignedPublicKey, SignedPublicKeyMessage, SigningKey, SymmetricCryptoKey, UnsignedSharedKey, }; @@ -37,15 +37,20 @@ use crate::{ /// # #[symmetric] /// # pub enum SymmKeyId { /// # User, -/// # Local(&'static str), +/// # #[local] +/// # Local(LocalId), /// # } /// # #[asymmetric] /// # pub enum AsymmKeyId { /// # UserPrivate, +/// # #[local] +/// # Local(LocalId), /// # } /// # #[signing] /// # pub enum SigningKeyId { /// # UserSigning, +/// # #[local] +/// # Local(LocalId), /// # } /// # pub Ids => SymmKeyId, AsymmKeyId, SigningKeyId; /// # } @@ -59,11 +64,10 @@ use crate::{ /// # } /// # } /// -/// const LOCAL_KEY: SymmKeyId = SymmKeyId::Local("local_key_id"); /// /// impl CompositeEncryptable for Data { /// fn encrypt_composite(&self, ctx: &mut KeyStoreContext, key: SymmKeyId) -> Result { -/// let local_key_id = ctx.unwrap_symmetric_key(key, LOCAL_KEY, &self.key)?; +/// let local_key_id = ctx.unwrap_symmetric_key(key, &self.key)?; /// self.name.encrypt(ctx, local_key_id) /// } /// } @@ -149,7 +153,6 @@ impl KeyStoreContext<'_, Ids> { pub fn unwrap_symmetric_key( &mut self, wrapping_key: Ids::Symmetric, - new_key_id: Ids::Symmetric, wrapped_key: &EncString, ) -> Result { let wrapping_key = self.get_symmetric_key(wrapping_key)?; @@ -183,6 +186,8 @@ impl KeyStoreContext<'_, Ids> { _ => return Err(CryptoError::InvalidKey), }; + let new_key_id = Ids::Symmetric::new_local(LocalId::new()); + #[allow(deprecated)] self.set_symmetric_key(new_key_id, key)?; @@ -301,20 +306,14 @@ impl KeyStoreContext<'_, Ids> { } /// 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::make_aes256_cbc_hmac_key(); - #[allow(deprecated)] - self.set_symmetric_key(key_id, key)?; - Ok(key_id) + pub fn generate_symmetric_key(&mut self) -> Result { + self.add_local_symmetric_key(SymmetricCryptoKey::make_aes256_cbc_hmac_key()) } /// Generate a new signature key using the current default algorithm, and store it in the /// context - pub fn make_signing_key(&mut self, key_id: Ids::Signing) -> Result { - let key = SigningKey::make(SignatureAlgorithm::default_algorithm()); - #[allow(deprecated)] - self.set_signing_key(key_id, key)?; - Ok(key_id) + pub fn make_signing_key(&mut self) -> Result { + self.add_local_signing_key(SigningKey::make(SignatureAlgorithm::default_algorithm())) } /// Derive a shareable key using hkdf from secret and name and store it in the context. @@ -323,11 +322,11 @@ impl KeyStoreContext<'_, Ids> { /// Bitwarden `clients` repository. pub fn derive_shareable_key( &mut self, - key_id: Ids::Symmetric, secret: Zeroizing<[u8; 16]>, name: &str, info: Option<&str>, ) -> Result { + let key_id = Ids::Symmetric::new_local(LocalId::new()); #[allow(deprecated)] self.set_symmetric_key( key_id, @@ -414,6 +413,13 @@ impl KeyStoreContext<'_, Ids> { Ok(()) } + /// Add a new symmetric key to the local context, returning a new unique identifier for it. + pub fn add_local_symmetric_key(&mut self, key: SymmetricCryptoKey) -> Result { + let key_id = Ids::Symmetric::new_local(LocalId::new()); + self.local_symmetric_keys.upsert(key_id, key); + Ok(key_id) + } + #[deprecated(note = "This function should ideally never be used outside this crate")] #[allow(missing_docs)] pub fn set_asymmetric_key( @@ -443,6 +449,13 @@ impl KeyStoreContext<'_, Ids> { Ok(()) } + /// Add a new signing key to the local context, returning a new unique identifier for it. + pub fn add_local_signing_key(&mut self, key: SigningKey) -> Result { + let key_id = Ids::Signing::new_local(LocalId::new()); + self.local_signing_keys.upsert(key_id, key); + Ok(key_id) + } + pub(crate) fn decrypt_data_with_symmetric_key( &self, key: Ids::Symmetric, @@ -525,7 +538,7 @@ mod tests { KeyStore, }, traits::tests::{TestIds, TestSigningKey, TestSymmKey}, - CompositeEncryptable, CryptoError, Decryptable, SignatureAlgorithm, SigningKey, + CompositeEncryptable, CryptoError, Decryptable, LocalId, SignatureAlgorithm, SigningKey, SigningNamespace, SymmetricCryptoKey, }; @@ -567,11 +580,12 @@ mod tests { #[test] fn test_key_encryption() { let store: KeyStore = KeyStore::default(); + let local = LocalId::new(); let mut ctx = store.context(); // Generate and insert a key - let key_1_id = TestSymmKey::C(1); + let key_1_id = TestSymmKey::C(local); let key_1 = SymmetricCryptoKey::make_aes256_cbc_hmac_key(); ctx.set_symmetric_key(key_1_id, key_1.clone()).unwrap(); @@ -579,7 +593,7 @@ mod tests { assert!(ctx.has_symmetric_key(key_1_id)); // Generate and insert a new key - let key_2_id = TestSymmKey::C(2); + let key_2_id = TestSymmKey::C(local); let key_2 = SymmetricCryptoKey::make_aes256_cbc_hmac_key(); ctx.set_symmetric_key(key_2_id, key_2.clone()).unwrap(); @@ -590,10 +604,7 @@ mod tests { let key_2_enc = ctx.wrap_symmetric_key(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.unwrap_symmetric_key(key_1_id, new_key_id, &key_2_enc) - .unwrap(); + let new_key_id = ctx.unwrap_symmetric_key(key_1_id, &key_2_enc).unwrap(); // Now `key_2_id` and `new_key_id` contain the same key, so we should be able to encrypt // with one and decrypt with the other @@ -646,24 +657,18 @@ mod tests { .unwrap(); // Unwrap the keys - let unwrapped_key_2 = ctx - .unwrap_symmetric_key(key_aes_1_id, key_aes_2_id, &wrapped_key_1_2) + let _unwrapped_key_2 = ctx + .unwrap_symmetric_key(key_aes_1_id, &wrapped_key_1_2) .unwrap(); - let unwrapped_key_3 = ctx - .unwrap_symmetric_key(key_aes_1_id, key_xchacha_3_id, &wrapped_key_1_3) + let _unwrapped_key_3 = ctx + .unwrap_symmetric_key(key_aes_1_id, &wrapped_key_1_3) .unwrap(); - let unwrapped_key_1 = ctx - .unwrap_symmetric_key(key_xchacha_3_id, key_aes_1_id, &wrapped_key_3_1) + let _unwrapped_key_1 = ctx + .unwrap_symmetric_key(key_xchacha_3_id, &wrapped_key_3_1) .unwrap(); - let unwrapped_key_4 = ctx - .unwrap_symmetric_key(key_xchacha_3_id, key_xchacha_4_id, &wrapped_key_3_4) + let _unwrapped_key_4 = ctx + .unwrap_symmetric_key(key_xchacha_3_id, &wrapped_key_3_4) .unwrap(); - - // Assert that the unwrapped keys are the same as the original keys - assert_eq!(unwrapped_key_2, key_aes_2_id); - assert_eq!(unwrapped_key_3, key_xchacha_3_id); - assert_eq!(unwrapped_key_1, key_aes_1_id); - assert_eq!(unwrapped_key_4, key_xchacha_4_id); } #[test] diff --git a/crates/bitwarden-crypto/src/store/mod.rs b/crates/bitwarden-crypto/src/store/mod.rs index 765762bac..55fd69d11 100644 --- a/crates/bitwarden-crypto/src/store/mod.rs +++ b/crates/bitwarden-crypto/src/store/mod.rs @@ -52,15 +52,19 @@ pub use context::KeyStoreContext; /// pub enum SymmKeyId { /// User, /// #[local] -/// Local(&'static str) +/// Local(LocalId), /// } /// #[asymmetric] /// pub enum AsymmKeyId { /// UserPrivate, +/// #[local] +/// Local(LocalId), /// } /// #[signing] /// pub enum SigningKeyId { /// UserSigning, +/// #[local] +/// Local(LocalId), /// } /// pub Ids => SymmKeyId, AsymmKeyId, SigningKeyId; /// } diff --git a/crates/bitwarden-crypto/src/traits/key_id.rs b/crates/bitwarden-crypto/src/traits/key_id.rs index b9f8082c4..a1b756d0d 100644 --- a/crates/bitwarden-crypto/src/traits/key_id.rs +++ b/crates/bitwarden-crypto/src/traits/key_id.rs @@ -24,6 +24,9 @@ pub trait KeyId: /// Returns whether the key is local to the current context or shared globally by the /// key store. See [crate::store::KeyStoreContext] for more information. fn is_local(&self) -> bool; + + /// Creates a new unique local key identifier. + fn new_local(id: LocalId) -> Self; } /// Represents a set of all the key identifiers that need to be defined to use a key store. @@ -37,6 +40,17 @@ pub trait KeyIds { type Signing: KeyId; } +/// An opaque identifier for a local key. Currently only contains a unique ID, but it can be +/// extended to contain scope information to allow cleanup on scope exit. +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd)] +pub struct LocalId(pub(crate) uuid::Uuid); + +impl LocalId { + pub(crate) fn new() -> Self { + LocalId(uuid::Uuid::new_v4()) + } +} + /// Just a small derive_like macro that can be used to generate the key identifier enums. /// Example usage: /// ```rust @@ -47,17 +61,21 @@ pub trait KeyIds { /// User, /// Org(uuid::Uuid), /// #[local] -/// Local(&'static str), +/// Local(LocalId), /// } /// /// #[asymmetric] /// pub enum AsymmKeyId { /// PrivateKey, +/// #[local] +/// Local(LocalId), /// } /// /// #[signing] /// pub enum SigningKeyId { /// SigningKey, +/// #[local] +/// Local(LocalId), /// } /// /// pub Ids => SymmKeyId, AsymmKeyId, SigningKeyId; @@ -76,6 +94,9 @@ macro_rules! key_ids { )+ $ids_vis:vis $ids_name:ident => $symm_name:ident, $asymm_name:ident, $signing_name:ident; ) => { + + use $crate::LocalId; + $( #[derive(std::fmt::Debug, Clone, Copy, std::hash::Hash, Eq, PartialEq, Ord, PartialOrd)] #[allow(missing_docs)] @@ -93,6 +114,12 @@ macro_rules! key_ids { key_ids!(@variant_value $( $variant_tag )? ), )* } } + + fn new_local(id: LocalId) -> Self { + $( + { key_ids!(@new_local $variant id $( $variant_tag )? ) } + )* + } } )+ @@ -114,27 +141,33 @@ macro_rules! key_ids { ( @variant_value local ) => { true }; ( @variant_value ) => { false }; + + ( @new_local $variant:ident $id:ident local ) => { Self::$variant($id) }; + ( @new_local $variant:ident $id:ident ) => {{}}; } #[cfg(test)] pub(crate) mod tests { + use crate::{ traits::tests::{TestAsymmKey, TestSigningKey, TestSymmKey}, - KeyId, + KeyId, LocalId, }; #[test] fn test_local() { + let local = LocalId::new(); + assert!(!TestSymmKey::A(0).is_local()); assert!(!TestSymmKey::B((4, 10)).is_local()); - assert!(TestSymmKey::C(8).is_local()); + assert!(TestSymmKey::C(local).is_local()); assert!(!TestAsymmKey::A(0).is_local()); assert!(!TestAsymmKey::B.is_local()); - assert!(TestAsymmKey::C("test").is_local()); + assert!(TestAsymmKey::C(local).is_local()); assert!(!TestSigningKey::A(0).is_local()); assert!(!TestSigningKey::B.is_local()); - assert!(TestSigningKey::C("test").is_local()); + assert!(TestSigningKey::C(local).is_local()); } } diff --git a/crates/bitwarden-crypto/src/traits/mod.rs b/crates/bitwarden-crypto/src/traits/mod.rs index 4b9bab2b6..54946075d 100644 --- a/crates/bitwarden-crypto/src/traits/mod.rs +++ b/crates/bitwarden-crypto/src/traits/mod.rs @@ -5,7 +5,7 @@ mod decryptable; pub use decryptable::Decryptable; pub(crate) mod key_id; -pub use key_id::{KeyId, KeyIds}; +pub use key_id::{KeyId, KeyIds, LocalId}; /// Types implementing [IdentifyKey] are capable of knowing which cryptographic key is /// needed to encrypt/decrypt them. @@ -27,7 +27,7 @@ pub(crate) mod tests { B((u8, u8)), #[local] - C(u8), + C(LocalId), } #[asymmetric] @@ -35,7 +35,7 @@ pub(crate) mod tests { A(u8), B, #[local] - C(&'static str), + C(LocalId), } #[signing] @@ -43,7 +43,7 @@ pub(crate) mod tests { A(u8), B, #[local] - C(&'static str), + C(LocalId), } pub TestIds => TestSymmKey, TestAsymmKey, TestSigningKey; diff --git a/crates/bitwarden-send/src/send.rs b/crates/bitwarden-send/src/send.rs index dc3af947d..1466364ab 100644 --- a/crates/bitwarden-send/src/send.rs +++ b/crates/bitwarden-send/src/send.rs @@ -146,8 +146,6 @@ pub struct SendListView { pub expiration_date: Option>, } -const SEND_KEY: SymmetricKeyId = SymmetricKeyId::Local("send_key"); - impl Send { #[allow(missing_docs)] pub fn get_key( @@ -164,7 +162,7 @@ impl Send { key: &[u8], ) -> Result { let key = Zeroizing::new(key.try_into().map_err(|_| CryptoError::InvalidKeyLen)?); - ctx.derive_shareable_key(SEND_KEY, key, "send", Some("send")) + ctx.derive_shareable_key(key, "send", Some("send")) } } diff --git a/crates/bitwarden-vault/src/cipher/attachment.rs b/crates/bitwarden-vault/src/cipher/attachment.rs index 213be72df..a123b595c 100644 --- a/crates/bitwarden-vault/src/cipher/attachment.rs +++ b/crates/bitwarden-vault/src/cipher/attachment.rs @@ -66,7 +66,6 @@ pub struct AttachmentFileView<'a> { pub attachment: AttachmentView, pub contents: &'a [u8], } -const ATTACHMENT_KEY: SymmetricKeyId = SymmetricKeyId::Local("attachment_key"); impl IdentifyKey for AttachmentFileView<'_> { fn key_identifier(&self) -> SymmetricKeyId { @@ -93,7 +92,7 @@ impl CompositeEncryptable // Because this is a new attachment, we have to generate a key for it, encrypt the contents // with it, and then encrypt the key with the cipher key - let attachment_key = ctx.generate_symmetric_key(ATTACHMENT_KEY)?; + let attachment_key = ctx.generate_symmetric_key()?; let encrypted_contents = OctetStreamBytes::from(self.contents).encrypt(ctx, attachment_key)?; attachment.key = Some(ctx.wrap_symmetric_key(ciphers_key, attachment_key)?); @@ -131,8 +130,7 @@ impl Decryptable> for AttachmentFile { // Version 2 or 3, `AttachmentKey` or `CipherKey(AttachmentKey)` if let Some(attachment_key) = &self.attachment.key { - let content_key = - ctx.unwrap_symmetric_key(ciphers_key, ATTACHMENT_KEY, attachment_key)?; + let content_key = ctx.unwrap_symmetric_key(ciphers_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 9d7032557..7915bbf10 100644 --- a/crates/bitwarden-vault/src/cipher/cipher.rs +++ b/crates/bitwarden-vault/src/cipher/cipher.rs @@ -389,9 +389,8 @@ impl Cipher { key: SymmetricKeyId, ciphers_key: &Option, ) -> Result { - const CIPHER_KEY: SymmetricKeyId = SymmetricKeyId::Local("cipher_key"); match ciphers_key { - Some(ciphers_key) => ctx.unwrap_symmetric_key(key, CIPHER_KEY, ciphers_key), + Some(ciphers_key) => ctx.unwrap_symmetric_key(key, ciphers_key), None => Ok(key), } } @@ -436,9 +435,7 @@ impl CipherView { ) -> Result<(), CryptoError> { let old_ciphers_key = Cipher::decrypt_cipher_key(ctx, key, &self.key)?; - const NEW_KEY: SymmetricKeyId = SymmetricKeyId::Local("new_cipher_key"); - - let new_key = ctx.generate_symmetric_key(NEW_KEY)?; + let new_key = ctx.generate_symmetric_key()?; self.reencrypt_attachment_keys(ctx, old_ciphers_key, new_key)?; self.reencrypt_fido2_credentials(ctx, old_ciphers_key, new_key)?; @@ -472,8 +469,8 @@ impl CipherView { if let Some(attachments) = &mut self.attachments { for attachment in attachments { if let Some(attachment_key) = &mut attachment.key { - let tmp_attachment_key_id = SymmetricKeyId::Local("attachment_key"); - ctx.unwrap_symmetric_key(old_key, tmp_attachment_key_id, attachment_key)?; + let tmp_attachment_key_id = + ctx.unwrap_symmetric_key(old_key, attachment_key)?; *attachment_key = ctx.wrap_symmetric_key(new_key, tmp_attachment_key_id)?; } } @@ -530,8 +527,7 @@ impl CipherView { // If the cipher has a key, we need to re-encrypt it with the new organization key if let Some(cipher_key) = &mut self.key { - let tmp_cipher_key_id = SymmetricKeyId::Local("cipher_key"); - ctx.unwrap_symmetric_key(old_key, tmp_cipher_key_id, cipher_key)?; + let tmp_cipher_key_id = ctx.unwrap_symmetric_key(old_key, cipher_key)?; *cipher_key = ctx.wrap_symmetric_key(new_key, tmp_cipher_key_id)?; } else { // If the cipher does not have a key, we need to reencrypt all attachment keys @@ -939,9 +935,8 @@ mod tests { let mut original_cipher = generate_cipher(); { - const CIPHER_KEY: SymmetricKeyId = SymmetricKeyId::Local("test_cipher_key"); let mut ctx = key_store.context(); - let cipher_key = ctx.generate_symmetric_key(CIPHER_KEY).unwrap(); + let cipher_key = ctx.generate_symmetric_key().unwrap(); original_cipher.key = Some( ctx.wrap_symmetric_key(SymmetricKeyId::User, cipher_key) @@ -956,12 +951,8 @@ mod tests { // Make sure that the cipher key is decryptable let wrapped_key = original_cipher.key.unwrap(); let mut ctx = key_store.context(); - ctx.unwrap_symmetric_key( - SymmetricKeyId::User, - SymmetricKeyId::Local("test_cipher_key"), - &wrapped_key, - ) - .unwrap(); + ctx.unwrap_symmetric_key(SymmetricKeyId::User, &wrapped_key) + .unwrap(); } #[test] @@ -1066,9 +1057,7 @@ mod tests { // Attachment has a key that is encrypted with the user key, as the cipher has no key itself let (attachment_key_enc, attachment_key_val) = { let mut ctx = key_store.context(); - let attachment_key = ctx - .generate_symmetric_key(SymmetricKeyId::Local("test_attachment_key")) - .unwrap(); + let attachment_key = ctx.generate_symmetric_key().unwrap(); let attachment_key_enc = ctx .wrap_symmetric_key(SymmetricKeyId::User, attachment_key) .unwrap(); @@ -1105,11 +1094,7 @@ mod tests { let new_attachment_key = cipher.attachments.unwrap()[0].key.clone().unwrap(); let mut ctx = key_store.context(); let new_attachment_key_id = ctx - .unwrap_symmetric_key( - org_key, - SymmetricKeyId::Local("test_attachment_key"), - &new_attachment_key, - ) + .unwrap_symmetric_key(org_key, &new_attachment_key) .unwrap(); #[allow(deprecated)] let new_attachment_key_dec = ctx @@ -1141,17 +1126,13 @@ mod tests { let mut ctx = key_store.context(); - let cipher_key = ctx - .generate_symmetric_key(SymmetricKeyId::Local("test_cipher_key")) - .unwrap(); + let cipher_key = ctx.generate_symmetric_key().unwrap(); let cipher_key_enc = ctx .wrap_symmetric_key(SymmetricKeyId::User, cipher_key) .unwrap(); // Attachment has a key that is encrypted with the cipher key - let attachment_key = ctx - .generate_symmetric_key(SymmetricKeyId::Local("test_attachment_key")) - .unwrap(); + let attachment_key = ctx.generate_symmetric_key().unwrap(); let attachment_key_enc = ctx.wrap_symmetric_key(cipher_key, attachment_key).unwrap(); let mut cipher = generate_cipher(); @@ -1175,11 +1156,7 @@ mod tests { // Check that the cipher key has been re-encrypted with the org key, let wrapped_new_cipher_key = cipher.key.clone().unwrap(); let new_cipher_key_dec = ctx - .unwrap_symmetric_key( - org_key, - SymmetricKeyId::Local("test_cipher_key"), - &wrapped_new_cipher_key, - ) + .unwrap_symmetric_key(org_key, &wrapped_new_cipher_key) .unwrap(); #[allow(deprecated)] let new_cipher_key_dec = ctx.dangerous_get_symmetric_key(new_cipher_key_dec).unwrap(); diff --git a/crates/bitwarden-wasm-internal/src/pure_crypto.rs b/crates/bitwarden-wasm-internal/src/pure_crypto.rs index 13ab4da05..63a24e6a2 100644 --- a/crates/bitwarden-wasm-internal/src/pure_crypto.rs +++ b/crates/bitwarden-wasm-internal/src/pure_crypto.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use bitwarden_core::key_management::{KeyIds, SymmetricKeyId}; +use bitwarden_core::key_management::KeyIds; use bitwarden_crypto::{ AsymmetricCryptoKey, AsymmetricPublicCryptoKey, BitwardenLegacyKeyBytes, CoseKeyBytes, CoseSerializable, CoseSign1Bytes, CryptoError, Decryptable, EncString, Kdf, KeyDecryptable, @@ -133,18 +133,13 @@ impl PureCrypto { let mut context = tmp_store.context(); let wrapping_key = SymmetricCryptoKey::try_from(&BitwardenLegacyKeyBytes::from(wrapping_key))?; - #[allow(deprecated)] - context.set_symmetric_key(SymmetricKeyId::Local("wrapping_key"), wrapping_key)?; + let wrapping_key = context.add_local_symmetric_key(wrapping_key)?; let key_to_be_wrapped = SymmetricCryptoKey::try_from(&BitwardenLegacyKeyBytes::from(key_to_be_wrapped))?; - #[allow(deprecated)] - context.set_symmetric_key(SymmetricKeyId::Local("key_to_wrap"), key_to_be_wrapped)?; + let key_to_wrap = context.add_local_symmetric_key(key_to_be_wrapped)?; // Note: The order of arguments is different here, and should probably be refactored Ok(context - .wrap_symmetric_key( - SymmetricKeyId::Local("wrapping_key"), - SymmetricKeyId::Local("key_to_wrap"), - )? + .wrap_symmetric_key(wrapping_key, key_to_wrap)? .to_string()) } @@ -158,16 +153,12 @@ impl PureCrypto { let mut context = tmp_store.context(); let wrapping_key = SymmetricCryptoKey::try_from(&BitwardenLegacyKeyBytes::from(wrapping_key))?; - #[allow(deprecated)] - context.set_symmetric_key(SymmetricKeyId::Local("wrapping_key"), wrapping_key)?; + let wrapping_key = context.add_local_symmetric_key(wrapping_key)?; // Note: The order of arguments is different here, and should probably be refactored - context.unwrap_symmetric_key( - SymmetricKeyId::Local("wrapping_key"), - SymmetricKeyId::Local("wrapped_key"), - &EncString::from_str(wrapped_key.as_str())?, - )?; + let unwrapped = context + .unwrap_symmetric_key(wrapping_key, &EncString::from_str(wrapped_key.as_str())?)?; #[allow(deprecated)] - let key = context.dangerous_get_symmetric_key(SymmetricKeyId::Local("wrapped_key"))?; + let key = context.dangerous_get_symmetric_key(unwrapped)?; Ok(key.to_encoded().to_vec()) } @@ -182,13 +173,11 @@ impl PureCrypto { ) -> Result { let tmp_store: KeyStore = KeyStore::default(); let mut context = tmp_store.context(); - #[allow(deprecated)] - context.set_symmetric_key( - SymmetricKeyId::Local("wrapping_key"), - SymmetricCryptoKey::try_from(&BitwardenLegacyKeyBytes::from(wrapping_key))?, - )?; + let wrapping_key = context.add_local_symmetric_key(SymmetricCryptoKey::try_from( + &BitwardenLegacyKeyBytes::from(wrapping_key), + )?)?; Ok(SpkiPublicKeyBytes::from(encapsulation_key) - .encrypt(&mut context, SymmetricKeyId::Local("wrapping_key"))? + .encrypt(&mut context, wrapping_key)? .to_string()) } @@ -200,13 +189,10 @@ impl PureCrypto { ) -> Result, CryptoError> { let tmp_store: KeyStore = KeyStore::default(); let mut context = tmp_store.context(); - #[allow(deprecated)] - context.set_symmetric_key( - SymmetricKeyId::Local("wrapping_key"), - SymmetricCryptoKey::try_from(&BitwardenLegacyKeyBytes::from(wrapping_key))?, - )?; - EncString::from_str(wrapped_key.as_str())? - .decrypt(&mut context, SymmetricKeyId::Local("wrapping_key")) + let wrapping_key = context.add_local_symmetric_key(SymmetricCryptoKey::try_from( + &BitwardenLegacyKeyBytes::from(wrapping_key), + )?)?; + EncString::from_str(wrapped_key.as_str())?.decrypt(&mut context, wrapping_key) } /// Wraps (encrypts) a PKCS8 DER encoded decapsulation (private) key using a symmetric wrapping @@ -217,13 +203,11 @@ impl PureCrypto { ) -> Result { let tmp_store: KeyStore = KeyStore::default(); let mut context = tmp_store.context(); - #[allow(deprecated)] - context.set_symmetric_key( - SymmetricKeyId::Local("wrapping_key"), - SymmetricCryptoKey::try_from(&BitwardenLegacyKeyBytes::from(wrapping_key))?, - )?; + let wrapping_key = context.add_local_symmetric_key(SymmetricCryptoKey::try_from( + &BitwardenLegacyKeyBytes::from(wrapping_key), + )?)?; Ok(Pkcs8PrivateKeyBytes::from(decapsulation_key) - .encrypt(&mut context, SymmetricKeyId::Local("wrapping_key"))? + .encrypt(&mut context, wrapping_key)? .to_string()) } @@ -235,13 +219,10 @@ impl PureCrypto { ) -> Result, CryptoError> { let tmp_store: KeyStore = KeyStore::default(); let mut context = tmp_store.context(); - #[allow(deprecated)] - context.set_symmetric_key( - SymmetricKeyId::Local("wrapping_key"), - SymmetricCryptoKey::try_from(&BitwardenLegacyKeyBytes::from(wrapping_key))?, - )?; - EncString::from_str(wrapped_key.as_str())? - .decrypt(&mut context, SymmetricKeyId::Local("wrapping_key")) + let wrapping_key = context.add_local_symmetric_key(SymmetricCryptoKey::try_from( + &BitwardenLegacyKeyBytes::from(wrapping_key), + )?)?; + EncString::from_str(wrapped_key.as_str())?.decrypt(&mut context, wrapping_key) } /// Encapsulates (encrypts) a symmetric key using an asymmetric encapsulation key (public key)