Skip to content

Commit 6661000

Browse files
author
Marta Mularczyk
committed
Add example for 1x API
1 parent 02db1ec commit 6661000

File tree

9 files changed

+127
-19
lines changed

9 files changed

+127
-19
lines changed

.github/workflows/native_build.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ jobs:
4343
run: cargo test --no-default-features --features std,test_util,non-fips --verbose --workspace
4444
- name: Examples
4545
working-directory: mls-rs
46-
run: cargo run --example basic_usage
46+
run: |
47+
cargo run --example basic_usage
48+
cargo run --example api_1x
4749
AsyncBuildAndTest:
4850
strategy:
4951
matrix:

mls-rs/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ criterion = { version = "0.5.1", features = ["async_futures", "html_reports"] }
113113
name = "basic_usage"
114114
required-features = []
115115

116+
[[example]]
117+
name = "api_1x"
118+
required-features = []
119+
116120
[[example]]
117121
name = "x509"
118122
required-features = ["x509"]

mls-rs/examples/api_1x.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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 std::convert::Infallible;
6+
7+
use mls_rs::{
8+
client_builder::MlsConfig,
9+
error::MlsError,
10+
identity::{
11+
basic::{BasicCredential, BasicIdentityProvider},
12+
SigningIdentity,
13+
},
14+
CipherSuite, CipherSuiteProvider, Client, CryptoProvider, ExtensionList, KeyPackageStorage,
15+
};
16+
use mls_rs_core::key_package::KeyPackageData;
17+
18+
const CIPHERSUITE: CipherSuite = CipherSuite::CURVE25519_AES128;
19+
20+
fn main() -> Result<(), MlsError> {
21+
let crypto_provider = mls_rs_crypto_openssl::OpensslCryptoProvider::default();
22+
23+
// Create clients for Alice and Bob
24+
let alice = make_client(crypto_provider.clone(), "alice")?;
25+
let bob = make_client(crypto_provider.clone(), "bob")?;
26+
27+
// Bob generates key package. We store secrets in memory, no need for any storage.
28+
let key_package_generation = bob
29+
.key_package_builder(CIPHERSUITE)?
30+
.valid_for_sec(123)
31+
.build()?;
32+
33+
let stored_secrets = key_package_generation.key_package_data;
34+
35+
// Alice creates a group with Bob.
36+
let mut alice_group = alice.create_group(ExtensionList::default(), Default::default())?;
37+
38+
let welcomes = alice_group
39+
.commit_builder()
40+
.add_member(key_package_generation.key_package_message)?
41+
.build()?
42+
.welcome_messages;
43+
44+
alice_group.apply_pending_commit()?;
45+
46+
// Bob joins
47+
let mut bob_group = bob.group_joiner(&welcomes[0], stored_secrets)?.join()?.0;
48+
49+
// Alice and bob can chat
50+
let msg = alice_group.encrypt_application_message(b"hello world", Default::default())?;
51+
let msg = bob_group.process_incoming_message(msg)?;
52+
53+
println!("Received message: {:?}", msg);
54+
55+
Ok(())
56+
}
57+
58+
#[derive(Clone)]
59+
struct NoOpKeyPackageStorage;
60+
61+
impl KeyPackageStorage for NoOpKeyPackageStorage {
62+
type Error = Infallible;
63+
64+
fn delete(&mut self, _: &[u8]) -> Result<(), Infallible> {
65+
Ok(())
66+
}
67+
68+
fn get(&self, _: &[u8]) -> Result<Option<KeyPackageData>, Infallible> {
69+
Ok(None)
70+
}
71+
72+
fn insert(&mut self, _: Vec<u8>, _: KeyPackageData) -> Result<(), Infallible> {
73+
Ok(())
74+
}
75+
}
76+
77+
fn make_client<P: CryptoProvider + Clone>(
78+
crypto_provider: P,
79+
name: &str,
80+
) -> Result<Client<impl MlsConfig>, MlsError> {
81+
let cipher_suite = crypto_provider.cipher_suite_provider(CIPHERSUITE).unwrap();
82+
let (secret, public) = cipher_suite.signature_key_generate().unwrap();
83+
let basic_identity = BasicCredential::new(name.as_bytes().to_vec());
84+
let signing_identity = SigningIdentity::new(basic_identity.into_credential(), public);
85+
86+
Ok(Client::builder()
87+
.identity_provider(BasicIdentityProvider)
88+
.crypto_provider(crypto_provider)
89+
.signing_identity(signing_identity, secret, CIPHERSUITE)
90+
.key_package_repo(NoOpKeyPackageStorage)
91+
.build())
92+
}

mls-rs/src/client.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,13 @@ where
605605
welcome_message: &'a MlsMessage,
606606
key_package_data: KeyPackageData,
607607
) -> Result<GroupJoiner<'a, 'b, C>, MlsError> {
608-
GroupJoiner::new(self.config.clone(), welcome_message, key_package_data).await
608+
GroupJoiner::new(
609+
self.config.clone(),
610+
welcome_message,
611+
key_package_data,
612+
self.signer.clone(),
613+
)
614+
.await
609615
}
610616

