Skip to content

Commit

Permalink
Key Package Generation / Join API 1.x (#226)
Browse files Browse the repository at this point in the history
* Fix CI (#223)

* feat(mls-rs): Verify the update path even in case of a self removal (#224)

* Fix bug where double-hitting a ciphertext deleted the whole ratchet (#228)

Co-authored-by: Marta Mularczyk <[email protected]>

* Work around rust < 1.78 crash (#231)

Somehow the DWARF info generated by the compiler for the
`hash`-replacement assignment is confusing to LLVM, which crashes.

By using a different form for the same operation, the compiler is happy.

* Avoid intermediate Vec in TreeKemPublic::update_hashes (#230)

[slice, slice].concat() creates an intermediate Vec, which can be
avoided by chaining updated_leaves and trailing_blanks before the first
Vec is created.

* Add API for deleting exporters (#227)

* Add API for deleting exporters

* Apply suggestions from code review

Co-authored-by: Stephane Raux <[email protected]>

---------

Co-authored-by: Marta Mularczyk <[email protected]>
Co-authored-by: Tom Leavy <[email protected]>
Co-authored-by: Stephane Raux <[email protected]>

* Key package generation 1.x

* Fix clippy warnings

* Initial implementation of group join 1.x

* Add example for 1x API

* Apply suggestions from code review

* Add SigningData struct

* Fixup

* Add more tests

* Fixup

* Fixup

---------

Co-authored-by: Félix Lescaudey de Maneville <[email protected]>
Co-authored-by: Marta Mularczyk <[email protected]>
Co-authored-by: Mike Hommey <[email protected]>
Co-authored-by: Tom Leavy <[email protected]>
Co-authored-by: Stephane Raux <[email protected]>
  • Loading branch information
6 people authored Jan 7, 2025
1 parent cb25022 commit 8da6828
Show file tree
Hide file tree
Showing 51 changed files with 1,230 additions and 474 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/native_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ jobs:
run: cargo test --no-default-features --features std,test_util,non-fips --verbose --workspace
- name: Examples
working-directory: mls-rs
run: cargo run --example basic_usage
run: |
cargo run --example basic_usage
cargo run --example api_1x
AsyncBuildAndTest:
strategy:
matrix:
Expand Down
4 changes: 2 additions & 2 deletions mls-rs-codec/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ thiserror = { version = "1.0.40", optional = true }
assert_matches = "1.5.0"

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen-test = { version = "0.3.26", default-features = false }
wasm-bindgen-test = { version = "=0.3.26", default-features = false }

[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = { version = "0.2.79" }
wasm-bindgen = { version = "=0.2.87" }

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(mls_build_async)'] }
6 changes: 3 additions & 3 deletions mls-rs-codec/src/cow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use alloc::{

use crate::{Error, MlsDecode, MlsEncode, MlsSize};

impl<'a, T> MlsSize for Cow<'a, T>
impl<T> MlsSize for Cow<'_, T>
where
T: MlsSize + ToOwned,
{
Expand All @@ -14,7 +14,7 @@ where
}
}

impl<'a, T> MlsEncode for Cow<'a, T>
impl<T> MlsEncode for Cow<'_, T>
where
T: MlsEncode + ToOwned,
{
Expand All @@ -24,7 +24,7 @@ where
}
}

impl<'a, T> MlsDecode for Cow<'a, T>
impl<T> MlsDecode for Cow<'_, T>
where
T: ToOwned,
<T as ToOwned>::Owned: MlsDecode,
Expand Down
4 changes: 2 additions & 2 deletions mls-rs-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ async-trait = "0.1.74"
assert_matches = "1.5.0"

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen-test = { version = "0.3.26", default-features = false }
wasm-bindgen-test = { version = "=0.3.26", default-features = false }

[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = { version = "^0.2.79" }
wasm-bindgen = { version = "=0.2.87" }

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(mls_build_async)', 'cfg(coverage_nightly)'] }
9 changes: 9 additions & 0 deletions mls-rs-core/src/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,17 @@ mod x509;

pub use basic::*;
pub use credential::*;
use mls_rs_codec::{MlsDecode, MlsEncode, MlsSize};
pub use provider::*;
pub use signing_identity::*;

#[cfg(feature = "x509")]
pub use x509::*;

use crate::crypto::SignatureSecretKey;

#[derive(Clone, Debug, MlsEncode, MlsSize, MlsDecode, PartialEq)]
pub struct SigningData {
pub signing_identity: SigningIdentity,
pub signing_key: SignatureSecretKey,
}
2 changes: 1 addition & 1 deletion mls-rs-core/src/identity/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub enum MemberValidationContext<'a> {
None,
}

impl<'a> MemberValidationContext<'a> {
impl MemberValidationContext<'_> {
pub fn new_extensions(&self) -> Option<&ExtensionList> {
match self {
Self::ForCommit { new_extensions, .. } => Some(*new_extensions),
Expand Down
2 changes: 1 addition & 1 deletion mls-rs-crypto-awslc/src/x509/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ pub struct X509ExtensionContext<'a> {
pub(crate) phantom: PhantomData<&'a Certificate>,
}

impl<'a> X509ExtensionContext<'a> {
impl X509ExtensionContext<'_> {
pub fn as_mut_ptr(&mut self) -> *mut X509V3_CTX {
&mut self.inner
}
Expand Down
2 changes: 1 addition & 1 deletion mls-rs-crypto-hpke/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ hex = { version = "^0.4.3", features = ["serde"] }
mls-rs-crypto-traits = { path = "../mls-rs-crypto-traits", features = ["mock"], version = "0.12.0" }

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen-test = { version = "0.3.26", default-features = false }
wasm-bindgen-test = { version = "=0.3.26", default-features = false }
getrandom = { version = "0.2", features = ["js"] }

[target.'cfg(mls_build_async)'.dependencies]
Expand Down
2 changes: 1 addition & 1 deletion mls-rs-crypto-rustcrypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ mls-rs-crypto-hpke = { path = "../mls-rs-crypto-hpke", default-features = false,
async-trait = "0.1.74"

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen-test = { version = "0.3.26", default-features = false }
wasm-bindgen-test = { version = "=0.3.26", default-features = false }

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(mls_build_async)'] }
4 changes: 2 additions & 2 deletions mls-rs-crypto-webcrypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ zeroize = { version = "1", features = ["zeroize_derive"] }
maybe-async = "0.2.10"
async-trait = "0.1.74"
js-sys = "0.3.64"
wasm-bindgen = "0.2.87"
wasm-bindgen = "=0.2.87"
wasm-bindgen-futures = "0.4.37"
serde-wasm-bindgen = "0.6"
serde = { version = "1.0", features = ["derive"] }
Expand All @@ -27,7 +27,7 @@ const-oid = { version = "0.9", features = ["db"] }

[dev-dependencies]
mls-rs-core = { path = "../mls-rs-core", version = "0.20.0", features = ["test_suite"] }
wasm-bindgen-test = { version = "0.3.26", default-features = false }
wasm-bindgen-test = { version = "=0.3.26", default-features = false }
futures-test = "0.3.25"
serde_json = "^1.0"
hex = { version = "^0.4.3", features = ["serde"] }
Expand Down
4 changes: 2 additions & 2 deletions mls-rs-crypto-webcrypto/src/aead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ impl Aead {
.then_some(())
.ok_or(CryptoError::WrongKeyLength)?;

let params = AesGcmParams::new(key_type.algorithm(), &Uint8Array::from(nonce));
let mut params = AesGcmParams::new(key_type.algorithm(), &Uint8Array::from(nonce));
let aad = Uint8Array::from(aad.unwrap_or_default());
params.set_additional_data(&aad);
params.additional_data(&aad);
let key = key_type.import(&crypto, key).await?;

let out = match key_type {
Expand Down
4 changes: 2 additions & 2 deletions mls-rs-crypto-webcrypto/src/key_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ impl KeyType {
| KeyType::EcdhSecret(curve)
| KeyType::EcdsaPublic(curve)
| KeyType::EcdsaSecret(curve) => {
let params = EcKeyImportParams::new(self.algorithm());
params.set_named_curve(curve);
let mut params = EcKeyImportParams::new(self.algorithm());
params.named_curve(curve);

crypto.import_key_with_object(self.format(), &key, &params, true, &key_usages)?
}
Expand Down
4 changes: 2 additions & 2 deletions mls-rs-identity-x509/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ assert_matches = "1"
rand = "0.8"

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen-test = { version = "0.3.26", default-features = false }
wasm-bindgen-test = { version = "=0.3.26", default-features = false }
getrandom = { version = "0.2", features = ["js"] }


[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = { version = "^0.2.79" }
wasm-bindgen = { version = "=0.2.87" }

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(mls_build_async)'] }
2 changes: 1 addition & 1 deletion mls-rs-provider-sqlite/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ license = "Apache-2.0 OR MIT"
[dependencies]
mls-rs-core = { path = "../mls-rs-core", version = "0.20.0" }
thiserror = "1.0.40"
wasm-bindgen = { version = "0.2", optional = true }
wasm-bindgen = { version = "=0.2.87", optional = true }
zeroize = { version = "1", features = ["zeroize_derive"] }
rusqlite = { version = "0.31", default-features = false }
rand = "0.8"
Expand Down
10 changes: 7 additions & 3 deletions mls-rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mls-rs"
version = "0.43.1"
version = "0.43.2"
edition = "2021"
description = "An implementation of Messaging Layer Security (RFC 9420)"
homepage = "https://github.com/awslabs/mls-rs"
Expand Down Expand Up @@ -96,12 +96,12 @@ serde = { version = "1.0", default-features = false, features = ["alloc", "deriv
hex = { version = "^0.4.3", default-features = false, features = ["serde", "alloc"] }

[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = { version = "^0.2.79" }
wasm-bindgen = { version = "=0.2.87" }
getrandom = { version = "0.2", features = ["js", "custom"], default-features = false }
rand_core = { version = "0.6", default-features = false, features = ["alloc"] }

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen-test = { version = "0.3.26", default-features = false }
wasm-bindgen-test = { version = "=0.3.26", default-features = false }
mls-rs-crypto-webcrypto = { path = "../mls-rs-crypto-webcrypto", version = "0.6.0" }
criterion = { version = "0.5.1", default-features = false, features = ["plotters", "cargo_bench_support", "async_futures", "html_reports"] }

Expand All @@ -113,6 +113,10 @@ criterion = { version = "0.5.1", features = ["async_futures", "html_reports"] }
name = "basic_usage"
required-features = []

[[example]]
name = "api_1x"
required-features = []

[[example]]
name = "x509"
required-features = ["x509"]
Expand Down
92 changes: 92 additions & 0 deletions mls-rs/examples/api_1x.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// Copyright by contributors to this project.
// SPDX-License-Identifier: (Apache-2.0 OR MIT)

use std::convert::Infallible;

use mls_rs::{
client_builder::MlsConfig,
error::MlsError,
identity::{
basic::{BasicCredential, BasicIdentityProvider},
SigningIdentity,
},
CipherSuite, CipherSuiteProvider, Client, CryptoProvider, ExtensionList, KeyPackageStorage,
};
use mls_rs_core::key_package::KeyPackageData;

const CIPHERSUITE: CipherSuite = CipherSuite::CURVE25519_AES128;

fn main() -> Result<(), MlsError> {
let crypto_provider = mls_rs_crypto_openssl::OpensslCryptoProvider::default();

// Create clients for Alice and Bob
let alice = make_client(crypto_provider.clone(), "alice")?;
let bob = make_client(crypto_provider.clone(), "bob")?;

// Bob generates key package. We store secrets in memory, no need for any storage.
let key_package_generation = bob
.key_package_builder(CIPHERSUITE, None)?
.valid_for_sec(123)
.build()?;

let stored_secrets = key_package_generation.key_package_data;

// Alice creates a group with Bob.
let mut alice_group = alice.create_group(ExtensionList::default(), Default::default())?;

let welcomes = alice_group
.commit_builder()
.add_member(key_package_generation.key_package_message)?
.build()?
.welcome_messages;

alice_group.apply_pending_commit()?;

// Bob joins
let mut bob_group = bob.group_joiner(&welcomes[0], stored_secrets)?.join()?.0;

// Alice and bob can chat
let msg = alice_group.encrypt_application_message(b"hello world", Default::default())?;
let msg = bob_group.process_incoming_message(msg)?;

println!("Received message: {:?}", msg);

Ok(())
}

#[derive(Clone)]
struct NoOpKeyPackageStorage;

impl KeyPackageStorage for NoOpKeyPackageStorage {
type Error = Infallible;

fn delete(&mut self, _: &[u8]) -> Result<(), Infallible> {
Ok(())
}

fn get(&self, _: &[u8]) -> Result<Option<KeyPackageData>, Infallible> {
Ok(None)
}

fn insert(&mut self, _: Vec<u8>, _: KeyPackageData) -> Result<(), Infallible> {
Ok(())
}
}

fn make_client<P: CryptoProvider + Clone>(
crypto_provider: P,
name: &str,
) -> Result<Client<impl MlsConfig>, MlsError> {
let cipher_suite = crypto_provider.cipher_suite_provider(CIPHERSUITE).unwrap();
let (secret, public) = cipher_suite.signature_key_generate().unwrap();
let basic_identity = BasicCredential::new(name.as_bytes().to_vec());
let signing_identity = SigningIdentity::new(basic_identity.into_credential(), public);

Ok(Client::builder()
.identity_provider(BasicIdentityProvider)
.crypto_provider(crypto_provider)
.signing_identity(signing_identity, secret, CIPHERSUITE)
.key_package_repo(NoOpKeyPackageStorage)
.build())
}
Loading

0 comments on commit 8da6828

Please sign in to comment.