File: group_propose_remove.rs

package info (click to toggle)
thunderbird 1%3A140.4.0esr-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,609,432 kB
  • sloc: cpp: 7,672,442; javascript: 5,901,613; ansic: 3,898,954; python: 1,413,343; xml: 653,997; asm: 462,286; java: 180,927; sh: 113,489; makefile: 20,460; perl: 14,288; objc: 13,059; yacc: 4,583; pascal: 3,352; lex: 1,720; ruby: 1,222; exp: 762; sql: 715; awk: 580; php: 436; lisp: 430; sed: 70; csh: 10
file content (252 lines) | stat: -rw-r--r-- 8,674 bytes parent folder | download | duplicates (15)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
// Copyright (c) 2024 Mozilla Corporation and contributors.
// SPDX-License-Identifier: (Apache-2.0 OR MIT)

use mls_platform_api::mls_group_propose_remove;
use mls_platform_api::ClientIdentifiers;
use mls_platform_api::MessageOrAck;
use mls_platform_api::PlatformError;
use mls_platform_api::Received;

//
// Scenario
//
// * Alice, Bob, Charlie create signing identity (generate_signature_keypair)
// * Alice, Bob, Charlie create credentials (generate_credential_basic)
// * Bob and Charlie create key packages (generate_key_package)
// * Alice creates a group (group_create)
// * Alice adds Bob to the group (group_add)
//   - Alice receives her add commit (receive for commit)
//   - Bob joins the group (group_join)
// * Bob adds Charlie to the group
//   - Bob receives the add commit
//   - Alice receives the add commit
//   - Charlie joins the group
// * Bob sends a self remove proposal to the group (group_propose_remove)
//   - Charlie receives the proposal (receive for proposal)
// * Charlie produces the commit for the remove proposal
//   - Alice receives her remove commit
//   - Charlie receives her remove commit
//   - Bob receives her remove commit

