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