Skip to main content

bitwarden_core/key_management/
mod.rs

1//! This module contains the definition for the key identifiers used by the rest of the crates.
2//! Any code that needs to interact with the [KeyStore] should use these types.
3//!
4//! - [SymmetricKeyId] is used to identify symmetric keys.
5//! - [PrivateKeyId] is used to identify private keys.
6//! - [KeyIds] is a helper type that combines both symmetric and private key identifiers. This is
7//!   usually used in the type bounds of [KeyStore],
8//!   [KeyStoreContext](bitwarden_crypto::KeyStoreContext),
9//!   [PrimitiveEncryptable](bitwarden_crypto::PrimitiveEncryptable),
10//!   [CompositeEncryptable](bitwarden_crypto::CompositeEncryptable), and
11//!   [Decryptable](bitwarden_crypto::Decryptable).
12
13use bitwarden_crypto::{
14    EncString, KeyStore, SymmetricCryptoKey, key_ids, safe::PasswordProtectedKeyEnvelope,
15};
16
17#[cfg(feature = "internal")]
18pub mod account_cryptographic_state;
19#[cfg(feature = "internal")]
20pub mod crypto;
21#[cfg(feature = "internal")]
22mod crypto_client;
23use bitwarden_encoding::B64;
24#[cfg(feature = "internal")]
25pub use crypto_client::CryptoClient;
26
27#[cfg(feature = "internal")]
28mod master_password;
29#[cfg(feature = "internal")]
30pub use master_password::{
31    MasterPasswordAuthenticationData, MasterPasswordError, MasterPasswordUnlockData,
32};
33#[cfg(feature = "internal")]
34mod security_state;
35#[cfg(feature = "internal")]
36pub use security_state::{
37    MINIMUM_ENFORCE_ICON_URI_HASH_VERSION, SecurityState, SignedSecurityState,
38};
39#[cfg(feature = "internal")]
40mod user_decryption;
41use serde::{Deserialize, Serialize};
42#[cfg(feature = "wasm")]
43use tsify::Tsify;
44#[cfg(feature = "internal")]
45pub use user_decryption::UserDecryptionData;
46#[cfg(feature = "internal")]
47mod v2_upgrade_token;
48#[cfg(feature = "internal")]
49pub use v2_upgrade_token::{V2UpgradeToken, V2UpgradeTokenError};
50
51#[cfg(all(feature = "internal", feature = "wasm"))]
52mod wasm_unlock_state;
53
54#[cfg(feature = "internal")]
55mod local_user_data_key;
56#[cfg(feature = "internal")]
57mod local_user_data_key_state;
58
59use crate::{OrganizationId, UserId};
60
61/// Represents the decrypted symmetric user-key of a user. This is held in ephemeral state of the
62/// client.
63#[derive(Serialize, Deserialize, Debug, Clone)]
64#[repr(transparent)]
65#[cfg_attr(feature = "wasm", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
66#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
67pub struct UserKeyState {
68    decrypted_user_key: B64,
69}
70
71bitwarden_state::register_repository_item!(String => UserKeyState, "UserKey");
72
73/// Represents the local user data key, wrapped by user key.
74/// This key is used to encrypt local user data (e.g., password generator history).
75#[derive(Serialize, Deserialize, Debug, Clone)]
76#[cfg_attr(feature = "wasm", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
77#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
78pub struct LocalUserDataKeyState {
79    wrapped_key: EncString,
80}
81
82bitwarden_state::register_repository_item!(UserId => LocalUserDataKeyState, "LocalUserDataKey");
83
84/// Represents the PIN envelope in memory, when ephemeral PIN unlock is used.
85#[derive(Serialize, Deserialize, Debug, Clone)]
86#[cfg_attr(feature = "wasm", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
87#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
88pub struct EphemeralPinEnvelopeState {
89    pin_envelope: PasswordProtectedKeyEnvelope,
90}
91
92bitwarden_state::register_repository_item!(String => EphemeralPinEnvelopeState, "EphemeralPinEnvelope");
93
94key_ids! {
95    #[symmetric]
96    pub enum SymmetricKeyId {
97        Master,
98        User,
99        Organization(OrganizationId),
100        LocalUserData,
101        #[local]
102        Local(LocalId),
103    }
104
105    #[private]
106    pub enum PrivateKeyId {
107        UserPrivateKey,
108        #[local]
109        Local(LocalId),
110    }
111
112    #[signing]
113    pub enum SigningKeyId {
114        UserSigningKey,
115        #[local]
116        Local(LocalId),
117    }
118
119    pub KeyIds => SymmetricKeyId, PrivateKeyId, SigningKeyId;
120}
121
122/// This is a helper function to create a test KeyStore with a single user key.
123/// While this function is not marked as #[cfg(test)], it should only be used for testing purposes.
124/// It's only public so that other crates can make use of it in their own tests.
125pub fn create_test_crypto_with_user_key(key: SymmetricCryptoKey) -> KeyStore<KeyIds> {
126    let store = KeyStore::default();
127
128    #[allow(deprecated)]
129    store
130        .context_mut()
131        .set_symmetric_key(SymmetricKeyId::User, key.clone())
132        .expect("Mutable context");
133
134    store
135}
136
137/// This is a helper function to create a test KeyStore with a single user key and an organization
138/// key using the provided organization uuid. While this function is not marked as #[cfg(test)], it
139/// should only be used for testing purposes. It's only public so that other crates can make use of
140/// it in their own tests.
141pub fn create_test_crypto_with_user_and_org_key(
142    key: SymmetricCryptoKey,
143    org_id: OrganizationId,
144    org_key: SymmetricCryptoKey,
145) -> KeyStore<KeyIds> {
146    let store = KeyStore::default();
147
148    #[allow(deprecated)]
149    store
150        .context_mut()
151        .set_symmetric_key(SymmetricKeyId::User, key.clone())
152        .expect("Mutable context");
153
154    #[allow(deprecated)]
155    store
156        .context_mut()
157        .set_symmetric_key(SymmetricKeyId::Organization(org_id), org_key.clone())
158        .expect("Mutable context");
159
160    store
161}