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
16use self::{
17 regenerate::internal_regenerate_public_key_encryption_key_pair,
18 should_regenerate::{
19 internal_should_regenerate_public_key_encryption_key_pair,
20 internal_should_regenerate_public_key_encryption_key_pair_with_ciphers,
21 },
22};
23use crate::UserCryptoManagementClient;
24
25#[derive(Debug, Error)]
26#[bitwarden_error(flat)]
27pub enum KeyPairRegenerationError {
28 #[error("User key is not available in key store")]
29 UserKeyNotAvailable,
30 #[error("API call failed during key pair regeneration")]
31 Api,
32 #[error("Cryptographic error during key pair regeneration")]
33 Crypto,
34}
35
36#[bitwarden_ffi::wasm_export]
37impl UserCryptoManagementClient {
38 pub async fn regenerate_public_key_encryption_key_pair_if_needed(
47 &self,
48 ) -> Result<bool, KeyPairRegenerationError> {
49 let key_store = self.client.internal.get_key_store();
50 let api_client = &self.client.internal.get_api_configurations().api_client;
51 let should_regenerate =
52 internal_should_regenerate_public_key_encryption_key_pair(key_store, api_client)
53 .await?;
54 if !should_regenerate {
55 return Ok(false);
56 }
57
58 internal_regenerate_public_key_encryption_key_pair(key_store, api_client).await?;
59
60 let state_bridge = self.client.km_state_bridge();
61 if state_bridge.is_bridge_registered() {
62 let state = {
63 let ctx = key_store.context();
64 WrappedAccountCryptographicState::get_from_key_store(&ctx)
65 .map_err(|_| KeyPairRegenerationError::Crypto)?
66 };
67 state_bridge.set_account_cryptographic_state(&state).await;
68 }
69
70 Ok(true)
71 }
72
73 pub async fn should_regenerate_public_key_encryption_key_pair(
79 &self,
80 ) -> Result<bool, KeyPairRegenerationError> {
81 let key_store = self.client.internal.get_key_store();
82 let api_client = &self.client.internal.get_api_configurations().api_client;
83 internal_should_regenerate_public_key_encryption_key_pair(key_store, api_client).await
84 }
85
86 pub(crate) async fn regenerate_public_key_encryption_key_pair_if_needed_with_ciphers(
92 &self,
93 ciphers: &[Cipher],
94 ) -> Result<Option<WrappedAccountCryptographicState>, KeyPairRegenerationError> {
95 let key_store = self.client.internal.get_key_store();
96 let api_client = &self.client.internal.get_api_configurations().api_client;
97 let should_regenerate =
98 internal_should_regenerate_public_key_encryption_key_pair_with_ciphers(
99 key_store, api_client, ciphers,
100 )
101 .await?;
102 if !should_regenerate {
103 return Ok(None);
104 }
105
106 internal_regenerate_public_key_encryption_key_pair(key_store, api_client).await?;
107
108 let ctx = key_store.context();
109 let state = WrappedAccountCryptographicState::get_from_key_store(&ctx)
110 .map_err(|_| KeyPairRegenerationError::Crypto)?;
111 Ok(Some(state))
112 }
113}