bitwarden_core/key_management/
crypto_client.rs

1use bitwarden_crypto::CryptoError;
2#[cfg(feature = "internal")]
3use bitwarden_crypto::{EncString, UnsignedSharedKey};
4#[cfg(feature = "wasm")]
5use wasm_bindgen::prelude::*;
6
7use super::crypto::{
8    derive_key_connector, make_key_pair, verify_asymmetric_keys, DeriveKeyConnectorError,
9    DeriveKeyConnectorRequest, EnrollAdminPasswordResetError, MakeKeyPairResponse,
10    VerifyAsymmetricKeysRequest, VerifyAsymmetricKeysResponse,
11};
12#[cfg(feature = "internal")]
13use crate::key_management::crypto::{
14    derive_pin_key, derive_pin_user_key, enroll_admin_password_reset, get_user_encryption_key,
15    initialize_org_crypto, initialize_user_crypto, update_password, DerivePinKeyResponse,
16    InitOrgCryptoRequest, InitUserCryptoRequest, UpdatePasswordResponse,
17};
18use crate::{
19    client::encryption_settings::EncryptionSettingsError,
20    error::StatefulCryptoError,
21    key_management::crypto::{
22        get_v2_rotated_account_keys, make_v2_keys_for_v1_user, CryptoClientError,
23        UserCryptoV2KeysResponse,
24    },
25    Client,
26};
27
28/// A client for the crypto operations.
29#[cfg_attr(feature = "wasm", wasm_bindgen)]
30pub struct CryptoClient {
31    pub(crate) client: crate::Client,
32}
33
34#[cfg_attr(feature = "wasm", wasm_bindgen)]
35impl CryptoClient {
36    /// Initialization method for the user crypto. Needs to be called before any other crypto
37    /// operations.
38    pub async fn initialize_user_crypto(
39        &self,
40        req: InitUserCryptoRequest,
41    ) -> Result<(), EncryptionSettingsError> {
42        initialize_user_crypto(&self.client, req).await
43    }
44
45    /// Initialization method for the organization crypto. Needs to be called after
46    /// `initialize_user_crypto` but before any other crypto operations.
47    pub async fn initialize_org_crypto(
48        &self,
49        req: InitOrgCryptoRequest,
50    ) -> Result<(), EncryptionSettingsError> {
51        initialize_org_crypto(&self.client, req).await
52    }
53
54    /// Generates a new key pair and encrypts the private key with the provided user key.
55    /// Crypto initialization not required.
56    pub fn make_key_pair(&self, user_key: String) -> Result<MakeKeyPairResponse, CryptoError> {
57        make_key_pair(user_key)
58    }
59
60    /// Verifies a user's asymmetric keys by decrypting the private key with the provided user
61    /// key. Returns if the private key is decryptable and if it is a valid matching key.
62    /// Crypto initialization not required.
63    pub fn verify_asymmetric_keys(
64        &self,
65        request: VerifyAsymmetricKeysRequest,
66    ) -> Result<VerifyAsymmetricKeysResponse, CryptoError> {
67        verify_asymmetric_keys(request)
68    }
69
70    /// Makes a new signing key pair and signs the public key for the user
71    pub fn make_keys_for_user_crypto_v2(
72        &self,
73    ) -> Result<UserCryptoV2KeysResponse, StatefulCryptoError> {
74        make_v2_keys_for_v1_user(&self.client)
75    }
76
77    /// Creates a rotated set of account keys for the current state
78    pub fn get_v2_rotated_account_keys(
79        &self,
80    ) -> Result<UserCryptoV2KeysResponse, StatefulCryptoError> {
81        get_v2_rotated_account_keys(&self.client)
82    }
83}
84
85impl CryptoClient {
86    /// Get the uses's decrypted encryption key. Note: It's very important
87    /// to keep this key safe, as it can be used to decrypt all of the user's data
88    pub async fn get_user_encryption_key(&self) -> Result<String, CryptoClientError> {
89        get_user_encryption_key(&self.client).await
90    }
91
92    /// Update the user's password, which will re-encrypt the user's encryption key with the new
93    /// password. This returns the new encrypted user key and the new password hash.
94    pub fn update_password(
95        &self,
96        new_password: String,
97    ) -> Result<UpdatePasswordResponse, CryptoClientError> {
98        update_password(&self.client, new_password)
99    }
100
101    /// Generates a PIN protected user key from the provided PIN. The result can be stored and later
102    /// used to initialize another client instance by using the PIN and the PIN key with
103    /// `initialize_user_crypto`.
104    pub fn derive_pin_key(&self, pin: String) -> Result<DerivePinKeyResponse, CryptoClientError> {
105        derive_pin_key(&self.client, pin)
106    }
107
108    /// Derives the pin protected user key from encrypted pin. Used when pin requires master
109    /// password on first unlock.
110    pub fn derive_pin_user_key(
111        &self,
112        encrypted_pin: EncString,
113    ) -> Result<EncString, CryptoClientError> {
114        derive_pin_user_key(&self.client, encrypted_pin)
115    }
116
117    /// Prepares the account for being enrolled in the admin password reset feature. This encrypts
118    /// the users [UserKey][bitwarden_crypto::UserKey] with the organization's public key.
119    pub fn enroll_admin_password_reset(
120        &self,
121        public_key: String,
122    ) -> Result<UnsignedSharedKey, EnrollAdminPasswordResetError> {
123        enroll_admin_password_reset(&self.client, public_key)
124    }
125
126    /// Derive the master key for migrating to the key connector
127    pub fn derive_key_connector(
128        &self,
129        request: DeriveKeyConnectorRequest,
130    ) -> Result<String, DeriveKeyConnectorError> {
131        derive_key_connector(request)
132    }
133}
134
135impl Client {
136    /// Access to crypto functionality.
137    pub fn crypto(&self) -> CryptoClient {
138        CryptoClient {
139            client: self.clone(),
140        }
141    }
142}