core_crypto/mls/conversation/
welcome.rs1use super::{Error, Result};
2use crate::{
3 LeafError, MlsError,
4 e2e_identity::NewCrlDistributionPoints,
5 group_store::GroupStore,
6 prelude::{ConversationId, MlsConversation, MlsConversationConfiguration},
7};
8use core_crypto_keystore::{connection::FetchFromDatabase, entities::PersistedMlsPendingGroup};
9use mls_crypto_provider::MlsCryptoProvider;
10use openmls::prelude::{MlsGroup, Welcome};
11use openmls_traits::OpenMlsCryptoProvider;
12
13#[derive(Debug)]
15pub struct WelcomeBundle {
16 pub id: ConversationId,
18 pub crl_new_distribution_points: NewCrlDistributionPoints,
20}
21
22impl MlsConversation {
23 pub(crate) async fn from_welcome_message(
34 welcome: Welcome,
35 configuration: MlsConversationConfiguration,
36 backend: &MlsCryptoProvider,
37 mls_groups: &mut GroupStore<MlsConversation>,
38 ) -> Result<Self> {
39 let mls_group_config = configuration.as_openmls_default_configuration()?;
40
41 let group = MlsGroup::new_from_welcome(backend, &mls_group_config, welcome, None).await;
42
43 let group = match group {
44 Err(openmls::prelude::WelcomeError::NoMatchingKeyPackage)
45 | Err(openmls::prelude::WelcomeError::NoMatchingEncryptionKey) => return Err(Error::OrphanWelcome),
46 _ => group.map_err(MlsError::wrap("group could not be created from welcome"))?,
47 };
48
49 let id = ConversationId::from(group.group_id().as_slice());
50 let existing_conversation = mls_groups.get_fetch(&id[..], &backend.keystore(), None).await;
51 let conversation_exists = existing_conversation.ok().flatten().is_some();
52
53 let pending_group = backend.key_store().find::<PersistedMlsPendingGroup>(&id[..]).await;
54 let pending_group_exists = pending_group.ok().flatten().is_some();
55
56 if conversation_exists || pending_group_exists {
57 return Err(LeafError::ConversationAlreadyExists(id).into());
58 }
59
60 Self::from_mls_group(group, configuration, backend).await
61 }
62}