bitwarden_core/auth/
tde.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use base64::{engine::general_purpose::STANDARD, Engine};
use bitwarden_crypto::{
    AsymmetricEncString, AsymmetricPublicCryptoKey, DeviceKey, EncString, Kdf, SymmetricCryptoKey,
    TrustDeviceResponse, UserKey,
};

use crate::{error::Result, Client};

/// This function generates a new user key and key pair, initializes the client's crypto with the
/// generated user key, and encrypts the user key with the organization public key for admin
/// password reset. If remember_device is true, it also generates a device key.
pub(super) fn make_register_tde_keys(
    client: &Client,
    email: String,
    org_public_key: String,
    remember_device: bool,
) -> Result<RegisterTdeKeyResponse> {
    let public_key = AsymmetricPublicCryptoKey::from_der(&STANDARD.decode(org_public_key)?)?;

    let mut rng = rand::thread_rng();

    let user_key = UserKey::new(SymmetricCryptoKey::generate(&mut rng));
    let key_pair = user_key.make_key_pair()?;

    let admin_reset =
        AsymmetricEncString::encrypt_rsa2048_oaep_sha1(&user_key.0.to_vec(), &public_key)?;

    let device_key = if remember_device {
        Some(DeviceKey::trust_device(&user_key.0)?)
    } else {
        None
    };

    client
        .internal
        .set_login_method(crate::client::LoginMethod::User(
            crate::client::UserLoginMethod::Username {
                client_id: "".to_owned(),
                email,
                kdf: Kdf::default(),
            },
        ));
    client
        .internal
        .initialize_user_crypto_decrypted_key(user_key.0, key_pair.private.clone())?;

    Ok(RegisterTdeKeyResponse {
        private_key: key_pair.private,
        public_key: key_pair.public,

        admin_reset,
        device_key,
    })
}

#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
pub struct RegisterTdeKeyResponse {
    pub private_key: EncString,
    pub public_key: String,

    pub admin_reset: AsymmetricEncString,
    pub device_key: Option<TrustDeviceResponse>,
}