bitwarden_uniffi/auth/
mod.rs

1use bitwarden_core::auth::{
2    password::MasterPasswordPolicyOptions, AuthRequestResponse, KeyConnectorResponse,
3    RegisterKeyResponse, RegisterTdeKeyResponse,
4};
5use bitwarden_crypto::{EncString, HashPurpose, Kdf, TrustDeviceResponse, UnsignedSharedKey};
6use bitwarden_encoding::B64;
7
8use crate::error::{Error, Result};
9
10#[derive(uniffi::Object)]
11pub struct AuthClient(pub(crate) bitwarden_core::Client);
12
13#[uniffi::export(async_runtime = "tokio")]
14impl AuthClient {
15    /// Calculate Password Strength
16    pub fn password_strength(
17        &self,
18        password: String,
19        email: String,
20        additional_inputs: Vec<String>,
21    ) -> u8 {
22        self.0
23            .auth()
24            .password_strength(password, email, additional_inputs)
25    }
26
27    /// Evaluate if the provided password satisfies the provided policy
28    pub fn satisfies_policy(
29        &self,
30        password: String,
31        strength: u8,
32        policy: MasterPasswordPolicyOptions,
33    ) -> bool {
34        self.0.auth().satisfies_policy(password, strength, &policy)
35    }
36
37    /// Hash the user password
38    pub async fn hash_password(
39        &self,
40        email: String,
41        password: String,
42        kdf_params: Kdf,
43        purpose: HashPurpose,
44    ) -> Result<String> {
45        Ok(self
46            .0
47            .kdf()
48            .hash_password(email, password, kdf_params, purpose)
49            .await
50            .map_err(Error::Crypto)?)
51    }
52
53    /// Generate keys needed for registration process
54    pub fn make_register_keys(
55        &self,
56        email: String,
57        password: String,
58        kdf: Kdf,
59    ) -> Result<RegisterKeyResponse> {
60        Ok(self
61            .0
62            .auth()
63            .make_register_keys(email, password, kdf)
64            .map_err(Error::Crypto)?)
65    }
66
67    /// Generate keys needed for TDE process
68    pub fn make_register_tde_keys(
69        &self,
70        email: String,
71        org_public_key: B64,
72        remember_device: bool,
73    ) -> Result<RegisterTdeKeyResponse> {
74        Ok(self
75            .0
76            .auth()
77            .make_register_tde_keys(email, org_public_key, remember_device)
78            .map_err(Error::EncryptionSettings)?)
79    }
80
81    /// Generate keys needed to onboard a new user without master key to key connector
82    pub fn make_key_connector_keys(&self) -> Result<KeyConnectorResponse> {
83        Ok(self
84            .0
85            .auth()
86            .make_key_connector_keys()
87            .map_err(Error::Crypto)?)
88    }
89
90    /// Validate the user password
91    ///
92    /// To retrieve the user's password hash, use [`AuthClient::hash_password`] with
93    /// `HashPurpose::LocalAuthentication` during login and persist it. If the login method has no
94    /// password, use the email OTP.
95    pub fn validate_password(&self, password: String, password_hash: String) -> Result<bool> {
96        Ok(self
97            .0
98            .auth()
99            .validate_password(password, password_hash)
100            .map_err(Error::AuthValidate)?)
101    }
102
103    /// Validate the user password without knowing the password hash
104    ///
105    /// Used for accounts that we know have master passwords but that have not logged in with a
106    /// password. Some example are login with device or TDE.
107    ///
108    /// This works by comparing the provided password against the encrypted user key.
109    pub fn validate_password_user_key(
110        &self,
111        password: String,
112        encrypted_user_key: String,
113    ) -> Result<String> {
114        Ok(self
115            .0
116            .auth()
117            .validate_password_user_key(password, encrypted_user_key)
118            .map_err(Error::AuthValidate)?)
119    }
120
121    /// Validate the user PIN
122    ///
123    /// To validate the user PIN, you need to have the user's pin_protected_user_key. This key is
124    /// obtained when enabling PIN unlock on the account with the `derive_pin_key` method.
125    ///
126    /// This works by comparing the decrypted user key with the current user key, so the client must
127    /// be unlocked.
128    pub fn validate_pin(&self, pin: String, pin_protected_user_key: EncString) -> Result<bool> {
129        Ok(self
130            .0
131            .auth()
132            .validate_pin(pin, pin_protected_user_key)
133            .map_err(Error::AuthValidate)?)
134    }
135
136    /// Initialize a new auth request
137    pub fn new_auth_request(&self, email: String) -> Result<AuthRequestResponse> {
138        Ok(self
139            .0
140            .auth()
141            .new_auth_request(&email)
142            .map_err(Error::Crypto)?)
143    }
144
145    /// Approve an auth request
146    pub fn approve_auth_request(&self, public_key: String) -> Result<UnsignedSharedKey> {
147        Ok(self
148            .0
149            .auth()
150            .approve_auth_request(public_key)
151            .map_err(Error::ApproveAuthRequest)?)
152    }
153
154    /// Trust the current device
155    pub fn trust_device(&self) -> Result<TrustDeviceResponse> {
156        Ok(self.0.auth().trust_device().map_err(Error::TrustDevice)?)
157    }
158}