1 // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 // Copyright by contributors to this project. 3 // SPDX-License-Identifier: (Apache-2.0 OR MIT) 4 5 //! An implementation of the [IETF Messaging Layer Security](https://messaginglayersecurity.rocks) 6 //! end-to-end encryption (E2EE) protocol. 7 //! 8 //! ## What is MLS? 9 //! 10 //! MLS is a new IETF end-to-end encryption standard that is designed to 11 //! provide transport agnostic, asynchronous, and highly performant 12 //! communication between a group of clients. 13 //! 14 //! ## MLS Protocol Features 15 //! 16 //! - Multi-party E2EE [group evolution](https://www.rfc-editor.org/rfc/rfc9420.html#name-cryptographic-state-and-evo) 17 //! via a propose-then-commit mechanism. 18 //! - Asynchronous by design with pre-computed [key packages](https://www.rfc-editor.org/rfc/rfc9420.html#name-key-packages), 19 //! allowing members to be added to a group while offline. 20 //! - Customizable credential system with built in support for X.509 certificates. 21 //! - [Extension system](https://www.rfc-editor.org/rfc/rfc9420.html#name-extensions) 22 //! allowing for application specific data to be negotiated via the protocol. 23 //! - Strong forward secrecy and post compromise security. 24 //! - Crypto agility via support for multiple [cipher suites](https://www.rfc-editor.org/rfc/rfc9420.html#name-cipher-suites). 25 //! - Pre-shared key support. 26 //! - Subgroup branching. 27 //! - Group reinitialization for breaking changes such as protocol upgrades. 28 //! 29 //! ## Features 30 //! 31 //! - Easy to use client interface that can manage multiple MLS identities and groups. 32 //! - 100% RFC 9420 conformance with support for all default credential, proposal, 33 //! and extension types. 34 //! - Support for WASM builds. 35 //! - Configurable storage for key packages, secrets and group state 36 //! via traits along with provided "in memory" and SQLite implementations. 37 //! - Support for custom user proposal and extension types. 38 //! - Ability to create user defined credentials with custom validation 39 //! routines that can bridge to existing credential schemes. 40 //! - OpenSSL and Rust Crypto based cipher suite implementations. 41 //! - Crypto agility with support for user defined cipher suite. 42 //! - Extensive test suite including security and interop focused tests against 43 //! pre-computed test vectors. 44 //! 45 //! ## Crypto Providers 46 //! 47 //! For cipher suite descriptions see the RFC documentation [here](https://www.rfc-editor.org/rfc/rfc9420.html#name-mls-cipher-suites) 48 //! 49 //! | Name | Cipher Suites | X509 Support | 50 //! |------|---------------|--------------| 51 //! | OpenSSL | 1-7 | Stable | 52 //! | AWS-LC | 1,2,3,5,7 | Stable | 53 //! | Rust Crypto | 1,2,3 | ⚠️ Experimental | 54 //! 55 //! ## Security Notice 56 //! 57 //! This library has been validated for conformance to the RFC 9420 specification but has not yet received a full security audit by a 3rd party. 58 59 #![allow(clippy::enum_variant_names)] 60 #![allow(clippy::result_large_err)] 61 #![allow(clippy::nonstandard_macro_braces)] 62 #![cfg_attr(not(feature = "std"), no_std)] 63 #![cfg_attr(docsrs, feature(doc_cfg))] 64 #![cfg_attr(coverage_nightly, feature(coverage_attribute))] 65 extern crate alloc; 66 67 #[cfg(all(test, target_arch = "wasm32"))] 68 wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); 69 70 #[cfg(all(test, target_arch = "wasm32"))] 71 use wasm_bindgen_test::wasm_bindgen_test as futures_test; 72 73 #[cfg(all(test, mls_build_async, not(target_arch = "wasm32")))] 74 use futures_test::test as futures_test; 75 76 #[cfg(test)] 77 macro_rules! hex { 78 ($input:literal) => { 79 hex::decode($input).expect("invalid hex value") 80 }; 81 } 82 83 #[cfg(test)] 84 macro_rules! load_test_case_json { 85 ($name:ident, $generate:expr) => { 86 load_test_case_json!($name, $generate, to_vec_pretty) 87 }; 88 ($name:ident, $generate:expr, $to_json:ident) => {{ 89 #[cfg(any(target_arch = "wasm32", not(feature = "std")))] 90 { 91 // Do not remove `async`! (The goal of this line is to remove warnings 92 // about `$generate` not being used. Actually calling it will make tests fail.) 93 let _ = async { $generate }; 94 serde_json::from_slice(include_bytes!(concat!( 95 env!("CARGO_MANIFEST_DIR"), 96 "/test_data/", 97 stringify!($name), 98 ".json" 99 ))) 100 .unwrap() 101 } 102 103 #[cfg(all(not(target_arch = "wasm32"), feature = "std"))] 104 { 105 let path = concat!( 106 env!("CARGO_MANIFEST_DIR"), 107 "/test_data/", 108 stringify!($name), 109 ".json" 110 ); 111 if !std::path::Path::new(path).exists() { 112 std::fs::write(path, serde_json::$to_json(&$generate).unwrap()).unwrap(); 113 } 114 serde_json::from_slice(&std::fs::read(path).unwrap()).unwrap() 115 } 116 }}; 117 } 118 119 mod cipher_suite { 120 pub use mls_rs_core::crypto::CipherSuite; 121 } 122 123 pub use cipher_suite::CipherSuite; 124 125 mod protocol_version { 126 pub use mls_rs_core::protocol_version::ProtocolVersion; 127 } 128 129 pub use protocol_version::ProtocolVersion; 130 131 pub mod client; 132 pub mod client_builder; 133 mod client_config; 134 /// Dependencies of [`CryptoProvider`] and [`CipherSuiteProvider`] 135 pub mod crypto; 136 /// Extension utilities and built-in extension types. 137 pub mod extension; 138 /// Tools to observe groups without being a member, useful 139 /// for server implementations. 140 #[cfg(feature = "external_client")] 141 #[cfg_attr(docsrs, doc(cfg(feature = "external_client")))] 142 pub mod external_client; 143 mod grease; 144 /// E2EE group created by a [`Client`]. 145 pub mod group; 146 mod hash_reference; 147 /// Identity providers to use with [`ClientBuilder`](client_builder::ClientBuilder). 148 pub mod identity; 149 mod iter; 150 mod key_package; 151 /// Pre-shared key support. 152 pub mod psk; 153 mod signer; 154 /// Storage providers to use with 155 /// [`ClientBuilder`](client_builder::ClientBuilder). 156 pub mod storage_provider; 157 158 pub use mls_rs_core::{ 159 crypto::{CipherSuiteProvider, CryptoProvider}, 160 group::GroupStateStorage, 161 identity::IdentityProvider, 162 key_package::KeyPackageStorage, 163 psk::PreSharedKeyStorage, 164 }; 165 166 /// Dependencies of [`MlsRules`]. 167 pub mod mls_rules { 168 pub use crate::group::{ 169 mls_rules::{ 170 CommitDirection, CommitOptions, CommitSource, DefaultMlsRules, EncryptionOptions, 171 }, 172 proposal_filter::{ProposalBundle, ProposalInfo, ProposalSource}, 173 }; 174 175 #[cfg(feature = "by_ref_proposal")] 176 pub use crate::group::proposal_ref::ProposalRef; 177 } 178 179 pub use mls_rs_core::extension::{Extension, ExtensionList}; 180 181 pub use crate::{ 182 client::Client, 183 group::{ 184 framing::{MlsMessage, WireFormat}, 185 mls_rules::MlsRules, 186 Group, 187 }, 188 key_package::{KeyPackage, KeyPackageRef}, 189 }; 190 191 /// Error types. 192 pub mod error { 193 pub use crate::client::MlsError; 194 pub use mls_rs_core::error::{AnyError, IntoAnyError}; 195 pub use mls_rs_core::extension::ExtensionError; 196 } 197 198 /// WASM compatible timestamp. 199 pub mod time { 200 pub use mls_rs_core::time::*; 201 } 202 203 mod tree_kem; 204 205 pub use mls_rs_codec; 206 207 mod private { 208 pub trait Sealed {} 209 } 210 211 use private::Sealed; 212 213 #[cfg(any(test, feature = "test_util"))] 214 #[doc(hidden)] 215 pub mod test_utils; 216 217 #[cfg(feature = "ffi")] 218 pub use safer_ffi_gen; 219