Skip to content

Commit

Permalink
feat!: add LeafNode validation
Browse files Browse the repository at this point in the history
  • Loading branch information
beltram committed Sep 18, 2023
1 parent 779048e commit 2e50618
Show file tree
Hide file tree
Showing 75 changed files with 990 additions and 454 deletions.
4 changes: 1 addition & 3 deletions openmls/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ x509-cert = "0.2"
subtle = "2.5"
fluvio-wasm-timer = "0.2"
indexmap = "2.0"
itertools = "0.11"

# Only required for tests.
rand = { version = "0.8", optional = true, features = ["getrandom"] }
getrandom = { version = "0.2", optional = true, features = ["js"] }
serde_json = { version = "1.0", optional = true }
# Crypto backends 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 }
async-lock = { version = "2.7", optional = true }
rstest = { version = "^0.16", optional = true }
Expand All @@ -42,7 +42,6 @@ default = []
crypto-subtle = [] # Enable subtle crypto APIs that have to be used with care.
test-utils = [
"dep:serde_json",
"dep:itertools",
"dep:openmls_rust_crypto",
"dep:rand",
"dep:getrandom",
Expand All @@ -58,7 +57,6 @@ content-debug = [] # ☣️ Enable logging of sensitive message content
[dev-dependencies]
backtrace = "0.3"
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"] }
Expand Down
2 changes: 1 addition & 1 deletion openmls/benches/benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ fn criterion_benchmark(c: &mut Criterion) {

c.bench_with_input(
BenchmarkId::new(
format!("KeyPackage create bundle with ciphersuite"),
"KeyPackage create bundle with ciphersuite".to_string(),
ciphersuite,
),
&(&backend, signer, credential_with_key),
Expand Down
5 changes: 5 additions & 0 deletions openmls/src/binary_tree/array_representation/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ impl<L: Clone + Debug + Default, P: Clone + Debug + Default> ABinaryTree<L, P> {
.map(|(index, leave)| (LeafNodeIndex::new(index as u32), leave))
}

/// Like [Self::leaves] but do not enumerate
pub(crate) fn raw_leaves(&self) -> impl Iterator<Item = &L> {
self.leaf_nodes.iter()
}

/// Returns an iterator over a tuple of the parent index and a reference to
/// a parent, sorted according to their position in the tree from left to
/// right.
Expand Down
2 changes: 1 addition & 1 deletion openmls/src/credentials/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use thiserror::Error;
/// An error that occurs in methods of a [`super::Credential`].
#[derive(Error, Debug, PartialEq, Clone)]
pub enum CredentialError {
/// A library error occured.
/// A library error occurred.
#[error(transparent)]
LibraryError(#[from] LibraryError),
/// The type of credential is not supported.
Expand Down
2 changes: 1 addition & 1 deletion openmls/src/credentials/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ pub enum MlsCredentialType {
/// ```
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub struct Credential {
credential_type: CredentialType,
pub(crate) credential_type: CredentialType,
credential: MlsCredentialType,
}

Expand Down
14 changes: 8 additions & 6 deletions openmls/src/extensions/test_extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ async fn ratchet_tree_extension(ciphersuite: Ciphersuite, backend: &impl OpenMls
test_utils::new_credential(backend, b"Bob", ciphersuite.signature_algorithm()).await;

// Generate KeyPackages
let bob_key_package_bundle = KeyPackageBundle::new(
let bob_kpb = KeyPackageBundle::new(
backend,
&bob_signature_keys,
ciphersuite,
bob_credential_with_key.clone(),
)
.await;
let bob_key_package = bob_key_package_bundle.key_package();
let bob_key_package = bob_kpb.key_package();

let config = CoreGroupConfig {
add_ratchet_tree_extension: true,
Expand Down Expand Up @@ -108,7 +108,8 @@ async fn ratchet_tree_extension(ciphersuite: Ciphersuite, backend: &impl OpenMls
.welcome_option
.expect("An unexpected error occurred."),
None,
bob_key_package_bundle,
bob_kpb.key_package(),
bob_kpb.private_key().clone(),
backend,
ResumptionPskStore::new(1024),
)
Expand All @@ -131,14 +132,14 @@ async fn ratchet_tree_extension(ciphersuite: Ciphersuite, backend: &impl OpenMls
// === Alice creates a group without the ratchet tree extension ===

// Generate KeyPackages
let bob_key_package_bundle = KeyPackageBundle::new(
let bob_kpb = KeyPackageBundle::new(
backend,
&bob_signature_keys,
ciphersuite,
bob_credential_with_key,
)
.await;
let bob_key_package = bob_key_package_bundle.key_package();
let bob_key_package = bob_kpb.key_package();

let config = CoreGroupConfig {
add_ratchet_tree_extension: false,
Expand Down Expand Up @@ -188,7 +189,8 @@ async fn ratchet_tree_extension(ciphersuite: Ciphersuite, backend: &impl OpenMls
.welcome_option
.expect("An unexpected error occurred."),
None,
bob_key_package_bundle,
bob_kpb.key_package(),
bob_kpb.private_key().clone(),
backend,
ResumptionPskStore::new(1024),
)
Expand Down
2 changes: 1 addition & 1 deletion openmls/src/framing/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl Deserialize for MlsMessageIn {

// KeyPackage version must match MlsMessage version.
if let MlsMessageInBody::KeyPackage(key_package) = &body {
if !key_package.version_is_supported(version) {
if !key_package.is_version_supported(version) {
return Err(tls_codec::Error::DecodingError(
"KeyPackage version does not match MlsMessage version.".into(),
));
Expand Down
2 changes: 1 addition & 1 deletion openmls/src/framing/message_in.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ impl MlsMessageIn {
pub fn into_keypackage(self) -> Option<crate::key_packages::KeyPackage> {
match self.body {
MlsMessageInBody::KeyPackage(key_package) => {
debug_assert!(key_package.version_is_supported(self.version));
debug_assert!(key_package.is_version_supported(self.version));
Some(key_package.into())
}
_ => None,
Expand Down
2 changes: 2 additions & 0 deletions openmls/src/framing/mls_auth_content_in.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ impl AuthenticatedContentIn {
crypto: &impl OpenMlsCrypto,
sender_context: Option<SenderContext>,
protocol_version: ProtocolVersion,
group: &PublicGroup,
) -> Result<AuthenticatedContent, ValidationError> {
Ok(AuthenticatedContent {
wire_format: self.wire_format,
Expand All @@ -61,6 +62,7 @@ impl AuthenticatedContentIn {
crypto,
sender_context,
protocol_version,
group,
)?,
auth: self.auth,
})
Expand Down
26 changes: 20 additions & 6 deletions openmls/src/framing/mls_content_in.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use super::{
ContentType, Sender, WireFormat,
};

use crate::prelude::PublicGroup;
use openmls_traits::{crypto::OpenMlsCrypto, types::Ciphersuite};
use serde::{Deserialize, Serialize};
use tls_codec::{
Expand Down Expand Up @@ -55,15 +56,20 @@ impl FramedContentIn {
crypto: &impl OpenMlsCrypto,
sender_context: Option<SenderContext>,
protocol_version: ProtocolVersion,
group: &PublicGroup,
) -> Result<FramedContent, ValidationError> {
Ok(FramedContent {
group_id: self.group_id,
epoch: self.epoch,
sender: self.sender,
authenticated_data: self.authenticated_data,
body: self
.body
.validate(ciphersuite, crypto, sender_context, protocol_version)?,
body: self.body.validate(
ciphersuite,
crypto,
sender_context,
protocol_version,
group,
)?,
})
}
}
Expand Down Expand Up @@ -135,12 +141,19 @@ impl FramedContentBodyIn {
crypto: &impl OpenMlsCrypto,
sender_context: Option<SenderContext>,
protocol_version: ProtocolVersion,
group: &PublicGroup,
) -> Result<FramedContentBody, ValidationError> {
Ok(match self {
FramedContentBodyIn::Application(bytes) => FramedContentBody::Application(bytes),
FramedContentBodyIn::Proposal(proposal_in) => FramedContentBody::Proposal(
proposal_in.validate(crypto, ciphersuite, sender_context, protocol_version)?,
),
FramedContentBodyIn::Proposal(proposal_in) => {
FramedContentBody::Proposal(proposal_in.validate(
crypto,
ciphersuite,
sender_context,
protocol_version,
group,
)?)
}
FramedContentBodyIn::Commit(commit_in) => {
let sender_context = sender_context
.ok_or(LibraryError::custom("Forgot the commit sender context"))?;
Expand All @@ -149,6 +162,7 @@ impl FramedContentBodyIn {
crypto,
sender_context,
protocol_version,
group,
)?)
}
})
Expand Down
21 changes: 12 additions & 9 deletions openmls/src/framing/test_framing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,18 +392,18 @@ async fn unknown_sender(ciphersuite: Ciphersuite, backend: &impl OpenMlsCryptoPr
test_utils::new_credential(backend, b"Charlie", ciphersuite.signature_algorithm()).await;

// Generate KeyPackages
let bob_key_package_bundle =
let bob_kpb =
KeyPackageBundle::new(backend, &bob_signature_keys, ciphersuite, bob_credential).await;
let bob_key_package = bob_key_package_bundle.key_package();
let bob_key_package = bob_kpb.key_package();

let charlie_key_package_bundle = KeyPackageBundle::new(
let charlie_kpb = KeyPackageBundle::new(
backend,
&charlie_signature_keys,
ciphersuite,
charlie_credential,
)
.await;
let charlie_key_package = charlie_key_package_bundle.key_package();
let charlie_key_package = charlie_kpb.key_package();

// Alice creates a group
let mut group_alice = CoreGroup::builder(
Expand Down Expand Up @@ -449,7 +449,8 @@ async fn unknown_sender(ciphersuite: Ciphersuite, backend: &impl OpenMlsCryptoPr
.welcome_option
.expect("An unexpected error occurred."),
Some(group_alice.public_group().export_ratchet_tree().into()),
bob_key_package_bundle,
bob_kpb.key_package(),
bob_kpb.private_key.clone(),
backend,
ResumptionPskStore::new(1024),
)
Expand Down Expand Up @@ -496,7 +497,8 @@ async fn unknown_sender(ciphersuite: Ciphersuite, backend: &impl OpenMlsCryptoPr
.welcome_option
.expect("An unexpected error occurred."),
Some(group_alice.public_group().export_ratchet_tree().into()),
charlie_key_package_bundle,
charlie_kpb.key_package(),
charlie_kpb.private_key.clone(),
backend,
ResumptionPskStore::new(1024),
)
Expand Down Expand Up @@ -631,14 +633,14 @@ pub(crate) async fn setup_alice_bob_group(
test_utils::new_credential(backend, b"Bob", ciphersuite.signature_algorithm()).await;

// Generate KeyPackages
let bob_key_package_bundle = KeyPackageBundle::new(
let bob_kpb = KeyPackageBundle::new(
backend,
&bob_signature_keys,
ciphersuite,
bob_credential.clone(),
)
.await;
let bob_key_package = bob_key_package_bundle.key_package();
let bob_key_package = bob_kpb.key_package();

// Alice creates a group
let mut group_alice = CoreGroup::builder(
Expand Down Expand Up @@ -695,7 +697,8 @@ pub(crate) async fn setup_alice_bob_group(
.welcome_option
.expect("commit didn't return a welcome as expected"),
Some(group_alice.public_group().export_ratchet_tree().into()),
bob_key_package_bundle,
bob_kpb.key_package(),
bob_kpb.private_key.clone(),
backend,
ResumptionPskStore::new(1024),
)
Expand Down
10 changes: 8 additions & 2 deletions openmls/src/framing/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ impl UnverifiedMessage {
ciphersuite: Ciphersuite,
crypto: &impl OpenMlsCrypto,
protocol_version: ProtocolVersion,
group: &PublicGroup,
) -> Result<(AuthenticatedContent, Credential), ProcessMessageError> {
let content: AuthenticatedContentIn = match self.credential.mls_credential() {
MlsCredentialType::Basic(_) => self
Expand Down Expand Up @@ -315,8 +316,13 @@ impl UnverifiedMessage {
.map_err(|_| ProcessMessageError::InvalidSignature)?
}
};
let content =
content.validate(ciphersuite, crypto, self.sender_context, protocol_version)?;
let content = content.validate(
ciphersuite,
crypto,
self.sender_context,
protocol_version,
group,
)?;
Ok((content, self.credential))
}

Expand Down
25 changes: 5 additions & 20 deletions openmls/src/group/core_group/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,27 +349,17 @@ impl CoreGroup {
pub(crate) fn create_add_proposal(
&self,
framing_parameters: FramingParameters,
joiner_key_package: KeyPackage,
key_package: KeyPackage,
signer: &impl Signer,
) -> Result<AuthenticatedContent, CreateAddProposalError> {
if let Some(required_capabilities) = self.required_capabilities() {
joiner_key_package
.leaf_node()
.capabilities()
.supports_required_capabilities(required_capabilities)?;
}
let add_proposal = AddProposal {
key_package: joiner_key_package,
};
let proposal = Proposal::Add(add_proposal);
AuthenticatedContent::member_proposal(
let proposal = Proposal::Add(AddProposal { key_package });
Ok(AuthenticatedContent::member_proposal(
framing_parameters,
self.own_leaf_index(),
proposal,
self.context(),
signer,
)
.map_err(|e| e.into())
)?)
}

// 11.1.2. Update
Expand Down Expand Up @@ -442,7 +432,7 @@ impl CoreGroup {
)
}

/// Checks if the memebers suuport the provided extensions. Pending proposals have to be passed
/// Checks if the members support the provided extensions. Pending proposals have to be passed
/// as parameters as Remove Proposals should be ignored
pub(crate) fn members_support_extensions<'a>(
&self,
Expand Down Expand Up @@ -719,11 +709,6 @@ impl CoreGroup {
self.public_group.group_context().extensions()
}

/// Get the required capabilities extension of this group.
pub(crate) fn required_capabilities(&self) -> Option<&RequiredCapabilitiesExtension> {
self.public_group.required_capabilities()
}

/// Returns `true` if the group uses the ratchet tree extension anf `false
/// otherwise
#[cfg(test)]
Expand Down
Loading

0 comments on commit 2e50618

Please sign in to comment.