Skip to content

Commit

Permalink
Merge pull request #14 from xmtp/nm/merge-upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
neekolas authored Jan 15, 2024
2 parents 1de4d54 + 3ed6ac8 commit ce07d17
Show file tree
Hide file tree
Showing 103 changed files with 2,595 additions and 719 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- [#1464](https://github.com/openmls/openmls/pull/1464): Add builder pattern for `MlsGroup`; split `MlsGroupJoinConfig` into `MlsGroupCreateConfig` and `MlsGroupJoinConfig`

## 0.5.0 (XXXX-XX-XX)

This release has many breaking API changes, a few of them are listed below:
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ members = [
"memory_keystore",
"delivery-service/ds",
"delivery-service/ds-lib",
"basic_credential"
"basic_credential",
]
resolver = "2"

# Central dependency management for some crates
[workspace.dependencies]
tls_codec = { version = "0.3.0", features = ["derive", "serde", "mls"] }
tls_codec = { version = "0.4.0", features = ["derive", "serde", "mls"] }
4 changes: 2 additions & 2 deletions basic_credential/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ p256 = { version = "0.13" }
rand = "0.8"

[features]
clonable = [] # Make the keys clonable
test-utils = [] # Only use for tests!
clonable = [] # Make the keys clonable
test-utils = [] # Only use for tests!
6 changes: 4 additions & 2 deletions basic_credential/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ use openmls_traits::{
use p256::ecdsa::{signature::Signer as P256Signer, Signature, SigningKey};

use rand::rngs::OsRng;
use tls_codec::{TlsDeserialize, TlsSerialize, TlsSize};
use tls_codec::{TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize};

/// A signature key pair for the basic credential.
///
/// This can be used as keys to implement the MLS basic credential. It is a simple
/// private and public key pair with corresponding signature scheme.
#[derive(TlsSerialize, TlsSize, TlsDeserialize, serde::Serialize, serde::Deserialize)]
#[derive(
TlsSerialize, TlsSize, TlsDeserialize, TlsDeserializeBytes, serde::Serialize, serde::Deserialize,
)]
#[cfg_attr(feature = "clonable", derive(Clone))]
pub struct SignatureKeyPair {
private: Vec<u8>,
Expand Down
6 changes: 3 additions & 3 deletions book/src/forward_secrecy.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ When an encrypted message is received, the corresponding decryption key is deriv

OpenMLS can address 3 scenarios:

- The Delivery Service cannot guarantee that application messages from one epoch are sent before the beginning of the next epoch. To address this, applications can configure their groups to keep the necessary key material around for past epochs by setting the `max_past_epochs` field in the `MlsGroupConfig` to the desired number of epochs.
- The Delivery Service cannot guarantee that application messages from one epoch are sent before the beginning of the next epoch. To address this, applications can configure their groups to keep the necessary key material around for past epochs by setting the `max_past_epochs` field in the `MlsGroupCreateConfig` to the desired number of epochs.

- The Delivery Service cannot guarantee that application messages will arrive in order within the same epoch. To address this, applications can configure the `out_of_order_tolerance` parameter of the `SenderRatchetConfiguration`. The configuration can be set as the `sender_ratchet_configuration` parameter of the `MlsGroupConfig`.
- The Delivery Service cannot guarantee that application messages will arrive in order within the same epoch. To address this, applications can configure the `out_of_order_tolerance` parameter of the `SenderRatchetConfiguration`. The configuration can be set as the `sender_ratchet_configuration` parameter of the `MlsGroupCreateConfig`.

- The Delivery Service cannot guarantee that application messages won't be dropped within the same epoch. To address this, applications can configure the `maximum_forward_distance` parameter of the `SenderRatchetConfiguration`. The configuration can be set as the `sender_ratchet_configuration` parameter of the `MlsGroupConfig`.
- The Delivery Service cannot guarantee that application messages won't be dropped within the same epoch. To address this, applications can configure the `maximum_forward_distance` parameter of the `SenderRatchetConfiguration`. The configuration can be set as the `sender_ratchet_configuration` parameter of the `MlsGroupCreateConfig`.
18 changes: 16 additions & 2 deletions book/src/user_manual/create_group.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Creating groups

Before a group can be created, a group configuration (`MlsGroupConfiguration`) needs to be defined. The default values of configuration parameters are picked for safety. However, check all parameters carefully to ascertain if they match your implementation's requirements. See [Group configuration](group_config.md) for more details.
There are two ways to create a group: Either by building an `MlsGroup` directly, or by using an `MlsGroupCreateConfig`. The former is slightly simpler, while the latter allows the creating of multiple groups using the same configuration. See [Group configuration](./group_config.md) for more details on group parameters.

In addition to the group configuration, the client should define all supported and required extensions for the group. The negotiation mechanism for extension in MLS consists in setting an initial list of extensions at group creation time and choosing key packages of subsequent new members accordingly.

Expand All @@ -10,16 +10,30 @@ In practice, the supported and required extensions are set by adding them to the
{{#include ../../../openmls/tests/book_code.rs:create_key_package}}
```

After that, the group can be created:
After that, the group can be created either using a config:

```rust,no_run,noplayground
{{#include ../../../openmls/tests/book_code.rs:alice_create_group}}
```

... or using the builder pattern:

```rust,no_run,noplayground
{{#include ../../../openmls/tests/book_code.rs:alice_create_group_with_builder}}
```

Note: Every group is assigned a random group ID during creation. The group ID cannot be changed and remains immutable throughout the group's lifetime. Choosing it randomly makes sure that the group ID doesn't collide with any other group ID in the same system.

If someone else already gave you a group ID, e.g., a provider server, you can also create a group using a specific group ID:

```rust,no_run,noplayground
{{#include ../../../openmls/tests/book_code.rs:alice_create_group_with_group_id}}
```

The Builder provides methods for setting required capabilities and external senders.
The information passed into these lands in the group context, in the form of extensions.
Should the user want to add further extensions, they can use the `with_group_context_extensions` method:

```rust,no_run,noplayground
{{#include ../../../openmls/tests/book_code.rs:alice_create_group_with_builder_with_extensions}}
```
22 changes: 18 additions & 4 deletions book/src/user_manual/group_config.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Group configuration

The group configuration can be specified by building a `MlsGroupConfig` object or choosing the default value. The default value contains safe values for all parameters and is suitable for scenarios without particular requirements.
Two very similar structs can help configure groups upon their creation: `MlsGroupJoinConfig` and `MlsGroupCreateConfig`.

The following parameters can be set:
`MlsGroupJoinConfig` contains the following runtime-relevant configuration options for an `MlsGroup` and can be set on a per-client basis when a group is joined.

| Name | Type | Explanation |
| ------------------------------ | ------------------------------- | ------------------------------------------------------------------------------------------------ |
Expand All @@ -11,11 +11,25 @@ The following parameters can be set:
| `max_past_epochs` | `usize` | Maximum number of past epochs for which application messages can be decrypted. The default is 0. |
| `number_of_resumption_psks` | `usize` | Number of resumption psks to keep. The default is 0. |
| `use_ratchet_tree_extension` | `bool` | Flag indicating the Ratchet Tree Extension should be used. The default is `false`. |
| `required_capabilities` | `RequiredCapabilitiesExtension` | Required capabilities (extensions and proposal types). |
| `sender_ratchet_configuration` | `SenderRatchetConfiguration` | Sender ratchet configuration. |

Example configuration:
`MlsGroupCreateConfig` contains an `MlsGroupJoinConfig`, as well as a few additional parameters that are part of the group state that is agreed-upon by all group members. It can be set at the time of a group's creation and contains the following additional configuration options.

| Name | Type | Explanation |
| ------------------------------ | ------------------------------- | ------------------------------------------------------------------------------------------------ |
| `required_capabilities` | `RequiredCapabilitiesExtension` | Required capabilities (extensions and proposal types). |
| `external_senders` | `ExternalSendersExtensions` | List credentials of non-group members that are allowed to send proposals to the group. |

Both ways of group configurations can be specified by using the struct's builder pattern, or choosing their default values. The default value contains safe values for all parameters and is suitable for scenarios without particular requirements.

Example join configuration:

```rust,no_run,noplayground
{{#include ../../../openmls/tests/book_code.rs:mls_group_config_example}}
```

Example create configuration:

```rust,no_run,noplayground
{{#include ../../../openmls/tests/book_code.rs:mls_group_create_config_example}}
```
4 changes: 2 additions & 2 deletions book/src/user_manual/join_from_external_commit.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

To join a group with an external commit message, a new `MlsGroup` can be instantiated directly from the `GroupInfo`.
The `GroupInfo`/Ratchet Tree should be shared over a secure channel.
If the RatchetTree extension is not in the required capabilities, then the ratchet tree needs to be provided.
If the RatchetTree extension is not included in the `GroupInfo` as a `GroupInfoExtension`, then the ratchet tree needs to be provided.

The `GroupInfo` can be obtained either from a call to `export_group_info`from the `MlsGroup`:

Expand All @@ -16,7 +16,7 @@ Or from a call to a function that results in a staged commit:
{{#include ../../../openmls/tests/book_code.rs:alice_exports_group_info}}
```

Calling `join_by_external_commit` will join the group and leave it with a commit pending to be merged.
Calling `join_by_external_commit` requires an `MlsGroupJoinConfig` (see [Group configuration](./group_config.md) for more details). The function creates an `MlsGroup` and leave it with a commit pending to be merged.

```rust,no_run,noplayground
{{#include ../../../openmls/tests/book_code.rs:charlie_joins_external_commit}}
Expand Down
3 changes: 1 addition & 2 deletions book/src/user_manual/join_from_welcome.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Join a group from a Welcome message

To join a group from a `Welcome` message, a new `MlsGroup` can be instantiated directly from the `Welcome` message.
If the group configuration does not use the ratchet tree extension, the ratchet tree needs to be provided.
To join a group from a `Welcome` message, a new `MlsGroup` can be instantiated directly from the `Welcome` message and an `MlsGroupJoinConfig` (see [Group configuration](./group_config.md) for more details). If the group configuration does not use the ratchet tree extension, the ratchet tree needs to be provided.

```rust,no_run,noplayground
{{#include ../../../openmls/tests/book_code.rs:bob_joins_with_welcome}}
Expand Down
4 changes: 2 additions & 2 deletions cli/src/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ impl User {

// NOTE: Since the DS currently doesn't distribute copies of the group's ratchet
// tree, we need to include the ratchet_tree_extension.
let group_config = MlsGroupConfig::builder()
let group_config = MlsGroupCreateConfig::builder()
.use_ratchet_tree_extension(true)
.build();

Expand Down Expand Up @@ -672,7 +672,7 @@ impl User {
}
// NOTE: Since the DS currently doesn't distribute copies of the group's ratchet
// tree, we need to include the ratchet_tree_extension.
let group_config = MlsGroupConfig::builder()
let group_config = MlsGroupJoinConfig::builder()
.use_ratchet_tree_extension(true)
.build();
let mut mls_group = MlsGroup::new_from_welcome(&self.crypto, &group_config, welcome, None)
Expand Down
5 changes: 3 additions & 2 deletions delivery-service/ds-lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use std::collections::HashSet;

use openmls::prelude::*;
use tls_codec::{
TlsByteSliceU16, TlsByteVecU16, TlsByteVecU32, TlsByteVecU8, TlsDeserialize, TlsSerialize,
TlsSize, TlsVecU32,
TlsByteSliceU16, TlsByteVecU16, TlsByteVecU32, TlsByteVecU8, TlsDeserialize,
TlsDeserializeBytes, TlsSerialize, TlsSize, TlsVecU32,
};

/// Information about a client.
Expand Down Expand Up @@ -38,6 +38,7 @@ pub struct ClientInfo {
PartialEq,
TlsSerialize,
TlsDeserialize,
TlsDeserializeBytes,
TlsSize,
serde::Serialize,
serde::Deserialize,
Expand Down
6 changes: 3 additions & 3 deletions delivery-service/ds/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ async fn test_list_clients() {
#[actix_rt::test]
async fn test_group() {
let crypto = &OpenMlsRustCrypto::default();
let mls_group_config = MlsGroupConfig::default();
let mls_group_create_config = MlsGroupCreateConfig::default();
let data = web::Data::new(DsData::default());
let app = test::init_service(
App::new()
Expand Down Expand Up @@ -257,7 +257,7 @@ async fn test_group() {
let mut group = MlsGroup::new_with_group_id(
crypto,
&signer_1,
&mls_group_config,
&mls_group_create_config,
group_id,
credential_with_key_1,
)
Expand Down Expand Up @@ -317,7 +317,7 @@ async fn test_group() {

let mut group_on_client2 = MlsGroup::new_from_welcome(
crypto,
&mls_group_config,
mls_group_create_config.join_config(),
welcome_msg
.into_welcome()
.expect("Unexpected message type."),
Expand Down
14 changes: 7 additions & 7 deletions interop_client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use openmls::{
credentials::{Credential, CredentialType, CredentialWithKey},
framing::{MlsMessageIn, MlsMessageInBody, MlsMessageOut, ProcessedMessageContent},
group::{
GroupEpoch, GroupId, MlsGroup, MlsGroupConfig, WireFormatPolicy,
GroupEpoch, GroupId, MlsGroup, MlsGroupCreateConfig, MlsGroupJoinConfig, WireFormatPolicy,
PURE_CIPHERTEXT_WIRE_FORMAT_POLICY, PURE_PLAINTEXT_WIRE_FORMAT_POLICY,
},
key_packages::KeyPackage,
Expand Down Expand Up @@ -230,7 +230,7 @@ impl MlsClient for MlsClientImpl {
// Note: We just use some values here that make live testing work.
// There is nothing special about the used numbers and they
// can be increased (or decreased) depending on the available scenarios.
let mls_group_config = MlsGroupConfig::builder()
let mls_group_config = MlsGroupCreateConfig::builder()
.crypto_config(CryptoConfig::with_default_version(ciphersuite))
.max_past_epochs(32)
.number_of_resumption_psks(32)
Expand Down Expand Up @@ -375,7 +375,7 @@ impl MlsClient for MlsClientImpl {
// Note: We just use some values here that make live testing work.
// There is nothing special about the used numbers and they
// can be increased (or decreased) depending on the available scenarios.
let mls_group_config = MlsGroupConfig::builder()
let mls_group_config = MlsGroupJoinConfig::builder()
.max_past_epochs(32)
.number_of_resumption_psks(32)
.sender_ratchet_configuration(SenderRatchetConfiguration::default())
Expand Down Expand Up @@ -521,7 +521,7 @@ impl MlsClient for MlsClientImpl {
let mls_group_config = {
let wire_format_policy = wire_format_policy(request.encrypt_handshake);

MlsGroupConfig::builder()
MlsGroupJoinConfig::builder()
.max_past_epochs(32)
.number_of_resumption_psks(32)
.sender_ratchet_configuration(SenderRatchetConfiguration::default())
Expand Down Expand Up @@ -818,7 +818,7 @@ impl MlsClient for MlsClientImpl {
// Note: We just use some values here that make live testing work.
// There is nothing special about the used numbers and they
// can be increased (or decreased) depending on the available scenarios.
let mls_group_config = MlsGroupConfig::builder()
let mls_group_config = MlsGroupJoinConfig::builder()
.use_ratchet_tree_extension(true)
.max_past_epochs(32)
.number_of_resumption_psks(32)
Expand Down Expand Up @@ -866,7 +866,7 @@ impl MlsClient for MlsClientImpl {
// Note: We just use some values here that make live testing work.
// There is nothing special about the used numbers and they
// can be increased (or decreased) depending on the available scenarios.
let mls_group_config = MlsGroupConfig::builder()
let mls_group_config = MlsGroupJoinConfig::builder()
.max_past_epochs(32)
.number_of_resumption_psks(32)
.use_ratchet_tree_extension(true)
Expand Down Expand Up @@ -920,7 +920,7 @@ impl MlsClient for MlsClientImpl {
// Note: We just use some values here that make live testing work.
// There is nothing special about the used numbers and they
// can be increased (or decreased) depending on the available scenarios.
let mls_group_config = MlsGroupConfig::builder()
let mls_group_config = MlsGroupJoinConfig::builder()
.max_past_epochs(32)
.number_of_resumption_psks(32)
.use_ratchet_tree_extension(true)
Expand Down
9 changes: 7 additions & 2 deletions openmls/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ serde_json = { version = "1.0", optional = true }
# Crypto providers required for KAT and testing - "test-utils" feature
itertools = { version = "0.10", optional = true }
openmls_rust_crypto = { version = "0.2.0", path = "../openmls_rust_crypto", optional = true }
openmls_basic_credential = { version = "0.2.0", path = "../basic_credential", optional = true, features = ["clonable", "test-utils"] }
openmls_basic_credential = { version = "0.2.0", path = "../basic_credential", optional = true, features = [
"clonable",
"test-utils",
] }
rstest = { version = "^0.16", optional = true }
rstest_reuse = { version = "0.4", optional = true }

Expand All @@ -50,7 +53,9 @@ hex = { version = "0.4", features = ["serde"] }
itertools = "0.10"
lazy_static = "1.4"
openmls = { path = ".", features = ["test-utils"] }
openmls_traits = { version = "0.2.0", path = "../traits", features = ["test-utils"] }
openmls_traits = { version = "0.2.0", path = "../traits", features = [
"test-utils",
] }
pretty_env_logger = "0.5"
rstest = "^0.16"
rstest_reuse = "0.4"
Expand Down
3 changes: 2 additions & 1 deletion openmls/src/binary_tree/array_representation/treemath.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::cmp::Ordering;

use serde::{Deserialize, Serialize};
use tls_codec::{TlsDeserialize, TlsSerialize, TlsSize};
use tls_codec::{TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize};

pub(crate) const MAX_TREE_SIZE: u32 = 1 << 30;
pub(crate) const MIN_TREE_SIZE: u32 = 1;
Expand All @@ -19,6 +19,7 @@ pub(crate) const MIN_TREE_SIZE: u32 = 1;
Serialize,
Deserialize,
TlsDeserialize,
TlsDeserializeBytes,
TlsSerialize,
TlsSize,
)]
Expand Down
Loading

0 comments on commit ce07d17

Please sign in to comment.