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