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 pub fn next_vc_application_secret<Provider: OpenMlsProvider>(
31 &self,
32 provider: &Provider,
33 operation_context: &[u8],
34 ) -> Result<(VcApplicationSecretInfo, Vec<u8>), VirtualClientsError> {
35 let epoch_id = require_newest_vc_derivation_epoch(provider.storage(), self.group_id())?;
36 let (state, mut operation_tree) = load_vc_epoch_state_and_tree(provider, &epoch_id)?;
37 let (leaf_index, _epoch_encryption_key, emulation_ciphersuite) = state.into_parts();
38 let (generation, operation_secret) = operation_tree.next_operation_secret(
39 provider.crypto(),
40 emulation_ciphersuite,
41 &epoch_id,
42 leaf_index,
43 VirtualClientOperationType::Application,
44 operation_context,
45 )?;
46 provider
47 .storage()
48 .write_vc_operation_tree(&epoch_id, &operation_tree)
49 .map_err(|e| {
50 log::error!(
51 "vc: persist operation tree after allocating an application secret failed: {e:?}"
52 );
53 VirtualClientsError::StorageError
54 })?;
55 let info = VcApplicationSecretInfo {
56 epoch_id,
57 leaf_index,
58 generation,
59 };
60 Ok((info, operation_secret.as_slice().to_vec()))
61 }
62
63 pub fn derive_vc_application_secret<Provider: OpenMlsProvider>(
71 &self,
72 provider: &Provider,
73 info: &VcApplicationSecretInfo,
74 operation_context: &[u8],
75 ) -> Result<Vec<u8>, VirtualClientsError> {
76 let (state, mut operation_tree) = load_vc_epoch_state_and_tree(provider, &info.epoch_id)?;
77 let (own_leaf_index, _epoch_encryption_key, emulation_ciphersuite) = state.into_parts();
78 if info.leaf_index == own_leaf_index {
79 log::error!("vc: application secret coordinates name the caller's own leaf index.");
80 return Err(VirtualClientsError::OwnLeafIndex);
81 }
82 let operation_secret = operation_tree.derive_operation_secret(
83 provider.crypto(),
84 emulation_ciphersuite,
85 &info.epoch_id,
86 info.leaf_index,
87 VirtualClientOperationType::Application,
88 info.generation,
89 operation_context,
90 )?;
91 provider
92 .storage()
93 .write_vc_operation_tree(&info.epoch_id, &operation_tree)
94 .map_err(|e| {
95 log::error!(
96 "vc: persist operation tree after rederiving an application secret failed: {e:?}"
97 );
98 VirtualClientsError::StorageError
99 })?;
100 Ok(operation_secret.as_slice().to_vec())
101 }
102}