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 use mls_rs::{
6     client_builder::MlsConfig,
7     error::MlsError,
8     identity::{
9         basic::{BasicCredential, BasicIdentityProvider},
10         SigningIdentity,
11     },
12     CipherSuite, CipherSuiteProvider, Client, CryptoProvider, ExtensionList,
13 };
14 
15 const CIPHERSUITE: CipherSuite = CipherSuite::CURVE25519_AES128;
16 
make_client<P: CryptoProvider + Clone>( crypto_provider: P, name: &str, ) -> Result<Client<impl MlsConfig>, MlsError>17 fn make_client<P: CryptoProvider + Clone>(
18     crypto_provider: P,
19     name: &str,
20 ) -> Result<Client<impl MlsConfig>, MlsError> {
21     let cipher_suite = crypto_provider.cipher_suite_provider(CIPHERSUITE).unwrap();
22 
23     // Generate a signature key pair.
24     let (secret, public) = cipher_suite.signature_key_generate().unwrap();
25 
26     // Create a basic credential for the session.
27     // NOTE: BasicCredential is for demonstration purposes and not recommended for production.
28     // X.509 credentials are recommended.
29     let basic_identity = BasicCredential::new(name.as_bytes().to_vec());
30     let signing_identity = SigningIdentity::new(basic_identity.into_credential(), public);
31 
32     Ok(Client::builder()
33         .identity_provider(BasicIdentityProvider)
34         .crypto_provider(crypto_provider)
35         .signing_identity(signing_identity, secret, CIPHERSUITE)
36         .build())
37 }
38 
main() -> Result<(), MlsError>39 fn main() -> Result<(), MlsError> {
40     let crypto_provider = mls_rs_crypto_openssl::OpensslCryptoProvider::default();
41 
42     // Create clients for Alice and Bob
43     let alice = make_client(crypto_provider.clone(), "alice")?;
44     let bob = make_client(crypto_provider.clone(), "bob")?;
45 
46     // Alice creates a new group.
47     let mut alice_group = alice.create_group(ExtensionList::default())?;
48 
49     // Bob generates a key package that Alice needs to add Bob to the group.
50     let bob_key_package = bob.generate_key_package_message()?;
51 
52     // Alice issues a commit that adds Bob to the group.
53     let alice_commit = alice_group
54         .commit_builder()
55         .add_member(bob_key_package)?
56         .build()?;
57 
58     // Alice confirms that the commit was accepted by the group so it can be applied locally.
59     // This would normally happen after a server confirmed your commit was accepted and can
60     // be broadcasted.
61     alice_group.apply_pending_commit()?;
62 
63     // Bob joins the group with the welcome message created as part of Alice's commit.
64     let (mut bob_group, _) = bob.join_group(None, &alice_commit.welcome_messages[0])?;
65 
66     // Alice encrypts an application message to Bob.
67     let msg = alice_group.encrypt_application_message(b"hello world", Default::default())?;
68 
69     // Bob decrypts the application message from Alice.
70     let msg = bob_group.process_incoming_message(msg)?;
71 
72     println!("Received message: {:?}", msg);
73 
74     // Alice and bob write the group state to their configured storage engine
75     alice_group.write_to_storage()?;
76     bob_group.write_to_storage()?;
77 
78     Ok(())
79 }
80