openmls/group/mls_group/
vc_application_secret.rs1use crate::components::{
2 vc_application_secret::VcApplicationSecretInfo,
3 vc_derivation_info::{
4 load_vc_epoch_state_and_tree, require_newest_vc_derivation_epoch,
5 VirtualClientOperationType, VirtualClientsError,
6 },
7};
8
9use super::*;
10
11impl MlsGroup {
12 #[openmls_traits::maybe_async]
31 pub async fn next_vc_application_secret<Provider: OpenMlsProvider>(
32 &self,
33 provider: &Provider,
34 operation_context: &[u8],
35 ) -> Result<(VcApplicationSecretInfo, Vec<u8>), VirtualClientsError> {
36 let epoch_id =
37 require_newest_vc_derivation_epoch(provider.storage(), self.group_id()).await?;
38 let (state, mut operation_tree) = load_vc_epoch_state_and_tree(provider, &epoch_id).await?;
39 let (leaf_index, _epoch_encryption_key, emulation_ciphersuite) = state.into_parts();
40 let (generation, operation_secret) = operation_tree.next_operation_secret(
41 provider.crypto(),
42 emulation_ciphersuite,
43 &epoch_id,
44 leaf_index,
45 VirtualClientOperationType::Application,
46 operation_context,
47 )?;
48 provider
49 .storage()
50 .write_vc_operation_tree(&epoch_id, &operation_tree)
51 .await
52 .map_err(|e| {
53 log::error!(
54 "vc: persist operation tree after allocating an application secret failed: {e:?}"
55 );
56 VirtualClientsError::StorageError
57 })?;
58 let info = VcApplicationSecretInfo {
59 epoch_id,
60 leaf_index,
61 generation,
62 };
63 Ok((info, operation_secret.as_slice().to_vec()))
64 }
65
66 #[openmls_traits::maybe_async]
74 pub async fn derive_vc_application_secret<Provider: OpenMlsProvider>(
75 &self,
76 provider: &Provider,
77 info: &VcApplicationSecretInfo,
78 operation_context: &[u8],
79 ) -> Result<Vec<u8>, VirtualClientsError> {
80 let (state, mut operation_tree) =
81 load_vc_epoch_state_and_tree(provider, &info.epoch_id).await?;
82 let (own_leaf_index, _epoch_encryption_key, emulation_ciphersuite) = state.into_parts();
83 if info.leaf_index == own_leaf_index {
84 log::error!("vc: application secret coordinates name the caller's own leaf index.");
85 return Err(VirtualClientsError::OwnLeafIndex);
86 }
87 let operation_secret = operation_tree.derive_operation_secret(
88 provider.crypto(),
89 emulation_ciphersuite,
90 &info.epoch_id,
91 info.leaf_index,
92 VirtualClientOperationType::Application,
93 info.generation,
94 operation_context,
95 )?;
96 provider
97 .storage()
98 .write_vc_operation_tree(&info.epoch_id, &operation_tree)
99 .await
100 .map_err(|e| {
101 log::error!(
102 "vc: persist operation tree after rederiving an application secret failed: {e:?}"
103 );
104 VirtualClientsError::StorageError
105 })?;
106 Ok(operation_secret.as_slice().to_vec())
107 }
108}