bitwarden_core/client/
encryption_settings.rs

1#[cfg(any(feature = "internal", feature = "secrets"))]
2use bitwarden_crypto::KeyStore;
3#[cfg(feature = "secrets")]
4use bitwarden_crypto::SymmetricCryptoKey;
5#[cfg(feature = "internal")]
6use bitwarden_crypto::UnsignedSharedKey;
7use bitwarden_error::bitwarden_error;
8use thiserror::Error;
9#[cfg(feature = "internal")]
10use tracing::instrument;
11
12#[cfg(any(feature = "secrets", feature = "internal"))]
13use crate::OrganizationId;
14#[cfg(any(feature = "internal", feature = "secrets"))]
15use crate::key_management::{KeyIds, SymmetricKeyId};
16use crate::{MissingPrivateKeyError, error::UserIdAlreadySetError};
17
18#[allow(missing_docs)]
19#[bitwarden_error(flat)]
20#[derive(Debug, Error)]
21pub enum EncryptionSettingsError {
22    #[error("Cryptography error, {0}")]
23    Crypto(#[from] bitwarden_crypto::CryptoError),
24
25    #[error("Cryptography Initialization error")]
26    CryptoInitialization,
27
28    #[error(transparent)]
29    MissingPrivateKey(#[from] MissingPrivateKeyError),
30
31    #[error(transparent)]
32    UserIdAlreadySet(#[from] UserIdAlreadySetError),
33
34    #[error("Wrong Pin")]
35    WrongPin,
36}
37
38#[allow(missing_docs)]
39pub struct EncryptionSettings {}
40
41impl EncryptionSettings {
42    /// Initialize the encryption settings with only a single decrypted organization key.
43    /// This is used only for logging in Secrets Manager with an access token
44    #[cfg(feature = "secrets")]
45    pub(crate) fn new_single_org_key(
46        organization_id: OrganizationId,
47        key: SymmetricCryptoKey,
48        store: &KeyStore<KeyIds>,
49    ) {
50        // FIXME: [PM-18098] When this is part of crypto we won't need to use deprecated methods
51        #[allow(deprecated)]
52        store
53            .context_mut()
54            .set_symmetric_key(SymmetricKeyId::Organization(organization_id), key)
55            .expect("Mutable context");
56    }
57
58    #[cfg(feature = "internal")]
59    #[instrument(err, skip_all)]
60    pub(crate) fn set_org_keys(
61        org_enc_keys: Vec<(OrganizationId, UnsignedSharedKey)>,
62        store: &KeyStore<KeyIds>,
63    ) -> Result<(), EncryptionSettingsError> {
64        use crate::key_management::AsymmetricKeyId;
65
66        let mut ctx = store.context_mut();
67
68        // FIXME: [PM-11690] - Early abort to handle private key being corrupt
69        if org_enc_keys.is_empty() {
70            return Ok(());
71        }
72
73        if !ctx.has_asymmetric_key(AsymmetricKeyId::UserPrivateKey) {
74            return Err(MissingPrivateKeyError.into());
75        }
76
77        // Make sure we only keep the keys given in the arguments and not any of the previous
78        // ones, which might be from organizations that the user is no longer a part of anymore
79        ctx.retain_symmetric_keys(|key_ref| !matches!(key_ref, SymmetricKeyId::Organization(_)));
80
81        // Decrypt the org keys with the private key
82        for (org_id, org_enc_key) in org_enc_keys {
83            ctx.decapsulate_key_unsigned(
84                AsymmetricKeyId::UserPrivateKey,
85                SymmetricKeyId::Organization(org_id),
86                &org_enc_key,
87            )?;
88        }
89
90        Ok(())
91    }
92}