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