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//! - [SymmetricKeySlotId] is used to identify symmetric keys.
5//! - [PrivateKeySlotId] is used to identify private keys.
6//! - [KeySlotIds] is a helper type that combines both symmetric and private key identifiers. This
7//!   is 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_slot_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    BLOB_SECURITY_VERSION, MINIMUM_ENFORCE_ICON_URI_HASH_VERSION, SecurityState,
38    SignedSecurityState,
39};
40#[cfg(feature = "internal")]
41mod user_decryption;
42use serde::{Deserialize, Serialize};
43#[cfg(feature = "wasm")]
44use tsify::Tsify;
45#[cfg(feature = "internal")]
46pub use user_decryption::UserDecryptionData;
47#[cfg(feature = "internal")]
48mod v2_upgrade_token;
49#[cfg(feature = "internal")]
50pub use v2_upgrade_token::{V2UpgradeToken, V2UpgradeTokenError};
51#[cfg(feature = "internal")]
52mod webauthn_prf;
53#[cfg(feature = "internal")]
54pub use webauthn_prf::{WebAuthnPrfError, WebAuthnPrfUnlockData, WebAuthnPrfUnlockOption};
55
56#[cfg(all(feature = "internal", feature = "wasm"))]
57mod wasm_unlock_state;
58
59#[cfg(feature = "internal")]
60mod pin_lock_system;
61#[cfg(feature = "internal")]
62pub use pin_lock_system::{PinLockSystem, PinLockType, PinUnlockStatus};
63
64#[cfg(feature = "internal")]
65mod local_user_data_key;
66#[cfg(feature = "internal")]
67mod local_user_data_key_state;
68
69/// A temporary bridge to access KM-related state from within the SDK.
70#[cfg(feature = "internal")]
71pub mod state_bridge;
72
73use crate::{OrganizationId, UserId};
74
75/// Represents the decrypted symmetric user-key of a user. This is held in ephemeral state of the
76/// client.
77#[derive(Serialize, Deserialize, Debug, Clone)]
78#[repr(transparent)]
79#[cfg_attr(feature = "wasm", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
80#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
81pub struct UserKeyState {
82    decrypted_user_key: B64,
83}
84
85bitwarden_state::register_repository_item!(String => UserKeyState, "UserKey");
86
87/// Represents the local user data key, wrapped by user key.
88/// This key is used to encrypt local user data (e.g., password generator history).
89#[derive(Serialize, Deserialize, Debug, Clone)]
90#[cfg_attr(feature = "wasm", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
91#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
92pub struct LocalUserDataKeyState {
93    wrapped_key: EncString,
94}
95
96bitwarden_state::register_repository_item!(UserId => LocalUserDataKeyState, "LocalUserDataKey");
97
98/// Represents the PIN envelope in memory, when ephemeral PIN unlock is used.
99#[derive(Serialize, Deserialize, Debug, Clone)]
100#[cfg_attr(feature = "wasm", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
101#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
102pub struct EphemeralPinEnvelopeState {
103    pin_envelope: PasswordProtectedKeyEnvelope,
104}
105
106bitwarden_state::register_repository_item!(String => EphemeralPinEnvelopeState, "EphemeralPinEnvelope");
107
108key_slot_ids! {
109    #[symmetric]
110    pub enum SymmetricKeySlotId {
111        Master,
112        User,
113        Organization(OrganizationId),
114        LocalUserData,
115        #[local]
116        Local(LocalId),
117    }
118
119    #[private]
120    pub enum PrivateKeySlotId {
121        UserPrivateKey,
122        #[local]
123        Local(LocalId),
124    }
125
126    #[signing]
127    pub enum SigningKeySlotId {
128        UserSigningKey,
129        #[local]
130        Local(LocalId),
131    }
132
133    pub KeySlotIds => SymmetricKeySlotId, PrivateKeySlotId, SigningKeySlotId;
134}
135
136/// This is a helper function to create a test KeyStore with a single user key.
137/// While this function is not marked as #[cfg(test)], it should only be used for testing purposes.
138/// It's only public so that other crates can make use of it in their own tests.
139pub fn create_test_crypto_with_user_key(key: SymmetricCryptoKey) -> KeyStore<KeySlotIds> {
140    let store = KeyStore::default();
141
142    #[allow(deprecated)]
143    store
144        .context_mut()
145        .set_symmetric_key(SymmetricKeySlotId::User, key.clone())
146        .expect("Mutable context");
147
148    store
149}
150
151/// This is a helper function to create a test KeyStore with a single user key and an organization
152/// key using the provided organization uuid. While this function is not marked as #[cfg(test)], it
153/// should only be used for testing purposes. It's only public so that other crates can make use of
154/// it in their own tests.
155pub fn create_test_crypto_with_user_and_org_key(
156    key: SymmetricCryptoKey,
157    org_id: OrganizationId,
158    org_key: SymmetricCryptoKey,
159) -> KeyStore<KeySlotIds> {
160    let store = KeyStore::default();
161
162    #[allow(deprecated)]
163    store
164        .context_mut()
165        .set_symmetric_key(SymmetricKeySlotId::User, key.clone())
166        .expect("Mutable context");
167
168    #[allow(deprecated)]
169    store
170        .context_mut()
171        .set_symmetric_key(SymmetricKeySlotId::Organization(org_id), org_key.clone())
172        .expect("Mutable context");
173
174    store
175}