1#![doc = include_str!("../../README.md")]
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 group_store;
35mod obfuscate;
36pub mod transaction_context;
37
38mod build_metadata;
39use crate::prelude::MlsCommitBundle;
40pub use build_metadata::{BUILD_METADATA, BuildMetadata};
41
42pub use core_crypto_keystore::DatabaseKey;
43
44pub mod prelude {
46    pub use openmls::{
47        group::{MlsGroup, MlsGroupConfig},
48        prelude::{
49            Ciphersuite as CiphersuiteName, Credential, GroupEpoch, KeyPackage, KeyPackageIn, KeyPackageRef,
50            MlsMessageIn, Node, group_info::VerifiableGroupInfo,
51        },
52    };
53
54    pub use mls_crypto_provider::{EntropySeed, MlsCryptoProvider, RawEntropySeed};
55
56    pub use crate::{
57        CoreCrypto, MlsTransport,
58        e2e_identity::{
59            E2eiEnrollment,
60            device_status::DeviceStatus,
61            identity::{WireIdentity, X509Identity},
62            types::{E2eiAcmeChallenge, E2eiAcmeDirectory, E2eiNewAcmeAuthz, E2eiNewAcmeOrder},
63        },
64        error::{CryptoboxMigrationError, Error, KeystoreError, LeafError, MlsError, ProteusError, RecursiveError},
65        mls::{
66            ciphersuite::MlsCiphersuite,
67            config::MlsClientConfiguration,
68            conversation::{
69                ConversationId, MlsConversation,
70                commit::MlsCommitBundle,
71                config::{MlsConversationConfiguration, MlsCustomConfiguration, MlsWirePolicy},
72                conversation_guard::decrypt::{MlsBufferedConversationDecryptMessage, MlsConversationDecryptMessage},
73                group_info::{GroupInfoPayload, MlsGroupInfoBundle, MlsGroupInfoEncryptionType, MlsRatchetTreeType},
74                proposal::MlsProposalBundle,
75                welcome::WelcomeBundle,
76            },
77            credential::{typ::MlsCredentialType, x509::CertificateBundle},
78            proposal::{MlsProposal, MlsProposalRef},
79            session::Session,
80            session::id::ClientId,
81            session::identifier::ClientIdentifier,
82            session::key_package::INITIAL_KEYING_MATERIAL_COUNT,
83            session::*,
84        },
85        obfuscate::Obfuscated,
86        transaction_context::e2e_identity::{E2eiDumpedPkiEnv, conversation_state::E2eiConversationState},
87    };
88}
89
90pub enum MlsTransportResponse {
92    Success,
94    Retry,
96    Abort {
98        reason: String,
100    },
101}
102
103#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
106#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
107pub trait MlsTransport: std::fmt::Debug + Send + Sync {
108    async fn send_commit_bundle(&self, commit_bundle: MlsCommitBundle) -> Result<MlsTransportResponse>;
110    async fn send_message(&self, mls_message: Vec<u8>) -> Result<MlsTransportResponse>;
112}
113
114#[derive(Debug, Clone)]
120pub struct CoreCrypto {
121    mls: mls::session::Session,
122    #[cfg(feature = "proteus")]
123    proteus: Arc<Mutex<Option<proteus::ProteusCentral>>>,
124    #[cfg(not(feature = "proteus"))]
125    #[allow(dead_code)]
126    proteus: (),
127}
128
129impl From<mls::session::Session> for CoreCrypto {
130    fn from(mls: mls::session::Session) -> Self {
131        Self {
132            mls,
133            proteus: Default::default(),
134        }
135    }
136}
137
138impl std::ops::Deref for CoreCrypto {
139    type Target = mls::session::Session;
140
141    fn deref(&self) -> &Self::Target {
142        &self.mls
143    }
144}
145
146impl std::ops::DerefMut for CoreCrypto {
147    fn deref_mut(&mut self) -> &mut Self::Target {
148        &mut self.mls
149    }
150}
151
152impl CoreCrypto {
153    #[inline]
155    pub fn take(self) -> mls::session::Session {
156        self.mls
157    }
158}