openmls/test_utils/frankenstein/
crypto.rs

1use openmls_traits::{crypto::OpenMlsCrypto, signatures::Signer, types::Ciphersuite};
2use tls_codec::{Serialize, TlsSerialize, TlsSize, VLBytes};
3
4use super::FrankenAuthenticatedContentTbm;
5
6/// Computes a valid membership tag for the provided content.
7pub fn compute_membership_tag(
8    crypto: &impl OpenMlsCrypto,
9    ciphersuite: Ciphersuite,
10    membership_key: &[u8],
11    auth_content_tbm: &FrankenAuthenticatedContentTbm,
12) -> VLBytes {
13    let serialized_auth_content_tbm = &auth_content_tbm.tls_serialize_detached().unwrap();
14    crypto
15        .hmac(
16            ciphersuite.hash_algorithm(),
17            membership_key,              // Extract salt is HMAC key
18            serialized_auth_content_tbm, // Extract ikm is HMAC message
19        )
20        .unwrap()
21        .as_slice()
22        .into()
23}
24
25/// Implements the "sign with label" function of the spec.
26pub fn sign_with_label(signer: &impl Signer, label: &[u8], msg: &[u8]) -> Vec<u8> {
27    let data = FrankenSignContent::new(label, msg)
28        .tls_serialize_detached()
29        .unwrap();
30    signer.sign(&data).unwrap()
31}
32
33#[derive(Debug, Clone, PartialEq, Eq, TlsSerialize, TlsSize)]
34pub struct FrankenSignContent<'a> {
35    label: Vec<u8>,
36    content: &'a [u8],
37}
38
39impl<'a> FrankenSignContent<'a> {
40    pub fn new(label: &[u8], content: &'a [u8]) -> Self {
41        let mut tagged_label = b"MLS 1.0 ".to_vec();
42        tagged_label.extend_from_slice(label);
43
44        Self {
45            label: tagged_label,
46            content,
47        }
48    }
49}