Skip to main content

bitwarden_user_crypto_management/key_rotation/
mod.rs

1//! Client to manage the cryptographic machinery of a user account, including key-rotation
2mod crypto;
3mod data;
4mod partial_rotateable_keyset;
5mod password_change_and_rotate_user_keys;
6mod rotate_user_keys;
7mod rotation_context;
8mod sync;
9mod unlock;
10mod unlock_method;
11
12use bitwarden_error::bitwarden_error;
13use serde::{Deserialize, Serialize};
14use thiserror::Error;
15#[cfg(feature = "wasm")]
16use tsify::Tsify;
17#[cfg(feature = "wasm")]
18use wasm_bindgen::prelude::*;
19
20use crate::{
21    UserCryptoManagementClient,
22    key_rotation::unlock::{V1EmergencyAccessMembership, V1OrganizationMembership},
23};
24
25/// Response model for untrusted memberships, containing both organization and emergency access
26/// memberships.
27#[derive(Serialize, Deserialize)]
28#[cfg_attr(feature = "wasm", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
29pub struct UntrustedMembershipsResponse {
30    emergency_access_memberships: Vec<V1EmergencyAccessMembership>,
31    organization_memberships: Vec<V1OrganizationMembership>,
32}
33
34#[cfg_attr(feature = "wasm", wasm_bindgen)]
35impl UserCryptoManagementClient {
36    /// Fetches the organization public keys for V1 organization memberships for the user for
37    /// organizations for which reset password is enrolled.
38    /// These have to be trusted manually be the user before rotating.
39    pub async fn get_untrusted_organization_public_keys(
40        &self,
41    ) -> Result<Vec<V1OrganizationMembership>, RotateUserKeysError> {
42        let api_client = &self.client.internal.get_api_configurations().api_client;
43        let key_rotation_data = sync::get_key_rotation_data(api_client)
44            .await
45            .map_err(|_| RotateUserKeysError::Api)?;
46        Ok(key_rotation_data.organization_memberships)
47    }
48
49    /// Fetches the emergency access public keys for V1 emergency access memberships for the user.
50    /// These have to be trusted manually be the user before rotating.
51    pub async fn get_untrusted_emergency_access_public_keys(
52        &self,
53    ) -> Result<Vec<V1EmergencyAccessMembership>, RotateUserKeysError> {
54        let api_client = &self.client.internal.get_api_configurations().api_client;
55        let key_rotation_data = sync::get_key_rotation_data(api_client)
56            .await
57            .map_err(|_| RotateUserKeysError::Api)?;
58        Ok(key_rotation_data.emergency_access_memberships)
59    }
60
61    /// Fetches all untrusted public keys from user's organization and emergency access memberships.
62    /// These have to be trusted manually by the user before rotating.
63    pub async fn get_untrusted_memberships(
64        &self,
65    ) -> Result<UntrustedMembershipsResponse, RotateUserKeysError> {
66        let api_client = &self.client.internal.get_api_configurations().api_client;
67        let key_rotation_data = sync::get_key_rotation_data(api_client)
68            .await
69            .map_err(|_| RotateUserKeysError::Api)?;
70        Ok(UntrustedMembershipsResponse {
71            emergency_access_memberships: key_rotation_data.emergency_access_memberships,
72            organization_memberships: key_rotation_data.organization_memberships,
73        })
74    }
75}
76
77/// Errors that can occur while converting key rotation data response models into their domain
78/// representations.
79#[allow(missing_docs)]
80#[derive(Debug, Error)]
81pub enum KeyRotationDataParseError {
82    #[error(transparent)]
83    MissingField(#[from] bitwarden_core::MissingFieldError),
84    #[error(transparent)]
85    Crypto(#[from] bitwarden_crypto::CryptoError),
86    #[error(transparent)]
87    B64(#[from] bitwarden_encoding::NotB64EncodedError),
88}
89
90#[derive(Debug, Error)]
91#[bitwarden_error(flat)]
92pub enum RotateUserKeysError {
93    #[error("API error during key rotation")]
94    Api,
95    #[error("Cryptographic error during key rotation")]
96    Crypto,
97    #[error("Invalid public key provided during key rotation")]
98    InvalidPublicKey,
99    #[error("Key Connector API error during key rotation")]
100    KeyConnectorApi,
101    #[error("Untrusted key encountered during key rotation")]
102    UntrustedKey,
103    #[error("Vault contains old attachments that must be re-uploaded before key rotation")]
104    OldAttachments,
105}