bitwarden_uniffi/auth/
mod.rs

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