1 use std::sync::Mutex;
2 
3 use mls_rs_core::{
4     crypto::{CipherSuiteProvider, CryptoProvider, SignatureSecretKey},
5     identity::BasicCredential,
6 };
7 
8 use once_cell::sync::Lazy;
9 
10 use crate::{
11     cipher_suite::CipherSuite,
12     client::MlsError,
13     client_builder::{BaseConfig, WithCryptoProvider, WithIdentityProvider},
14     group::{
15         framing::{Content, MlsMessage, Sender, WireFormat},
16         message_processor::MessageProcessor,
17         message_signature::AuthenticatedContent,
18         Commit, Group,
19     },
20     identity::{basic::BasicIdentityProvider, SigningIdentity},
21     Client, ExtensionList,
22 };
23 
24 #[cfg(awslc)]
25 pub use mls_rs_crypto_awslc::AwsLcCryptoProvider as MlsCryptoProvider;
26 #[cfg(not(any(awslc, rustcrypto)))]
27 pub use mls_rs_crypto_openssl::OpensslCryptoProvider as MlsCryptoProvider;
28 #[cfg(rustcrypto)]
29 pub use mls_rs_crypto_rustcrypto::RustCryptoProvider as MlsCryptoProvider;
30 
31 pub type TestClientConfig =
32     WithIdentityProvider<BasicIdentityProvider, WithCryptoProvider<MlsCryptoProvider, BaseConfig>>;
33 
34 pub static GROUP: Lazy<Mutex<Group<TestClientConfig>>> = Lazy::new(|| Mutex::new(create_group()));
35 
create_group() -> Group<TestClientConfig>36 pub fn create_group() -> Group<TestClientConfig> {
37     let cipher_suite = CipherSuite::CURVE25519_AES128;
38     let alice = make_client(cipher_suite, "alice");
39     let bob = make_client(cipher_suite, "bob");
40 
41     let mut alice = alice.create_group(ExtensionList::new()).unwrap();
42 
43     alice
44         .commit_builder()
45         .add_member(bob.generate_key_package_message().unwrap())
46         .unwrap()
47         .build()
48         .unwrap();
49 
50     alice.apply_pending_commit().unwrap();
51 
52     alice
53 }
54 
create_fuzz_commit_message( group_id: Vec<u8>, epoch: u64, authenticated_data: Vec<u8>, ) -> Result<MlsMessage, MlsError>55 pub fn create_fuzz_commit_message(
56     group_id: Vec<u8>,
57     epoch: u64,
58     authenticated_data: Vec<u8>,
59 ) -> Result<MlsMessage, MlsError> {
60     let mut group = GROUP.lock().unwrap();
61 
62     let mut context = group.context().clone();
63     context.group_id = group_id;
64     context.epoch = epoch;
65 
66     #[cfg(feature = "private_message")]
67     let wire_format = WireFormat::PrivateMessage;
68 
69     #[cfg(not(feature = "private_message"))]
70     let wire_format = WireFormat::PublicMessage;
71 
72     let auth_content = AuthenticatedContent::new_signed(
73         group.cipher_suite_provider(),
74         &context,
75         Sender::Member(0),
76         Content::Commit(alloc::boxed::Box::new(Commit {
77             proposals: Vec::new(),
78             path: None,
79         })),
80         &group.signer,
81         wire_format,
82         authenticated_data,
83     )?;
84 
85     group.format_for_wire(auth_content)
86 }
87 
make_client(cipher_suite: CipherSuite, name: &str) -> Client<TestClientConfig>88 fn make_client(cipher_suite: CipherSuite, name: &str) -> Client<TestClientConfig> {
89     let (secret, signing_identity) = make_identity(cipher_suite, name);
90 
91     // TODO : consider fuzzing on encrypted controls (doesn't seem very useful)
92     Client::builder()
93         .identity_provider(BasicIdentityProvider)
94         .crypto_provider(MlsCryptoProvider::default())
95         .signing_identity(signing_identity, secret, cipher_suite)
96         .build()
97 }
98 
make_identity(cipher_suite: CipherSuite, name: &str) -> (SignatureSecretKey, SigningIdentity)99 fn make_identity(cipher_suite: CipherSuite, name: &str) -> (SignatureSecretKey, SigningIdentity) {
100     let cipher_suite = MlsCryptoProvider::new()
101         .cipher_suite_provider(cipher_suite)
102         .unwrap();
103 
104     let (secret, public) = cipher_suite.signature_key_generate().unwrap();
105     let basic_identity = BasicCredential::new(name.as_bytes().to_vec());
106     let signing_identity = SigningIdentity::new(basic_identity.into_credential(), public);
107 
108     (secret, signing_identity)
109 }
110