611617
/// Decrypt GroupInfo encrypted in the Welcome message without actually joining

mls-rs/src/group/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,7 +1490,7 @@ impl<C: ClientConfig> Group<C> {
14901490
let key_package_data =
14911491
find_key_package_generation(&config.key_package_repo(), &key_package_refs).await?;
14921492

1493-
let (group_info, _, _) = GroupJoiner::new(config.clone(), welcome, key_package_data)
1493+
let (group_info, _, _) = GroupJoiner::new(config.clone(), welcome, key_package_data, None)
14941494
.await?
14951495
.decrypt_group_info()
14961496
.await?;
@@ -1499,7 +1499,6 @@ impl<C: ClientConfig> Group<C> {
14991499
}
15001500

15011501
#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
1502-
15031502
pub(crate) async fn decrypt_group_secrets<'a>(
15041503
welcome: &'a MlsMessage,
15051504
config: &C,

mls-rs/src/group/resumption.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,8 @@ async fn resumption_join_group<C: ClientConfig + Clone>(
298298
let key_package_data =
299299
find_key_package_generation(&config.key_package_repo(), &key_package_refs).await?;
300300

301-
let mut joiner = GroupJoiner::new(config.clone(), welcome, key_package_data)
301+
let mut joiner = GroupJoiner::new(config.clone(), welcome, key_package_data, Some(signer))
302302
.await?
303-
.signature_secret_key(signer)
304303
.additional_psk(psk_input);
305304

306305
if let Some(tree) = tree_data {

mls-rs/src/group_joiner.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ impl<'a, 'b, C: ClientConfig> GroupJoiner<'a, 'b, C> {
100100
config: C,
101101
welcome_msg: &'a MlsMessage,
102102
key_package_data: KeyPackageData,
103+
signer: Option<SignatureSecretKey>,
103104
) -> Result<Self, MlsError> {
104105
let key_package = KeyPackage::mls_decode(&mut &*key_package_data.key_package_bytes)?;
105106
let init_key = &key_package_data.init_key;
@@ -115,7 +116,7 @@ impl<'a, 'b, C: ClientConfig> GroupJoiner<'a, 'b, C> {
115116
version: welcome_msg.version,
116117
key_package,
117118
leaf_secret: key_package_data.leaf_node_key,
118-
signer: None,
119+
signer,
119120
#[cfg(feature = "psk")]
120121
additional_psk: None,
121122
})

mls-rs/src/key_package/builder.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use alloc::vec;
88
use mls_rs_codec::{MlsDecode, MlsEncode, MlsSize};
99
use mls_rs_core::error::IntoAnyError;
1010
use mls_rs_core::extension::MlsExtension;
11+
use mls_rs_core::key_package::KeyPackageData;
1112

1213
use crate::client::MlsError;
1314
use crate::client_config::ClientConfig;
@@ -124,17 +125,23 @@ impl<CP: CipherSuiteProvider> KeyPackageBuilder<'_, CP> {
124125
.sign(&self.cipher_suite_provider, signing_key, &())
125126
.await?;
126127

128+
let package_bytes = package.mls_encode_to_vec()?;
129+
let reference = package.to_reference(&self.cipher_suite_provider).await?;
130+
131+
let key_package_message = MlsMessage::new(
132+
self.protocol_version,
133+
MlsMessagePayload::KeyPackage(package),
134+
);
135+
127136
Ok(KeyPackageGeneration {
128-
reference: package.to_reference(&self.cipher_suite_provider).await?,
129-
key_package_message: MlsMessage::new(
130-
self.protocol_version,
131-
MlsMessagePayload::KeyPackage(package),
132-
),
133-
secrets: KeyPackageSecrets {
137+
reference,
138+
key_package_data: KeyPackageData::new(
139+
package_bytes,
134140
init_secret_key,
135141
leaf_node_secret,
136-
},
137-
not_after: lifetime.not_after,
142+
lifetime.not_after,
143+
),
144+
key_package_message,
138145
})
139146
}
140147
}
@@ -150,8 +157,7 @@ pub struct KeyPackageSecrets {
150157
pub struct KeyPackageGeneration {
151158
pub reference: KeyPackageRef,
152159
pub key_package_message: MlsMessage,
153-
pub secrets: KeyPackageSecrets,
154-
pub not_after: u64,
160+
pub key_package_data: KeyPackageData,
155161
}
156162

157163
impl<'a, CP> KeyPackageBuilder<'a, CP> {
@@ -253,7 +259,7 @@ mod tests {
253259
let opened = cipher_suite_provider
254260
.hpke_open(
255261
&sealed,
256-
&generated.secrets.init_secret_key,
262+
&generated.key_package_data.init_key,
257263
&generated_kp.hpke_init_key,
258264
&[],
259265
None,

mls-rs/src/key_package/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ mod validator;
2626
pub(crate) use validator::*;
2727

2828
pub(crate) mod generator;
29-
//pub use builder::*;
3029
pub(crate) use generator::*;
3130

3231
#[non_exhaustive]

0 commit comments

Comments
 (0)