bitwarden_vault/cipher/
attachment_client.rs

1use std::path::Path;
2
3use bitwarden_core::Client;
4use bitwarden_crypto::EncString;
5use bitwarden_error::bitwarden_error;
6use thiserror::Error;
7#[cfg(feature = "wasm")]
8use wasm_bindgen::prelude::*;
9
10use crate::{
11    Attachment, AttachmentEncryptResult, AttachmentFile, AttachmentFileView, AttachmentView,
12    Cipher, DecryptError, EncryptError,
13};
14
15#[allow(missing_docs)]
16#[cfg_attr(feature = "wasm", wasm_bindgen)]
17pub struct AttachmentsClient {
18    pub(crate) client: Client,
19}
20
21/// Generic error type for vault encryption errors.
22#[allow(missing_docs)]
23#[bitwarden_error(flat)]
24#[derive(Debug, Error)]
25pub enum EncryptFileError {
26    #[error(transparent)]
27    Encrypt(#[from] EncryptError),
28    #[error(transparent)]
29    Io(#[from] std::io::Error),
30}
31
32/// Generic error type for decryption errors
33#[allow(missing_docs)]
34#[bitwarden_error(flat)]
35#[derive(Debug, Error)]
36pub enum DecryptFileError {
37    #[error(transparent)]
38    Decrypt(#[from] DecryptError),
39    #[error(transparent)]
40    Io(#[from] std::io::Error),
41}
42
43#[cfg_attr(feature = "wasm", wasm_bindgen)]
44impl AttachmentsClient {
45    #[allow(missing_docs)]
46    pub fn decrypt_buffer(
47        &self,
48        cipher: Cipher,
49        attachment: AttachmentView,
50        encrypted_buffer: &[u8],
51    ) -> Result<Vec<u8>, DecryptError> {
52        let key_store = self.client.internal.get_key_store();
53
54        Ok(key_store.decrypt(&AttachmentFile {
55            cipher,
56            attachment,
57            contents: EncString::from_buffer(encrypted_buffer)?,
58        })?)
59    }
60}
61
62impl AttachmentsClient {
63    #[allow(missing_docs)]
64    pub fn encrypt_buffer(
65        &self,
66        cipher: Cipher,
67        attachment: AttachmentView,
68        buffer: &[u8],
69    ) -> Result<AttachmentEncryptResult, EncryptError> {
70        let key_store = self.client.internal.get_key_store();
71
72        Ok(key_store.encrypt(AttachmentFileView {
73            cipher,
74            attachment,
75            contents: buffer,
76        })?)
77    }
78
79    #[allow(missing_docs)]
80    pub fn encrypt_file(
81        &self,
82        cipher: Cipher,
83        attachment: AttachmentView,
84        decrypted_file_path: &Path,
85        encrypted_file_path: &Path,
86    ) -> Result<Attachment, EncryptFileError> {
87        let data = std::fs::read(decrypted_file_path)?;
88        let AttachmentEncryptResult {
89            attachment,
90            contents,
91        } = self.encrypt_buffer(cipher, attachment, &data)?;
92        std::fs::write(encrypted_file_path, contents)?;
93        Ok(attachment)
94    }
95
96    #[allow(missing_docs)]
97    pub fn decrypt_file(
98        &self,
99        cipher: Cipher,
100        attachment: AttachmentView,
101        encrypted_file_path: &Path,
102        decrypted_file_path: &Path,
103    ) -> Result<(), DecryptFileError> {
104        let data = std::fs::read(encrypted_file_path)?;
105        let decrypted = self.decrypt_buffer(cipher, attachment, &data)?;
106        std::fs::write(decrypted_file_path, decrypted)?;
107        Ok(())
108    }
109}