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 = if case.supports_x509() {
86                Some(case.set_test_chain(&[], &[], None).await)
87            } else {
88                None
89            };
90
91            // phase 1: init without initialized mls_client
92            let cc = CoreCrypto::new(db.clone());
93            let context = cc.new_transaction().await.unwrap();
94
95            let hooks = Arc::new(DummyPkiEnvironmentHooks);
96            let pki_env = PkiEnvironment::new(hooks, db).await.expect("creating pki environment");
97            cc.set_pki_environment(Some(Arc::new(pki_env))).await;
98
99            if let Some(x509_test_chain) = x509_test_chain {
100                x509_test_chain.register_with_central(&context).await;
101            }
102
103            // phase 2: init mls_client
104            let credential = case.generate_credential().await;
105            let session_id = credential.client_id().to_owned();
106            context
107                .mls_init(
108                    session_id.clone(),
109                    Arc::new(CoreCryptoTransportSuccessProvider::default()),
110                )
111                .await
112                .unwrap();
113
114            let credential_ref = context.add_credential(credential).await.unwrap();
115
116            // expect mls_client to work
117            assert!(context.generate_key_package(&credential_ref, None).await.is_ok());
118        })
119        .await
120    }
121}