1#![doc = include_str!(env!("STRIPPED_README_PATH"))]
7#![cfg_attr(not(test), deny(missing_docs))]
8#![allow(clippy::single_component_path_imports)]
9
10use async_lock::Mutex;
11#[cfg(test)]
12pub use core_crypto_macros::{dispotent, durable, idempotent};
13use std::sync::Arc;
14
15pub use self::error::*;
16
17#[cfg(test)]
18#[macro_use]
19pub mod test_utils;
20mod error;
23
24pub mod mls;
26
27pub mod e2e_identity;
29
30#[cfg(feature = "proteus")]
32pub mod proteus;
33
34mod ephemeral;
35mod group_store;
36mod obfuscate;
37pub mod transaction_context;
38
39mod build_metadata;
40use crate::prelude::MlsCommitBundle;
41pub use build_metadata::{BUILD_METADATA, BuildMetadata};
42
43use crate::ephemeral::HistorySecret;
44pub use core_crypto_keystore::DatabaseKey;
45
46pub mod prelude {
48 pub use openmls::{
49 group::{MlsGroup, MlsGroupConfig},
50 prelude::{
51 Ciphersuite as CiphersuiteName, Credential, GroupEpoch, KeyPackage, KeyPackageIn, KeyPackageRef,
52 MlsMessageIn, Node, group_info::VerifiableGroupInfo,
53 },
54 };
55
56 pub use mls_crypto_provider::{EntropySeed, MlsCryptoProvider, RawEntropySeed};
57
58 pub use crate::{
59 CoreCrypto, MlsTransport,
60 e2e_identity::{
61 E2eiEnrollment,
62 device_status::DeviceStatus,
63 identity::{WireIdentity, X509Identity},
64 types::{E2eiAcmeChallenge, E2eiAcmeDirectory, E2eiNewAcmeAuthz, E2eiNewAcmeOrder},
65 },
66 ephemeral::{HISTORY_CLIENT_ID_PREFIX, HistorySecret},
67 error::{CryptoboxMigrationError, Error, KeystoreError, LeafError, MlsError, ProteusError, RecursiveError},
68 mls::{
69 ciphersuite::MlsCiphersuite,
70 conversation::{
71 ConversationId, MlsConversation,
72 commit::MlsCommitBundle,
73 config::{MlsConversationConfiguration, MlsCustomConfiguration, MlsWirePolicy},
74 conversation_guard::decrypt::{MlsBufferedConversationDecryptMessage, MlsConversationDecryptMessage},
75 group_info::{GroupInfoPayload, MlsGroupInfoBundle, MlsGroupInfoEncryptionType, MlsRatchetTreeType},
76 proposal::MlsProposalBundle,
77 welcome::WelcomeBundle,
78 },
79 credential::{typ::MlsCredentialType, x509::CertificateBundle},
80 proposal::{MlsProposal, MlsProposalRef},
81 session::{
82 Session,
83 config::{SessionConfig, ValidatedSessionConfig},
84 id::ClientId,
85 identifier::ClientIdentifier,
86 key_package::INITIAL_KEYING_MATERIAL_COUNT,
87 *,
88 },
89 },
90 obfuscate::Obfuscated,
91 transaction_context::e2e_identity::conversation_state::E2eiConversationState,
92 };
93}
94
95pub enum MlsTransportResponse {
97 Success,
99 Retry,
101 Abort {
103 reason: String,
105 },
106}
107
108#[derive(Debug, derive_more::From, derive_more::Deref, serde::Serialize, serde::Deserialize)]
111pub struct MlsTransportData(pub Vec<u8>);
112
113#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
116#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
117pub trait MlsTransport: std::fmt::Debug + Send + Sync {
118 async fn send_commit_bundle(&self, commit_bundle: MlsCommitBundle) -> Result<MlsTransportResponse>;
120 async fn send_message(&self, mls_message: Vec<u8>) -> Result<MlsTransportResponse>;
122
123 async fn prepare_for_transport(&self, secret: &HistorySecret) -> Result<MlsTransportData>;
130}
131
132#[derive(Debug, Clone)]
138pub struct CoreCrypto {
139 mls: mls::session::Session,
140 #[cfg(feature = "proteus")]
141 proteus: Arc<Mutex<Option<proteus::ProteusCentral>>>,
142 #[cfg(not(feature = "proteus"))]
143 #[allow(dead_code)]
144 proteus: (),
145}
146
147impl From<mls::session::Session> for CoreCrypto {
148 fn from(mls: mls::session::Session) -> Self {
149 Self {
150 mls,
151 proteus: Default::default(),
152 }
153 }
154}
155
156impl std::ops::Deref for CoreCrypto {
157 type Target = mls::session::Session;
158
159 fn deref(&self) -> &Self::Target {
160 &self.mls
161 }
162}
163
164impl std::ops::DerefMut for CoreCrypto {
165 fn deref_mut(&mut self) -> &mut Self::Target {
166 &mut self.mls
167 }
168}
169
170impl CoreCrypto {
171 #[inline]
173 pub fn take(self) -> mls::session::Session {
174 self.mls
175 }
176}