Skip to main content

core_crypto/mls/
mod.rs

1pub(crate) mod cipher_suite;
2pub mod conversation;
3pub(crate) mod conversation_cache;
4pub mod credential;
5mod external_sender;
6pub mod key_package;
7pub(crate) mod session;
8
9pub use cipher_suite::UnknownCipherSuite;
10pub(crate) use conversation::TntMessageCounter;
11pub use external_sender::ExternalSender;
12pub use session::{EpochObserver, HistoryObserver};
13
14#[cfg(test)]
15mod tests {
16    use crate::{CoreCrypto, test_utils::*, transaction_context::Error as TransactionError};
17
18    mod conversation_epoch {
19        use super::*;
20
21        #[apply(all_cred_cipher)]
22        async fn can_get_newly_created_conversation_epoch(case: TestContext) {
23            let [session] = case.sessions().await;
24            let conversation = case.create_conversation([&session]).await;
25            let epoch = conversation.guard().await.epoch().await;
26            assert_eq!(epoch, 0);
27        }
28
29        #[apply(all_cred_cipher)]
30        async fn can_get_conversation_epoch(case: TestContext) {
31            let [alice, bob] = case.sessions().await;
32            Box::pin(async move {
33                let conversation = case.create_conversation([&alice, &bob]).await;
34                let epoch = conversation.guard().await.epoch().await;
35                assert_eq!(epoch, 1);
36            })
37            .await;
38        }
39
40        #[apply(all_cred_cipher)]
41        async fn conversation_not_found(case: TestContext) {
42            let [session] = case.sessions().await;
43            let id = conversation_id();
44            let err = session.transaction.conversation(&id).await.unwrap_err();
45            assert!(matches!(
46                err,
47                TransactionError::ConversationNotFound(i) if i == id
48            ));
49        }
50    }
51
52    #[apply(all_cred_cipher)]
53    async fn create_conversation_should_fail_when_already_exists(case: TestContext) {
54        let [alice] = case.sessions().await;
55        Box::pin(async move {
56            let conversation = case.create_conversation([&alice]).await;
57            let id = conversation.id().clone();
58            let credentials = alice
59                .find_credentials(Default::default())
60                .await
61                .expect("finding credentials");
62            let credential = credentials.first().expect("first credential");
63
64            // creating a conversation should first verify that the conversation does not already exist ; only then
65            // create it
66            let repeat_create = alice
67                .transaction
68                .new_conversation(&id, credential, case.cfg.clone())
69                .await;
70            assert!(matches!(repeat_create.unwrap_err(), TransactionError::ConversationAlreadyExists(i) if i == id));
71        })
72        .await;
73    }
74
75    #[apply(all_cred_cipher)]
76    async fn can_2_phase_init_central(mut case: TestContext) {
77        let db = case.create_persistent_db().await;
78        Box::pin(async move {
79            use std::sync::Arc;
80
81            use wire_e2e_identity::pki_env::PkiEnvironment;
82
83            use crate::test_utils::DummyPkiEnvironmentHooks;
84
85            let x509_test_chain = case.set_test_chain(&[], &[], None).await;
86
87            // phase 1: init without initialized mls_client
88            let cc = CoreCrypto::new(db.clone());
89            let context = cc.new_transaction().await.unwrap();
90
91            let hooks = Arc::new(DummyPkiEnvironmentHooks);
92            let pki_env = PkiEnvironment::new(hooks, db).await.expect("creating pki environment");
93            cc.set_pki_environment(Some(Arc::new(pki_env))).await;
94
95            x509_test_chain.register_with_central(&context).await;
96
97            // phase 2: init mls_client
98            let credential = case.generate_credential().await;
99            let session_id = credential.client_id().to_owned();
100            context
101                .mls_init(
102                    session_id.clone(),
103                    Arc::new(CoreCryptoTransportSuccessProvider::default()),
104                )
105                .await
106                .unwrap();
107
108            let credential_ref = context.add_credential(credential).await.unwrap();
109
110            // expect mls_client to work
111            assert!(context.generate_key_package(&credential_ref, None).await.is_ok());
112        })
113        .await
114    }
115}