| 280 | } |
| 281 | |
| 282 | std::tuple<MLSMessage, State> |
| 283 | State::external_join(const bytes& leaf_secret, |
| 284 | SignaturePrivateKey sig_priv, |
| 285 | const KeyPackage& key_package, |
| 286 | const GroupInfo& group_info, |
| 287 | const std::optional<TreeKEMPublicKey>& tree, |
| 288 | const MessageOpts& msg_opts, |
| 289 | std::optional<LeafIndex> remove_prior, |
| 290 | const std::map<bytes, bytes>& psks) |
| 291 | { |
| 292 | // Create a preliminary state |
| 293 | auto initial_state = State(std::move(sig_priv), group_info, tree); |
| 294 | |
| 295 | // Look up the external public key for the group |
| 296 | const auto maybe_external_pub = |
| 297 | group_info.extensions.find<ExternalPubExtension>(); |
| 298 | if (!maybe_external_pub) { |
| 299 | throw InvalidParameterError("No external pub in GroupInfo"); |
| 300 | } |
| 301 | |
| 302 | const auto& external_pub = opt::get(maybe_external_pub).external_pub; |
| 303 | |
| 304 | // Insert an ExternalInit proposal |
| 305 | auto opts = CommitOpts{}; |
| 306 | auto [enc, force_init_secret] = |
| 307 | KeyScheduleEpoch::external_init(key_package.cipher_suite, external_pub); |
| 308 | auto ext_init = Proposal{ ExternalInit{ enc } }; |
| 309 | opts.extra_proposals.push_back(ext_init); |
| 310 | |
| 311 | // Evict a prior appearance if required |
| 312 | if (remove_prior) { |
| 313 | auto remove = initial_state.remove_proposal(opt::get(remove_prior)); |
| 314 | opts.extra_proposals.push_back(remove); |
| 315 | } |
| 316 | |
| 317 | // Inject PSKs |
| 318 | for (const auto& [id, secret] : psks) { |
| 319 | initial_state.add_external_psk(id, secret); |
| 320 | auto psk = initial_state.pre_shared_key_proposal(id); |
| 321 | opts.extra_proposals.push_back(psk); |
| 322 | } |
| 323 | |
| 324 | // Use the preliminary state to create a commit and advance to a real state |
| 325 | auto params = ExternalCommitParams{ key_package, force_init_secret }; |
| 326 | auto [commit_msg, welcome, state] = |
| 327 | initial_state.commit(leaf_secret, opts, msg_opts, params); |
| 328 | silence_unused(welcome); |
| 329 | return { commit_msg, state }; |
| 330 | } |
| 331 | |
| 332 | MLSMessage |
| 333 | State::new_member_add(const bytes& group_id, |
nothing calls this directly
no test coverage detected