1// Wire
2// Copyright (C) 2022 Wire Swiss GmbH
34// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
89// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
1314// You should have received a copy of the GNU General Public License
15// along with this program. If not, see http://www.gnu.org/licenses/.
1617//! Core Crypto is a wrapper on top of OpenMLS aimed to provide an ergonomic API for usage in web
18//! through Web Assembly and in mobile devices through FFI.
19//!
20//! The goal is provide a easier and less verbose API to create, manage and interact with MLS
21//! groups.
22#![doc = include_str!("../../README.md")]
23#![cfg_attr(not(test), deny(missing_docs))]
24#![allow(clippy::single_component_path_imports)]
2526use async_lock::Mutex;
27#[cfg(test)]
28pub use core_crypto_macros::{dispotent, durable, idempotent};
29use std::sync::Arc;
3031pub use self::error::*;
3233#[cfg(test)]
34#[macro_use]
35pub mod test_utils;
36// both imports above have to be defined at the beginning of the crate for rstest to work
3738mod error;
3940/// MLS Abstraction
41pub mod mls;
4243/// re-export [rusty-jwt-tools](https://github.com/wireapp/rusty-jwt-tools) API
44pub mod e2e_identity;
4546#[cfg(feature = "proteus")]
47/// Proteus Abstraction
48pub mod proteus;
4950pub mod context;
51mod group_store;
52mod obfuscate;
5354mod build_metadata;
55use crate::prelude::MlsCommitBundle;
56pub use build_metadata::{BUILD_METADATA, BuildMetadata};
5758/// Common imports that should be useful for most uses of the crate
59pub mod prelude {
60pub use openmls::{
61 group::{MlsGroup, MlsGroupConfig},
62 prelude::{
63 Ciphersuite as CiphersuiteName, Credential, GroupEpoch, KeyPackage, KeyPackageIn, KeyPackageRef,
64 MlsMessageIn, Node, group_info::VerifiableGroupInfo,
65 },
66 };
6768pub use mls_crypto_provider::{EntropySeed, MlsCryptoProvider, RawEntropySeed};
6970pub use crate::{
71 CoreCrypto, MlsTransport,
72 e2e_identity::{
73 E2eiEnrollment,
74 conversation_state::E2eiConversationState,
75 device_status::DeviceStatus,
76 identity::{WireIdentity, X509Identity},
77 types::{E2eiAcmeChallenge, E2eiAcmeDirectory, E2eiNewAcmeAuthz, E2eiNewAcmeOrder},
78 },
79 error::{CryptoboxMigrationError, Error, KeystoreError, LeafError, MlsError, ProteusError, RecursiveError},
80 mls::{
81 MlsCentral,
82 ciphersuite::MlsCiphersuite,
83 client::id::ClientId,
84 client::identifier::ClientIdentifier,
85 client::key_package::INITIAL_KEYING_MATERIAL_COUNT,
86 client::*,
87 config::MlsCentralConfiguration,
88 conversation::{
89 ConversationId, MlsConversation,
90 commit::{MlsCommitBundle, MlsConversationCreationMessage},
91 config::{MlsConversationConfiguration, MlsCustomConfiguration, MlsWirePolicy},
92 conversation_guard::decrypt::{MlsBufferedConversationDecryptMessage, MlsConversationDecryptMessage},
93 group_info::{GroupInfoPayload, MlsGroupInfoBundle, MlsGroupInfoEncryptionType, MlsRatchetTreeType},
94 proposal::MlsProposalBundle,
95 welcome::WelcomeBundle,
96 },
97 credential::{typ::MlsCredentialType, x509::CertificateBundle},
98 proposal::{MlsProposal, MlsProposalRef},
99 },
100 obfuscate::Obfuscated,
101 };
102}
103104/// Response from the delivery service
105pub enum MlsTransportResponse {
106/// The message was accepted by the delivery service
107Success,
108/// A client should have consumed all incoming messages before re-trying.
109Retry,
110/// The message was rejected by the delivery service and there's no recovery.
111Abort {
112/// Why did the delivery service reject the message?
113reason: String,
114 },
115}
116117/// Client callbacks to allow communication with the delivery service.
118/// There are two different endpoints, one for messages and one for commit bundles.
119#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
120#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
121pub trait MlsTransport: std::fmt::Debug + Send + Sync {
122/// Send a commit bundle to the corresponding endpoint.
123async fn send_commit_bundle(&self, commit_bundle: MlsCommitBundle) -> Result<MlsTransportResponse>;
124/// Send a message to the corresponding endpoint.
125async fn send_message(&self, mls_message: Vec<u8>) -> Result<MlsTransportResponse>;
126}
127128#[derive(Debug)]
129/// Wrapper superstruct for both [mls::MlsCentral] and [proteus::ProteusCentral]
130///
131/// As [std::ops::Deref] is implemented, this struct is automatically dereferred to [mls::MlsCentral] apart from `proteus_*` calls
132pub struct CoreCrypto {
133 mls: mls::MlsCentral,
134#[cfg(feature = "proteus")]
135proteus: Arc<Mutex<Option<proteus::ProteusCentral>>>,
136#[cfg(not(feature = "proteus"))]
137 #[allow(dead_code)]
138proteus: (),
139}
140141impl From<mls::MlsCentral> for CoreCrypto {
142fn from(mls: mls::MlsCentral) -> Self {
143Self {
144 mls,
145 proteus: Default::default(),
146 }
147 }
148}
149150impl std::ops::Deref for CoreCrypto {
151type Target = mls::MlsCentral;
152153fn deref(&self) -> &Self::Target {
154&self.mls
155 }
156}
157158impl std::ops::DerefMut for CoreCrypto {
159fn deref_mut(&mut self) -> &mut Self::Target {
160&mut self.mls
161 }
162}
163164impl CoreCrypto {
165/// Allows to extract the MLS Client from the wrapper superstruct
166#[inline]
167pub fn take(self) -> mls::MlsCentral {
168self.mls
169 }
170}