bitwarden_core/client/
encryption_settings.rs1#[cfg(feature = "internal")]
2use bitwarden_crypto::{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(any(feature = "internal", feature = "secrets"))]
11use crate::key_management::{KeyIds, SymmetricKeyId};
12use crate::{error::UserIdAlreadySetError, MissingPrivateKeyError, VaultLockedError};
13
14#[allow(missing_docs)]
15#[bitwarden_error(flat)]
16#[derive(Debug, Error)]
17pub enum EncryptionSettingsError {
18 #[error("Cryptography error, {0}")]
19 Crypto(#[from] bitwarden_crypto::CryptoError),
20
21 #[error(transparent)]
22 InvalidBase64(#[from] base64::DecodeError),
23
24 #[error(transparent)]
25 VaultLocked(#[from] VaultLockedError),
26
27 #[error("Invalid private key")]
28 InvalidPrivateKey,
29
30 #[error("Invalid signing key")]
31 InvalidSigningKey,
32
33 #[error(transparent)]
34 MissingPrivateKey(#[from] MissingPrivateKeyError),
35
36 #[error(transparent)]
37 UserIdAlreadySetError(#[from] UserIdAlreadySetError),
38}
39
40#[allow(missing_docs)]
41pub struct EncryptionSettings {}
42
43impl EncryptionSettings {
44 #[cfg(feature = "internal")]
49 pub(crate) fn new_decrypted_key(
50 user_key: SymmetricCryptoKey,
51 private_key: EncString,
52 signing_key: Option<EncString>,
53 store: &KeyStore<KeyIds>,
54 ) -> Result<(), EncryptionSettingsError> {
55 use bitwarden_crypto::{AsymmetricCryptoKey, CoseSerializable, KeyDecryptable, SigningKey};
56 use log::warn;
57
58 use crate::key_management::{AsymmetricKeyId, SigningKeyId, SymmetricKeyId};
59
60 let private_key = {
61 let dec: Vec<u8> = private_key.decrypt_with_key(&user_key)?;
62 AsymmetricCryptoKey::from_der(&dec.into())
65 .map_err(|_| {
66 warn!("Invalid private key");
67 })
68 .ok()
69
70 };
75 let signing_key = signing_key
76 .map(|key| {
77 use bitwarden_crypto::CryptoError;
78
79 let dec: Vec<u8> = key.decrypt_with_key(&user_key)?;
80 SigningKey::from_cose(&dec.into()).map_err(Into::<CryptoError>::into)
81 })
82 .transpose()?;
83
84 #[allow(deprecated)]
86 {
87 let mut ctx = store.context_mut();
88 ctx.set_symmetric_key(SymmetricKeyId::User, user_key)?;
89 if let Some(private_key) = private_key {
90 ctx.set_asymmetric_key(AsymmetricKeyId::UserPrivateKey, private_key)?;
91 }
92
93 if let Some(signing_key) = signing_key {
94 ctx.set_signing_key(SigningKeyId::UserSigningKey, signing_key)?;
95 }
96 }
97
98 Ok(())
99 }
100
101 #[cfg(feature = "secrets")]
104 pub(crate) fn new_single_org_key(
105 organization_id: Uuid,
106 key: SymmetricCryptoKey,
107 store: &KeyStore<KeyIds>,
108 ) {
109 #[allow(deprecated)]
111 store
112 .context_mut()
113 .set_symmetric_key(SymmetricKeyId::Organization(organization_id), key)
114 .expect("Mutable context");
115 }
116
117 #[cfg(feature = "internal")]
118 pub(crate) fn set_org_keys(
119 org_enc_keys: Vec<(Uuid, UnsignedSharedKey)>,
120 store: &KeyStore<KeyIds>,
121 ) -> Result<(), EncryptionSettingsError> {
122 use crate::key_management::AsymmetricKeyId;
123
124 let mut ctx = store.context_mut();
125
126 if org_enc_keys.is_empty() {
128 return Ok(());
129 }
130
131 if !ctx.has_asymmetric_key(AsymmetricKeyId::UserPrivateKey) {
132 return Err(MissingPrivateKeyError.into());
133 }
134
135 ctx.retain_symmetric_keys(|key_ref| !matches!(key_ref, SymmetricKeyId::Organization(_)));
138
139 for (org_id, org_enc_key) in org_enc_keys {
141 ctx.decapsulate_key_unsigned(
142 AsymmetricKeyId::UserPrivateKey,
143 SymmetricKeyId::Organization(org_id),
144 &org_enc_key,
145 )?;
146 }
147
148 Ok(())
149 }
150}