bitwarden_user_crypto_management/public_key_encryption_key_pair_regeneration/
mod.rs1mod regenerate;
9mod should_regenerate;
10
11use bitwarden_core::key_management::account_cryptographic_state::WrappedAccountCryptographicState;
12use bitwarden_error::bitwarden_error;
13use bitwarden_vault::Cipher;
14use thiserror::Error;
15#[cfg(feature = "wasm")]
16use wasm_bindgen::prelude::*;
17
18use self::{
19 regenerate::internal_regenerate_public_key_encryption_key_pair,
20 should_regenerate::{
21 internal_should_regenerate_public_key_encryption_key_pair,
22 internal_should_regenerate_public_key_encryption_key_pair_with_ciphers,
23 },
24};
25use crate::UserCryptoManagementClient;
26
27#[derive(Debug, Error)]
28#[bitwarden_error(flat)]
29pub enum KeyPairRegenerationError {
30 #[error("User key is not available in key store")]
31 UserKeyNotAvailable,
32 #[error("API call failed during key pair regeneration")]
33 Api,
34 #[error("Cryptographic error during key pair regeneration")]
35 Crypto,
36}
37
38#[cfg_attr(feature = "wasm", wasm_bindgen)]
39impl UserCryptoManagementClient {
40 pub async fn regenerate_public_key_encryption_key_pair_if_needed(
49 &self,
50 ) -> Result<bool, KeyPairRegenerationError> {
51 let key_store = self.client.internal.get_key_store();
52 let api_client = &self.client.internal.get_api_configurations().api_client;
53 let should_regenerate =
54 internal_should_regenerate_public_key_encryption_key_pair(key_store, api_client)
55 .await?;
56 if !should_regenerate {
57 return Ok(false);
58 }
59
60 internal_regenerate_public_key_encryption_key_pair(key_store, api_client).await?;
61
62 let state_bridge = self.client.km_state_bridge();
63 if state_bridge.is_bridge_registered() {
64 let state = {
65 let ctx = key_store.context();
66 WrappedAccountCryptographicState::get_from_key_store(&ctx)
67 .map_err(|_| KeyPairRegenerationError::Crypto)?
68 };
69 state_bridge.set_account_cryptographic_state(&state).await;
70 }
71
72 Ok(true)
73 }
74
75 pub async fn should_regenerate_public_key_encryption_key_pair(
81 &self,
82 ) -> Result<bool, KeyPairRegenerationError> {
83 let key_store = self.client.internal.get_key_store();
84 let api_client = &self.client.internal.get_api_configurations().api_client;
85 internal_should_regenerate_public_key_encryption_key_pair(key_store, api_client).await
86 }
87
88 pub(crate) async fn regenerate_public_key_encryption_key_pair_if_needed_with_ciphers(
94 &self,
95 ciphers: &[Cipher],
96 ) -> Result<Option<WrappedAccountCryptographicState>, KeyPairRegenerationError> {
97 let key_store = self.client.internal.get_key_store();
98 let api_client = &self.client.internal.get_api_configurations().api_client;
99 let should_regenerate =
100 internal_should_regenerate_public_key_encryption_key_pair_with_ciphers(
101 key_store, api_client, ciphers,
102 )
103 .await?;
104 if !should_regenerate {
105 return Ok(None);
106 }
107
108 internal_regenerate_public_key_encryption_key_pair(key_store, api_client).await?;
109
110 let ctx = key_store.context();
111 let state = WrappedAccountCryptographicState::get_from_key_store(&ctx)
112 .map_err(|_| KeyPairRegenerationError::Crypto)?;
113 Ok(Some(state))
114 }
115}