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 error;
6mod external_sender;
7pub mod key_package;
8pub(crate) mod session;
9
10pub(crate) use conversation::TntMessageCounter;
11pub use error::{Error, Result};
12pub use external_sender::ExternalSender;
13pub use session::{EpochObserver, HistoryObserver};
14
15#[cfg(test)]
16mod tests {
17    use crate::{CoreCrypto, test_utils::*, transaction_context::Error as TransactionError};
18
19    mod conversation_epoch {
20        use super::*;
21
22        #[apply(all_cred_cipher)]
23        async fn can_get_newly_created_conversation_epoch(case: TestContext) {
24            let [session] = case.sessions().await;
25            let conversation = case.create_conversation([&session]).await;
26            let epoch = conversation.guard().await.epoch().await;
27            assert_eq!(epoch, 0);
28        }
29
30        #[apply(all_cred_cipher)]
31        async fn can_get_conversation_epoch(case: TestContext) {
32            let [alice, bob] = case.sessions().await;
33            Box::pin(async move {
34                let conversation = case.create_conversation([&alice, &bob]).await;
35                let epoch = conversation.guard().await.epoch().await;
36                assert_eq!(epoch, 1);
37            })
38            .await;
39        }
40
41        #[apply(all_cred_cipher)]
42        async fn conversation_not_found(case: TestContext) {
43            use crate::LeafError;
44            let [session] = case.sessions().await;
45            let id = conversation_id();
46            let err = session.transaction.conversation(&id).await.unwrap_err();
47            assert!(matches!(
48                err,
49                TransactionError::Leaf(LeafError::ConversationNotFound(i)) if i == id
50            ));
51        }
52    }
53
54    #[apply(all_cred_cipher)]
55    async fn create_conversation_should_fail_when_already_exists(case: TestContext) {
56        use crate::LeafError;
57
58        let [alice] = case.sessions().await;
59        Box::pin(async move {
60            let conversation = case.create_conversation([&alice]).await;
61            let id = conversation.id().clone();
62            let credentials = alice.find_credentials(Default::default()).await.expect("finding credentials");
63            let credential = credentials.first().expect("first credential");
64
65                // creating a conversation should first verify that the conversation does not already exist ; only then 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::Leaf(LeafError::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}