#[test]
fn test_group_propose_self_remove() -> Result<(), PlatformError> {
    // Default group configuration
    let group_config = mls_platform_api::GroupConfig::default();

    // Storage states
    let mut state_global = mls_platform_api::state_access("global.db", &[0u8; 32])?;

    // Credentials
    let alice_cred = mls_platform_api::mls_generate_credential_basic("alice".as_bytes())?;
    let bob_cred = mls_platform_api::mls_generate_credential_basic("bob".as_bytes())?;
    let charlie_cred = mls_platform_api::mls_generate_credential_basic("charlie".as_bytes())?;

    println!("\nAlice credential: {}", hex::encode(&alice_cred));
    println!("Bob credential: {}", hex::encode(&bob_cred));
    println!("Charlie credential: {}", hex::encode(&charlie_cred));

    // Create signature keypairs and store them in the state
    let alice_id =
        mls_platform_api::mls_generate_identity(&state_global, group_config.ciphersuite)?;

    let bob_id = mls_platform_api::mls_generate_identity(&state_global, group_config.ciphersuite)?;

    let charlie_id =
        mls_platform_api::mls_generate_identity(&state_global, group_config.ciphersuite)?;

    println!("\nAlice identifier: {}", hex::encode(&alice_id));
    println!("Bob identifier: {}", hex::encode(&bob_id));
    println!("Charlie identifier: {}", hex::encode(&charlie_id));

    // Create Key Package for Bob
    let bob_kp = mls_platform_api::mls_generate_key_package(
        &state_global,
        &bob_id,
        &bob_cred,
        &Default::default(),
    )?;

    // Create Key Package for Charlie
    let charlie_kp = mls_platform_api::mls_generate_key_package(
        &state_global,
        &charlie_id,
        &charlie_cred,
        &Default::default(),
    )?;

    // Create a group with Alice
    let gide = mls_platform_api::mls_group_create(
        &mut state_global,
        &alice_id,
        &alice_cred,
        None,
        None,
        &Default::default(),
    )?;

    println!("\nGroup created by Alice: {}", hex::encode(&gide.group_id));

    // List the members of the group
    let members = mls_platform_api::mls_group_details(&state_global, &gide.group_id, &alice_id)?;
    println!("Members (alice, before adding bob): {members:?}");

    //
    // Alice adds Bob to a group
    //
    println!("\nAlice adds Bob to the Group");
    let commit_output = mls_platform_api::mls_group_add(
        &mut state_global,
        &gide.group_id,
        &alice_id,
        vec![bob_kp],
    )?;

    let welcome = commit_output
        .welcome
        .first()
        .expect("No welcome messages found")
        .clone();

    // Alice process her own commit
    println!("\nAlice process her commit to add Bob to the Group");
    mls_platform_api::mls_receive(
        &state_global,
        &alice_id,
        &MessageOrAck::MlsMessage(commit_output.commit.clone()),
    )?;

    // List the members of the group
    let members = mls_platform_api::mls_group_details(&state_global, &gide.group_id, &alice_id)?;
    println!("Members (alice, after adding bob): {members:?}");

    // Bob joins
    println!("\nBob joins the group created by Alice");
    mls_platform_api::mls_group_join(&state_global, &bob_id, &welcome, None)?;

    // List the members of the group
    let members = mls_platform_api::mls_group_details(&state_global, &gide.group_id, &bob_id)?;
    println!("Members (bob, after joining the group): {members:?}");

    //
    // Bob adds Charlie
    //
    println!("\nBob adds Charlie to the Group");
    let commit_2_output = mls_platform_api::mls_group_add(
        &mut state_global,
        &gide.group_id,
        &bob_id,
        vec![charlie_kp],
    )?;

    let commit_2 = commit_2_output.commit;
    let welcome_2 = commit_2_output
        .welcome
        .first()
        .expect("No welcome messages found")
        .clone();

    // Bobs process its commit
    println!("\nBob process their Commit");
    mls_platform_api::mls_receive(
        &state_global,
        &bob_id,
        &MessageOrAck::MlsMessage(commit_2.clone()),
    )?;

    // List the members of the group
    let members = mls_platform_api::mls_group_details(&state_global, &gide.group_id, &bob_id)?;
    println!("Members (bob, after adding charlie): {members:?}");

    // Alice receives the commit
    println!("\nAlice receives the commit from Bob to add Charlie");
    mls_platform_api::mls_receive(
        &state_global,
        &alice_id,
        &MessageOrAck::MlsMessage(commit_2),
    )?;

    // Charlie joins
    println!("\nCharlie joins the group");
    mls_platform_api::mls_group_join(&state_global, &charlie_id, &welcome_2, None)?;

    // List the members of the group
    let members = mls_platform_api::mls_group_details(&state_global, &gide.group_id, &charlie_id)?;
    println!("Members (charlie, after joining the group): {members:?}");

    //
    // Bob proposes to remove itself
    //
    println!("\nBob proposes a self remove");
    let self_remove_proposal =
        mls_group_propose_remove(&state_global, &gide.group_id, &bob_id, &bob_id)?;

    //
    // Charlie receives the proposal from Bob
    //
    println!("\nCharlie commits to the remove");
    let recv_commit_output_5 = mls_platform_api::mls_receive(
        &state_global,
        &charlie_id,
        &MessageOrAck::MlsMessage(self_remove_proposal.clone()),
    )?;

    let (_, Received::CommitOutput(commit_output_5)) = recv_commit_output_5 else {
        panic!("Expected a different type.");
    };

    let commit_5_msg = MessageOrAck::MlsMessage(commit_output_5.commit);

    // Alice processes the remove commit
    println!("\nAlice processes the remove commit");
    mls_platform_api::mls_receive(
        &state_global,
        &alice_id,
        &MessageOrAck::MlsMessage(self_remove_proposal.clone()),
    )?;
    mls_platform_api::mls_receive(&state_global, &alice_id, &commit_5_msg)?;

    let members_alice =
        mls_platform_api::mls_group_details(&state_global, &gide.group_id, &alice_id)?;
    println!("Members (alice, after removing Bob): {members_alice:?}");

    // Charlie processes the remove commit
    println!("\nCharlie processes the remove commit");
    mls_platform_api::mls_receive(&state_global, &charlie_id, &commit_5_msg)?;

    let members_charlie =
        mls_platform_api::mls_group_details(&state_global, &gide.group_id, &charlie_id)?;
    println!("Members (charlie, after removing bob): {members_charlie:?}");

    // Bob processes the remove commit
    println!("\nBob processes the remove commit");

    // https://github.com/awslabs/mls-rs/pull/154
    // mls_platform_api::mls_receive(
    //     &state_global,
    //     &bob_id,
    //     MlsMessageOrAck::MlsMessage(self_remove_proposal),
    // )?;

    let out_5_bob = mls_platform_api::mls_receive(&state_global, &bob_id, &commit_5_msg)?;

    println!("Bob, out_commit_5 {out_5_bob:?}");
    println!("Bob's state for the group has been removed");
    // Note: Bob cannot look at its own group state because it was already removed

    // Check if Bob is present in the group
    let bob_present = members_alice
        .group_members
        .iter()
        .any(|ClientIdentifiers { identity, .. }| identity == &bob_id);

    // Test that bob was removed from the group
    assert!(
        !bob_present,
        "Bob should not be in the group members after removal"
    );

    // Test that Alice and Charlie have the same group
    assert!(members_alice == members_charlie);

    Ok(())
}