bitwarden_core/client/
encryption_settings.rs1use bitwarden_crypto::{AsymmetricCryptoKey, KeyStore, SymmetricCryptoKey};
2#[cfg(feature = "internal")]
3use bitwarden_crypto::{EncString, UnsignedSharedKey};
4use bitwarden_error::bitwarden_error;
5use thiserror::Error;
6use uuid::Uuid;
7
8use crate::{
9 key_management::{AsymmetricKeyId, KeyIds, SymmetricKeyId},
10 MissingPrivateKeyError, VaultLockedError,
11};
12
13#[bitwarden_error(flat)]
14#[derive(Debug, Error)]
15pub enum EncryptionSettingsError {
16 #[error("Cryptography error, {0}")]
17 Crypto(#[from] bitwarden_crypto::CryptoError),
18
19 #[error(transparent)]
20 InvalidBase64(#[from] base64::DecodeError),
21
22 #[error(transparent)]
23 VaultLocked(#[from] VaultLockedError),
24
25 #[error("Invalid private key")]
26 InvalidPrivateKey,
27
28 #[error(transparent)]
29 MissingPrivateKey(#[from] MissingPrivateKeyError),
30}
31
32pub struct EncryptionSettings {}
33
34impl EncryptionSettings {
35 #[cfg(feature = "internal")]
40 pub(crate) fn new_decrypted_key(
41 user_key: SymmetricCryptoKey,
42 private_key: EncString,
43 store: &KeyStore<KeyIds>,
44 ) -> Result<(), EncryptionSettingsError> {
45 use bitwarden_crypto::KeyDecryptable;
46 use log::warn;
47
48 use crate::key_management::{AsymmetricKeyId, SymmetricKeyId};
49
50 let private_key = {
51 let dec: Vec<u8> = private_key.decrypt_with_key(&user_key)?;
52
53 AsymmetricCryptoKey::from_der(&dec)
56 .map_err(|_| {
57 warn!("Invalid private key");
58 })
59 .ok()
60
61 };
66
67 #[allow(deprecated)]
69 {
70 let mut ctx = store.context_mut();
71 ctx.set_symmetric_key(SymmetricKeyId::User, user_key)?;
72 if let Some(private_key) = private_key {
73 ctx.set_asymmetric_key(AsymmetricKeyId::UserPrivateKey, private_key)?;
74 }
75 }
76
77 Ok(())
78 }
79
80 #[cfg(feature = "secrets")]
83 pub(crate) fn new_single_org_key(
84 organization_id: Uuid,
85 key: SymmetricCryptoKey,
86 store: &KeyStore<KeyIds>,
87 ) {
88 #[allow(deprecated)]
90 store
91 .context_mut()
92 .set_symmetric_key(SymmetricKeyId::Organization(organization_id), key)
93 .expect("Mutable context");
94 }
95
96 #[cfg(feature = "internal")]
97 pub(crate) fn set_org_keys(
98 org_enc_keys: Vec<(Uuid, UnsignedSharedKey)>,
99 store: &KeyStore<KeyIds>,
100 ) -> Result<(), EncryptionSettingsError> {
101 let mut ctx = store.context_mut();
102
103 if org_enc_keys.is_empty() {
105 return Ok(());
106 }
107
108 if !ctx.has_asymmetric_key(AsymmetricKeyId::UserPrivateKey) {
109 return Err(MissingPrivateKeyError.into());
110 }
111
112 ctx.retain_symmetric_keys(|key_ref| !matches!(key_ref, SymmetricKeyId::Organization(_)));
115
116 for (org_id, org_enc_key) in org_enc_keys {
118 ctx.decapsulate_key_unsigned(
119 AsymmetricKeyId::UserPrivateKey,
120 SymmetricKeyId::Organization(org_id),
121 &org_enc_key,
122 )?;
123 }
124
125 Ok(())
126 }
127}