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 use error::{Error, Result};
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            use crate::LeafError;
43            let [session] = case.sessions().await;
44            let id = conversation_id();
45            let err = session.transaction.conversation(&id).await.unwrap_err();
46            assert!(matches!(
47                err,
48                TransactionError::Leaf(LeafError::ConversationNotFound(i)) if i == id
49            ));
50        }
51    }
52
53    #[apply(all_cred_cipher)]
54    async fn create_conversation_should_fail_when_already_exists(case: TestContext) {
55        use crate::LeafError;
56
57        let [alice] = case.sessions().await;
58        Box::pin(async move {
59            let conversation = case.create_conversation([&alice]).await;
60            let id = conversation.id().clone();
61            let credentials = alice.find_credentials(Default::default()).await.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 create it
65                let repeat_create = alice
66                    .transaction
67                    .new_conversation(&id, credential, case.cfg.clone())
68                    .await;
69                assert!(matches!(repeat_create.unwrap_err(), TransactionError::Leaf(LeafError::ConversationAlreadyExists(i)) if i == id));
70            })
71        .await;
72    }
73
74    #[apply(all_cred_cipher)]
75    async fn can_2_phase_init_central(mut case: TestContext) {
76        let db = case.create_persistent_db().await;
77        Box::pin(async move {
78            use std::sync::Arc;
79
80            use wire_e2e_identity::pki_env::PkiEnvironment;
81
82            use crate::test_utils::DummyPkiEnvironmentHooks;
83
84            let x509_test_chain = case.set_test_chain(&[], &[], None).await;
85
86            // phase 1: init without initialized mls_client
87            let cc = CoreCrypto::new(db.clone());
88            let context = cc.new_transaction().await.unwrap();
89
90            let hooks = Arc::new(DummyPkiEnvironmentHooks);
91            let pki_env = PkiEnvironment::new(hooks, db).await.expect("creating pki environment");
92            cc.set_pki_environment(Some(Arc::new(pki_env))).await;
93
94            x509_test_chain.register_with_central(&context).await;
95
96            // phase 2: init mls_client
97            let credential = case.generate_credential().await;
98            let session_id = credential.client_id().to_owned();
99            context
100                .mls_init(
101                    session_id.clone(),
102                    Arc::new(CoreCryptoTransportSuccessProvider::default()),
103                )
104                .await
105                .unwrap();
106
107            let credential_ref = context.add_credential(credential).await.unwrap();
108
109            // expect mls_client to work
110            assert!(context.generate_key_package(&credential_ref, None).await.is_ok());
111        })
112        .await
113    }
114}