diff --git a/crates/bitwarden-vault/src/cipher/attachment.rs b/crates/bitwarden-vault/src/cipher/attachment.rs index e37b6ad02..38ad7d6cd 100644 --- a/crates/bitwarden-vault/src/cipher/attachment.rs +++ b/crates/bitwarden-vault/src/cipher/attachment.rs @@ -36,6 +36,18 @@ pub struct AttachmentView { pub size_name: Option, pub file_name: Option, pub key: Option, + /// The decrypted attachmentkey in base64 format. + /// + /// **TEMPORARY FIELD**: This field is a temporary workaround to provide + /// decrypted attachment keys to the TypeScript client during the migration + /// process. It will be removed once the encryption/decryption logic is + /// fully migrated to the SDK. + /// + /// **Ticket**: + /// + /// Do not rely on this field for long-term use. + #[cfg(feature = "wasm")] + pub decrypted_key: Option, } #[allow(missing_docs)] @@ -160,6 +172,17 @@ impl Decryptable for Attachment { ctx: &mut KeyStoreContext, key: SymmetricKeyId, ) -> Result { + let decrypted_key = if let Some(attachment_key) = &self.key { + let content_key_id = ctx.unwrap_symmetric_key(key, ATTACHMENT_KEY, attachment_key)?; + + #[allow(deprecated)] + let actual_key = ctx.dangerous_get_symmetric_key(content_key_id)?; + + Some(actual_key.to_base64()) + } else { + None + }; + Ok(AttachmentView { id: self.id.clone(), url: self.url.clone(), @@ -167,6 +190,8 @@ impl Decryptable for Attachment { size_name: self.size_name.clone(), file_name: self.file_name.decrypt(ctx, key)?, key: self.key.clone(), + #[cfg(feature = "wasm")] + decrypted_key, }) } } @@ -223,6 +248,7 @@ mod tests { size_name: Some("100 Bytes".into()), file_name: Some("Test.txt".into()), key: None, + decrypted_key: None, }; let contents = b"This is a test file that we will encrypt. It's 100 bytes long, the encrypted version will be longer!"; @@ -279,6 +305,7 @@ mod tests { size_name: Some("161 Bytes".into()), file_name: Some("Test.txt".into()), key: Some("2.r288/AOSPiaLFkW07EBGBw==|SAmnnCbOLFjX5lnURvoualOetQwuyPc54PAmHDTRrhT0gwO9ailna9U09q9bmBfI5XrjNNEsuXssgzNygRkezoVQvZQggZddOwHB6KQW5EQ=|erIMUJp8j+aTcmhdE50zEX+ipv/eR1sZ7EwULJm/6DY=".parse().unwrap()), + decrypted_key: None, }; let cipher = Cipher { @@ -336,6 +363,7 @@ mod tests { size_name: Some("161 Bytes".into()), file_name: Some("Test.txt".into()), key: None, + decrypted_key: None, }; let cipher = Cipher { diff --git a/crates/bitwarden-vault/src/cipher/cipher.rs b/crates/bitwarden-vault/src/cipher/cipher.rs index 0d4c515dd..77754ba99 100644 --- a/crates/bitwarden-vault/src/cipher/cipher.rs +++ b/crates/bitwarden-vault/src/cipher/cipher.rs @@ -343,7 +343,7 @@ impl Decryptable for Cipher { permissions: self.permissions, view_password: self.view_password, local_data: self.local_data.decrypt(ctx, ciphers_key).ok().flatten(), - attachments: self.attachments.decrypt(ctx, ciphers_key).ok().flatten(), + attachments: self.attachments.decrypt(ctx, ciphers_key)?, fields: self.fields.decrypt(ctx, ciphers_key).ok().flatten(), password_history: self .password_history @@ -962,6 +962,7 @@ mod tests { size_name: None, file_name: Some("Attachment test name".into()), key: None, + decrypted_key: None, }; cipher.attachments = Some(vec![attachment]); @@ -1031,6 +1032,7 @@ mod tests { size_name: None, file_name: Some("Attachment test name".into()), key: None, + decrypted_key: None, }; cipher.attachments = Some(vec![attachment]); @@ -1074,6 +1076,7 @@ mod tests { size_name: None, file_name: Some("Attachment test name".into()), key: Some(attachment_key_enc), + decrypted_key: None, }; cipher.attachments = Some(vec![attachment]); let cred = generate_fido2(&mut key_store.context(), SymmetricKeyId::User); @@ -1141,6 +1144,7 @@ mod tests { size_name: None, file_name: Some("Attachment test name".into()), key: Some(attachment_key_enc.clone()), + decrypted_key: None, }; cipher.attachments = Some(vec![attachment]);