bitwarden_uniffi/auth/
mod.rs

1use bitwarden_core::auth::{
2    AuthRequestResponse, KeyConnectorResponse, RegisterKeyResponse, RegisterTdeKeyResponse,
3    password::MasterPasswordPolicyOptions,
4};
5use bitwarden_crypto::{EncString, HashPurpose, Kdf, TrustDeviceResponse, UnsignedSharedKey};
6use bitwarden_encoding::B64;
7
8use crate::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<B64> {
45        Ok(self
46            .0
47            .kdf()
48            .hash_password(email, password, kdf_params, purpose)
49            .await?)
50    }
51
52    /// Generate keys needed for registration process
53    pub fn make_register_keys(
54        &self,
55        email: String,
56        password: String,
57        kdf: Kdf,
58    ) -> Result<RegisterKeyResponse> {
59        Ok(self.0.auth().make_register_keys(email, password, kdf)?)
60    }
61
62    /// Generate keys needed for TDE process
63    pub fn make_register_tde_keys(
64        &self,
65        email: String,
66        org_public_key: B64,
67        remember_device: bool,
68    ) -> Result<RegisterTdeKeyResponse> {
69        Ok(self
70            .0
71            .auth()
72            .make_register_tde_keys(email, org_public_key, remember_device)?)
73    }
74
75    /// Generate keys needed to onboard a new user without master key to key connector
76    pub fn make_key_connector_keys(&self) -> Result<KeyConnectorResponse> {
77        Ok(self.0.auth().make_key_connector_keys()?)
78    }
79
80    /// Validate the user password
81    ///
82    /// To retrieve the user's password hash, use [`AuthClient::hash_password`] with
83    /// `HashPurpose::LocalAuthentication` during login and persist it. If the login method has no
84    /// password, use the email OTP.
85    pub fn validate_password(&self, password: String, password_hash: B64) -> Result<bool> {
86        Ok(self.0.auth().validate_password(password, password_hash)?)
87    }
88
89    /// Validate the user password without knowing the password hash
90    ///
91    /// Used for accounts that we know have master passwords but that have not logged in with a
92    /// password. Some example are login with device or TDE.
93    ///
94    /// This works by comparing the provided password against the encrypted user key.
95    pub fn validate_password_user_key(
96        &self,
97        password: String,
98        encrypted_user_key: String,
99    ) -> Result<B64> {
100        Ok(self
101            .0
102            .auth()
103            .validate_password_user_key(password, encrypted_user_key)?)
104    }
105
106    /// Validate the user PIN
107    ///
108    /// To validate the user PIN, you need to have the user's pin_protected_user_key. This key is
109    /// obtained when enabling PIN unlock on the account with the `derive_pin_key` method.
110    ///
111    /// This works by comparing the decrypted user key with the current user key, so the client must
112    /// be unlocked.
113    pub fn validate_pin(&self, pin: String, pin_protected_user_key: EncString) -> Result<bool> {
114        Ok(self.0.auth().validate_pin(pin, pin_protected_user_key)?)
115    }
116
117    /// Initialize a new auth request
118    pub fn new_auth_request(&self, email: String) -> Result<AuthRequestResponse> {
119        Ok(self.0.auth().new_auth_request(&email)?)
120    }
121
122    /// Approve an auth request
123    pub fn approve_auth_request(&self, public_key: B64) -> Result<UnsignedSharedKey> {
124        Ok(self.0.auth().approve_auth_request(public_key)?)
125    }
126
127    /// Trust the current device
128    pub fn trust_device(&self) -> Result<TrustDeviceResponse> {
129        Ok(self.0.auth().trust_device()?)
130    }
131}