use crate::test_utils::*;
use openmls_rust_crypto::OpenMlsRustCrypto;
use tls_codec::{Deserialize, Serialize};
use super::*;
use crate::{
credentials::*, framing::*, group::errors::*, group::*, key_packages::*,
messages::proposals::ProposalType,
};
#[test]
fn capabilities() {
let extension_bytes = [
0u8, 1, 0, 0, 0, 29, 1, 1, 6, 0, 1, 0, 2, 0, 3, 6, 0, 1, 0, 2, 0, 3, 12, 0, 1, 0, 2, 0, 3,
0, 4, 0, 5, 0, 8,
];
let mut extension_bytes_mut = &extension_bytes[..];
let ext = Extension::Capabilities(CapabilitiesExtension::default());
let capabilities_extension = Extension::tls_deserialize(&mut extension_bytes_mut)
.expect("An unexpected error occurred.");
assert_eq!(ext, capabilities_extension);
assert_eq!(
extension_bytes,
&capabilities_extension
.tls_serialize_detached()
.expect("An unexpected error occurred.")[..]
);
let encoded = ext
.tls_serialize_detached()
.expect("error encoding capabilities extension");
let ext_decoded = Extension::tls_deserialize(&mut encoded.as_slice())
.expect("error decoding capabilities extension");
assert_eq!(ext, ext_decoded);
}
#[test]
fn key_package_id() {
let data = &[0u8, 8, 1, 2, 3, 4, 5, 6, 6, 6];
let kpi = ExternalKeyIdExtension::new(&data[2..]);
let kpi_from_bytes = ExternalKeyIdExtension::tls_deserialize(&mut (data as &[u8]))
.expect("An unexpected error occurred.");
assert_eq!(kpi, kpi_from_bytes);
let serialized_extension_struct = kpi
.tls_serialize_detached()
.expect("An unexpected error occurred.");
assert_eq!(&data[..], &serialized_extension_struct);
}
#[test]
fn lifetime() {
let ext = LifetimeExtension::default();
assert!(ext.is_valid());
let ext = LifetimeExtension::new(0);
std::thread::sleep(std::time::Duration::from_secs(1));
assert!(!ext.is_valid());
let serialized = ext
.tls_serialize_detached()
.expect("error encoding life time extension");
let ext_deserialized = LifetimeExtension::tls_deserialize(&mut serialized.as_slice())
.err()
.expect("Didn't get an error deserializing invalid life time extension");
assert_eq!(
ext_deserialized,
tls_codec::Error::DecodingError("Invalid".to_string()),
);
}
#[apply(ciphersuites_and_backends)]
fn ratchet_tree_extension(ciphersuite: Ciphersuite, backend: &impl OpenMlsCryptoProvider) {
let group_aad = b"Alice's test group";
let framing_parameters = FramingParameters::new(group_aad, WireFormat::MlsPlaintext);
let alice_credential_bundle = CredentialBundle::new(
"Alice".into(),
CredentialType::Basic,
ciphersuite.signature_algorithm(),
backend,
)
.expect("An unexpected error occurred.");
let bob_credential_bundle = CredentialBundle::new(
"Bob".into(),
CredentialType::Basic,
ciphersuite.signature_algorithm(),
backend,
)
.expect("An unexpected error occurred.");
let alice_key_package_bundle = KeyPackageBundle::new(
&[ciphersuite],
&alice_credential_bundle,
backend,
Vec::new(),
)
.expect("An unexpected error occurred.");
let bob_key_package_bundle =
KeyPackageBundle::new(&[ciphersuite], &bob_credential_bundle, backend, Vec::new())
.expect("An unexpected error occurred.");
let bob_key_package = bob_key_package_bundle.key_package();
let config = CoreGroupConfig {
add_ratchet_tree_extension: true,
};
let mut alice_group = CoreGroup::builder(GroupId::random(backend), alice_key_package_bundle)
.with_config(config)
.build(backend)
.expect("Error creating group.");
let bob_add_proposal = alice_group
.create_add_proposal(
framing_parameters,
&alice_credential_bundle,
bob_key_package.clone(),
backend,
)
.expect("Could not create proposal.");
let proposal_store = ProposalStore::from_queued_proposal(
QueuedProposal::from_mls_plaintext(ciphersuite, backend, bob_add_proposal)
.expect("Could not create QueuedProposal."),
);
let params = CreateCommitParams::builder()
.framing_parameters(framing_parameters)
.credential_bundle(&alice_credential_bundle)
.proposal_store(&proposal_store)
.force_self_update(false)
.build();
let create_commit_result = alice_group
.create_commit(params, backend)
.expect("Error creating commit");
alice_group
.merge_commit(create_commit_result.staged_commit)
.expect("error merging commit");
let bob_group = match CoreGroup::new_from_welcome(
create_commit_result
.welcome_option
.expect("An unexpected error occurred."),
None,
bob_key_package_bundle,
backend,
) {
Ok(g) => g,
Err(e) => panic!("Could not join group with ratchet tree extension {}", e),
};
assert_eq!(
alice_group.authentication_secret(),
bob_group.authentication_secret()
);
assert!(alice_group.use_ratchet_tree_extension());
assert!(bob_group.use_ratchet_tree_extension());
let alice_key_package_bundle = KeyPackageBundle::new(
&[ciphersuite],
&alice_credential_bundle,
backend,
Vec::new(),
)
.expect("An unexpected error occurred.");
let bob_key_package_bundle =
KeyPackageBundle::new(&[ciphersuite], &bob_credential_bundle, backend, Vec::new())
.expect("An unexpected error occurred.");
let bob_key_package = bob_key_package_bundle.key_package();
let config = CoreGroupConfig {
add_ratchet_tree_extension: false,
};
let mut alice_group = CoreGroup::builder(GroupId::random(backend), alice_key_package_bundle)
.with_config(config)
.build(backend)
.expect("Error creating group.");
let bob_add_proposal = alice_group
.create_add_proposal(
framing_parameters,
&alice_credential_bundle,
bob_key_package.clone(),
backend,
)
.expect("Could not create proposal.");
let proposal_store = ProposalStore::from_queued_proposal(
QueuedProposal::from_mls_plaintext(ciphersuite, backend, bob_add_proposal)
.expect("Could not create staged proposal."),
);
let params = CreateCommitParams::builder()
.framing_parameters(framing_parameters)
.credential_bundle(&alice_credential_bundle)
.proposal_store(&proposal_store)
.force_self_update(false)
.build();
let create_commit_result = alice_group
.create_commit(params, backend)
.expect("Error creating commit");
alice_group
.merge_commit(create_commit_result.staged_commit)
.expect("error merging commit");
let error = CoreGroup::new_from_welcome(
create_commit_result
.welcome_option
.expect("An unexpected error occurred."),
None,
bob_key_package_bundle,
backend,
)
.err();
assert_eq!(
error.expect("We expected an error"),
WelcomeError::MissingRatchetTree
);
}
#[test]
fn required_capabilities() {
let extension_bytes = vec![0u8, 6, 0, 0, 0, 2, 0, 0];
let mut extension_bytes_mut = &extension_bytes[..];
let ext = Extension::RequiredCapabilities(RequiredCapabilitiesExtension::default());
let required_capabilities = Extension::tls_deserialize(&mut extension_bytes_mut)
.expect("An unexpected error occurred.");
assert_eq!(ext, required_capabilities);
assert_eq!(
extension_bytes,
&required_capabilities
.tls_serialize_detached()
.expect("An unexpected error occurred.")[..]
);
let required_capabilities = RequiredCapabilitiesExtension::new(
&[ExtensionType::ExternalKeyId, ExtensionType::RatchetTree],
&[ProposalType::Reinit],
);
let ext = Extension::RequiredCapabilities(required_capabilities);
let extension_bytes = vec![0u8, 6, 0, 0, 0, 8, 4, 0, 3, 0, 5, 2, 0, 5];
let encoded = ext
.tls_serialize_detached()
.expect("error encoding required capabilities extension");
let ext_decoded = Extension::tls_deserialize(&mut encoded.as_slice())
.expect("error decoding required capabilities extension");
assert_eq!(ext, ext_decoded);
assert_eq!(extension_bytes, encoded);
}