1 // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 // Copyright by contributors to this project.
3 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
4 
5 use alloc::vec::Vec;
6 use mls_rs_codec::{MlsDecode, MlsEncode};
7 
8 use mls_rs_core::extension::ExtensionList;
9 
10 use crate::{
11     group::{
12         framing::ContentType,
13         proposal::{
14             AddProposal, ExternalInit, PreSharedKeyProposal, ReInitProposal, RemoveProposal,
15             UpdateProposal,
16         },
17         Commit, GroupSecrets, MlsMessage,
18     },
19     tree_kem::node::NodeVec,
20 };
21 
22 #[derive(serde::Serialize, serde::Deserialize, Debug, Default, Clone)]
23 struct TestCase {
24     #[serde(with = "hex::serde")]
25     mls_welcome: Vec<u8>,
26     #[serde(with = "hex::serde")]
27     mls_group_info: Vec<u8>,
28     #[serde(with = "hex::serde")]
29     mls_key_package: Vec<u8>,
30 
31     #[serde(with = "hex::serde")]
32     ratchet_tree: Vec<u8>,
33     #[serde(with = "hex::serde")]
34     group_secrets: Vec<u8>,
35 
36     #[serde(with = "hex::serde")]
37     add_proposal: Vec<u8>,
38     #[serde(with = "hex::serde")]
39     update_proposal: Vec<u8>,
40     #[serde(with = "hex::serde")]
41     remove_proposal: Vec<u8>,
42     #[serde(with = "hex::serde")]
43     pre_shared_key_proposal: Vec<u8>,
44     #[serde(with = "hex::serde")]
45     re_init_proposal: Vec<u8>,
46     #[serde(with = "hex::serde")]
47     external_init_proposal: Vec<u8>,
48     #[serde(with = "hex::serde")]
49     group_context_extensions_proposal: Vec<u8>,
50 
51     #[serde(with = "hex::serde")]
52     commit: Vec<u8>,
53 
54     #[serde(with = "hex::serde")]
55     public_message_application: Vec<u8>,
56     #[serde(with = "hex::serde")]
57     public_message_proposal: Vec<u8>,
58     #[serde(with = "hex::serde")]
59     public_message_commit: Vec<u8>,
60     #[serde(with = "hex::serde")]
61     private_message: Vec<u8>,
62 }
63 
64 // The test vector can be found here:
65 // https://github.com/mlswg/mls-implementations/blob/main/test-vectors/messages.json
66 #[maybe_async::test(not(mls_build_async), async(mls_build_async, crate::futures_test))]
serialization()67 async fn serialization() {
68     let test_cases: Vec<TestCase> = load_test_case_json!(serialization, Vec::<TestCase>::new());
69 
70     for test_case in test_cases.into_iter() {
71         let message = MlsMessage::from_bytes(&test_case.mls_welcome).unwrap();
72         message.clone().into_welcome().unwrap();
73         assert_eq!(&message.to_bytes().unwrap(), &test_case.mls_welcome);
74 
75         let message = MlsMessage::from_bytes(&test_case.mls_group_info).unwrap();
76         message.clone().into_group_info().unwrap();
77         assert_eq!(&message.to_bytes().unwrap(), &test_case.mls_group_info);
78 
79         let message = MlsMessage::from_bytes(&test_case.mls_key_package).unwrap();
80         message.clone().into_key_package().unwrap();
81         assert_eq!(&message.to_bytes().unwrap(), &test_case.mls_key_package);
82 
83         let tree = NodeVec::mls_decode(&mut &*test_case.ratchet_tree).unwrap();
84 
85         assert_eq!(&tree.mls_encode_to_vec().unwrap(), &test_case.ratchet_tree);
86 
87         let secs = GroupSecrets::mls_decode(&mut &*test_case.group_secrets).unwrap();
88 
89         assert_eq!(&secs.mls_encode_to_vec().unwrap(), &test_case.group_secrets);
90 
91         let proposal = AddProposal::mls_decode(&mut &*test_case.add_proposal).unwrap();
92 
93         assert_eq!(
94             &proposal.mls_encode_to_vec().unwrap(),
95             &test_case.add_proposal
96         );
97 
98         let proposal = UpdateProposal::mls_decode(&mut &*test_case.update_proposal).unwrap();
99 
100         assert_eq!(
101             &proposal.mls_encode_to_vec().unwrap(),
102             &test_case.update_proposal
103         );
104 
105         let proposal = RemoveProposal::mls_decode(&mut &*test_case.remove_proposal).unwrap();
106 
107         assert_eq!(
108             &proposal.mls_encode_to_vec().unwrap(),
109             &test_case.remove_proposal
110         );
111 
112         let proposal = ReInitProposal::mls_decode(&mut &*test_case.re_init_proposal).unwrap();
113 
114         assert_eq!(
115             &proposal.mls_encode_to_vec().unwrap(),
116             &test_case.re_init_proposal
117         );
118 
119         let proposal =
120             PreSharedKeyProposal::mls_decode(&mut &*test_case.pre_shared_key_proposal).unwrap();
121 
122         assert_eq!(
123             &proposal.mls_encode_to_vec().unwrap(),
124             &test_case.pre_shared_key_proposal
125         );
126 
127         let proposal = ExternalInit::mls_decode(&mut &*test_case.external_init_proposal).unwrap();
128 
129         assert_eq!(
130             &proposal.mls_encode_to_vec().unwrap(),
131             &test_case.external_init_proposal
132         );
133 
134         let proposal =
135             ExtensionList::mls_decode(&mut &*test_case.group_context_extensions_proposal).unwrap();
136 
137         assert_eq!(
138             &proposal.mls_encode_to_vec().unwrap(),
139             &test_case.group_context_extensions_proposal
140         );
141 
142         let commit = Commit::mls_decode(&mut &*test_case.commit).unwrap();
143 
144         assert_eq!(&commit.mls_encode_to_vec().unwrap(), &test_case.commit);
145 
146         let message = MlsMessage::from_bytes(&test_case.public_message_application).unwrap();
147         let serialized = message.mls_encode_to_vec().unwrap();
148         assert_eq!(&serialized, &test_case.public_message_application);
149         let content_type = message.into_plaintext().unwrap().content.content_type();
150         assert_eq!(content_type, ContentType::Application);
151 
152         let message = MlsMessage::from_bytes(&test_case.public_message_proposal).unwrap();
153         let serialized = message.mls_encode_to_vec().unwrap();
154         assert_eq!(&serialized, &test_case.public_message_proposal);
155         let content_type = message.into_plaintext().unwrap().content.content_type();
156         assert_eq!(content_type, ContentType::Proposal);
157 
158         let message = MlsMessage::from_bytes(&test_case.public_message_commit).unwrap();
159         let serialized = message.mls_encode_to_vec().unwrap();
160         assert_eq!(&serialized, &test_case.public_message_commit);
161         let content_type = message.into_plaintext().unwrap().content.content_type();
162         assert_eq!(content_type, ContentType::Commit);
163 
164         let message = MlsMessage::from_bytes(&test_case.private_message).unwrap();
165         let serialized = message.mls_encode_to_vec().unwrap();
166         assert_eq!(&serialized, &test_case.private_message);
167         message.into_ciphertext().unwrap();
168     }
169 }
170