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