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