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 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 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 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 assert!(context.generate_key_package(&credential_ref, None).await.is_ok());
112 })
113 .await
114 }
115}