core_crypto/transaction_context/
key_package.rs

1//! This module contains all transactional behavior related to key packages
2
3use openmls::prelude::{KeyPackage, KeyPackageRef};
4
5use crate::{
6    RecursiveError,
7    prelude::{MlsCiphersuite, MlsCredentialType},
8};
9
10use super::{Error, Result, TransactionContext};
11
12impl TransactionContext {
13    /// Returns `amount_requested` OpenMLS [openmls::key_packages::KeyPackage]s.
14    /// Will always return the requested amount as it will generate the necessary (lacking) amount on-the-fly
15    ///
16    /// Note: Keypackage pruning is performed as a first step
17    ///
18    /// # Arguments
19    /// * `amount_requested` - number of KeyPackages to request and fill the `KeyPackageBundle`
20    ///
21    /// # Return type
22    /// A vector of `KeyPackageBundle`
23    ///
24    /// # Errors
25    /// Errors can happen when accessing the KeyStore
26    pub async fn get_or_create_client_keypackages(
27        &self,
28        ciphersuite: MlsCiphersuite,
29        credential_type: MlsCredentialType,
30        amount_requested: usize,
31    ) -> Result<Vec<KeyPackage>> {
32        let session = self.session().await?;
33        session
34            .request_key_packages(
35                amount_requested,
36                ciphersuite,
37                credential_type,
38                &self.mls_provider().await?,
39            )
40            .await
41            .map_err(RecursiveError::mls_client("requesting key packages"))
42            .map_err(Into::into)
43    }
44
45    /// Returns the count of valid, non-expired, unclaimed keypackages in store for the given [MlsCiphersuite] and [MlsCredentialType]
46    pub async fn client_valid_key_packages_count(
47        &self,
48        ciphersuite: MlsCiphersuite,
49        credential_type: MlsCredentialType,
50    ) -> Result<usize> {
51        let session = self.session().await?;
52        session
53            .valid_keypackages_count(&self.mls_provider().await?, ciphersuite, credential_type)
54            .await
55            .map_err(RecursiveError::mls_client("counting valid key packages"))
56            .map_err(Into::into)
57    }
58
59    /// Prunes local KeyPackages after making sure they also have been deleted on the backend side
60    /// You should only use this after [TransactionContext::save_x509_credential]
61    pub async fn delete_keypackages(&self, refs: &[KeyPackageRef]) -> Result<()> {
62        if refs.is_empty() {
63            return Err(Error::CallerError("The provided keypackage list was empty"));
64        }
65        let mut session = self.session().await?;
66        session
67            .prune_keypackages_and_credential(&self.mls_provider().await?, refs)
68            .await
69            .map_err(RecursiveError::mls_client("pruning key packages and credential"))
70            .map_err(Into::into)
71    }
72}