1use openmls_traits::types::Ciphersuite;
6use thiserror::Error;
7
8#[cfg(feature = "extensions-draft")]
9use super::public_group::errors::ApplyAppDataUpdateError;
10
11pub use super::mls_group::errors::*;
12use super::public_group::errors::CreationFromExternalError;
13use crate::{
14 ciphersuite::signable::SignatureError,
15 credentials::Credential,
16 error::LibraryError,
17 extensions::errors::{ExtensionError, InvalidExtensionError},
18 framing::errors::MessageDecryptionError,
19 group::commit_builder::external_commits::ExternalCommitBuilderError,
20 key_packages::errors::{KeyPackageExtensionSupportError, KeyPackageVerifyError},
21 messages::{group_info::GroupInfoError, GroupSecretsError},
22 prelude::ExtensionType,
23 schedule::{
24 errors::{KeyScheduleError, PskError},
25 PreSharedKeyId,
26 },
27 treesync::errors::*,
28};
29
30#[cfg(doc)]
31use crate::{group::GroupId, treesync::LeafNodeParameters};
32
33#[derive(Error, Debug, PartialEq, Clone)]
35pub enum WelcomeError<StorageError> {
36 #[error(transparent)]
38 GroupSecrets(#[from] GroupSecretsError),
39 #[error("Private part of `init_key` not found in key store.")]
41 PrivateInitKeyNotFound,
42 #[error(transparent)]
44 LibraryError(#[from] LibraryError),
45 #[error("Ciphersuites in Welcome and key package bundle don't match.")]
47 CiphersuiteMismatch,
48 #[error(transparent)]
50 GroupInfo(#[from] GroupInfoError),
51 #[error("No joiner secret found in the Welcome message.")]
53 JoinerSecretNotFound,
54 #[error("No ratchet tree available to build initial tree after receiving a Welcome message.")]
56 MissingRatchetTree,
57 #[error("The computed confirmation tag does not match the expected one.")]
59 ConfirmationTagMismatch,
60 #[error("The signature on the GroupInfo is not valid.")]
62 InvalidGroupInfoSignature,
63 #[error("We don't support the version of the group we are trying to join.")]
65 UnsupportedMlsVersion,
66 #[error("We don't support all capabilities of the group.")]
68 UnsupportedCapability,
69 #[error("Ciphersuite {0:?} of the group we are trying to join is not supported by the crypto provider.")]
71 UnsupportedCiphersuite(Ciphersuite),
72 #[error("Sender not found in tree.")]
74 UnknownSender,
75 #[error("Not a Welcome message.")]
77 NotAWelcomeMessage,
78 #[error("Malformed Welcome message.")]
80 MalformedWelcomeMessage,
81 #[error("Could not decrypt the Welcome message.")]
83 UnableToDecrypt,
84 #[error("Unsupported extensions found in the GroupContext or KeyPackage of another member.")]
86 UnsupportedExtensions,
87 #[error(transparent)]
89 Psk(#[from] PskError),
90 #[error("No matching encryption key was found in the key store.")]
92 NoMatchingEncryptionKey,
93 #[error("No matching key package was found in the key store.")]
95 NoMatchingKeyPackage,
96 #[error(transparent)]
98 PublicTreeError(#[from] PublicTreeError),
99 #[error(transparent)]
102 PublicGroupError(#[from] CreationFromExternalError<StorageError>),
103 #[error(transparent)]
105 LeafNodeValidation(#[from] LeafNodeValidationError),
106 #[error("An error occurred when querying storage")]
108 StorageError(StorageError),
109 #[error("A group with this [`GroupId`] already exists.")]
111 GroupAlreadyExists,
112 #[cfg(feature = "virtual-clients-draft")]
115 #[error(transparent)]
116 VirtualClientsError(#[from] crate::components::vc_derivation_info::VirtualClientsError),
117 #[cfg(feature = "virtual-clients-draft")]
120 #[error(transparent)]
121 RegisterVcDerivationEpoch(#[from] crate::group::RegisterVcDerivationEpochError<StorageError>),
122 #[error(transparent)]
124 KeySchedule(#[from] KeyScheduleError),
125 #[error("The subgroup's protocol version or ciphersuite does not match the parent group.")]
128 SubgroupParameterMismatch,
129 #[error("The subgroup is not at epoch 1.")]
132 SubgroupEpochInvalid,
133 #[error("A member of the subgroup does not match any member of the parent group.")]
136 SubgroupLeafMismatch,
137 #[error("The subgroup's branch PSK does not reference the provided parent group/epoch.")]
140 SubgroupParentMismatch,
141 #[error("The successor group's parameters do not match the ReInit proposal.")]
144 ReInitParameterMismatch,
145 #[error("The successor group is not at epoch 1.")]
148 ReInitEpochInvalid,
149 #[error("A member of the successor group does not match any member of the old group.")]
152 ReInitLeafMismatch,
153 #[error("The successor group is missing members {0:?} of the old group.")]
155 ReInitLeavesMissing(Vec<Credential>),
156 #[error("The group's reinit PSK does not reference the provided predecessor group/epoch.")]
159 ReInitPredecessorMismatch,
160}
161
162#[derive(Error, Debug, PartialEq, Clone)]
164pub enum ExternalCommitError<StorageError> {
165 #[error(transparent)]
167 LibraryError(#[from] LibraryError),
168 #[error("No ratchet tree available to build initial tree.")]
170 MissingRatchetTree,
171 #[error("No external_pub extension available to join group by external commit.")]
173 MissingExternalPub,
174 #[error("Ciphersuite {0:?} of the group we are trying to join is not supported by the crypto provider.")]
176 UnsupportedCiphersuite(Ciphersuite),
177 #[error("Sender not found in tree.")]
179 UnknownSender,
180 #[error("The signature over the given group info is invalid.")]
182 InvalidGroupInfoSignature,
183 #[error("Error creating external commit.")]
185 CommitError(#[from] CreateCommitError),
186 #[error(transparent)]
189 PublicGroupError(#[from] CreationFromExternalError<StorageError>),
190 #[error("Credential is missing from external commit.")]
192 MissingCredential,
193 #[error("An error occurred when writing group to storage.")]
195 StorageError(StorageError),
196}
197
198impl<StorageError> From<ExternalCommitBuilderError<StorageError>>
199 for ExternalCommitError<StorageError>
200{
201 fn from(error: ExternalCommitBuilderError<StorageError>) -> Self {
202 match error {
203 ExternalCommitBuilderError::LibraryError(library_error) => {
204 ExternalCommitError::LibraryError(library_error)
205 }
206 ExternalCommitBuilderError::MissingRatchetTree => {
207 ExternalCommitError::MissingRatchetTree
208 }
209 ExternalCommitBuilderError::MissingExternalPub => {
210 ExternalCommitError::MissingExternalPub
211 }
212 ExternalCommitBuilderError::UnsupportedCiphersuite(ciphersuite) => {
213 ExternalCommitError::UnsupportedCiphersuite(ciphersuite)
214 }
215 ExternalCommitBuilderError::PublicGroupError(creation_from_external_error) => {
216 ExternalCommitError::PublicGroupError(creation_from_external_error)
217 }
218 ExternalCommitBuilderError::StorageError(error) => {
219 ExternalCommitError::StorageError(error)
220 }
221 ExternalCommitBuilderError::InvalidProposal(e) => {
224 log::error!("Error validating proposal in external commit: {e}");
225 ExternalCommitError::LibraryError(LibraryError::custom(
226 "Error creating external commit",
227 ))
228 }
229 }
230 }
231}
232
233#[cfg(feature = "virtual-clients-draft")]
239#[derive(Error, Debug)]
240pub enum VcExternalCommitJoinError<StorageError> {
241 #[error(transparent)]
243 LibraryError(#[from] LibraryError),
244 #[error("No ratchet tree available to build the prior-epoch public group.")]
246 MissingRatchetTree,
247 #[error(transparent)]
249 PublicGroupError(#[from] CreationFromExternalError<StorageError>),
250 #[error(transparent)]
252 ProcessMessageError(#[from] ProcessMessageError<StorageError>),
253 #[error(transparent)]
255 StageCommitError(#[from] StageCommitError),
256 #[error(transparent)]
258 MergeCommitError(#[from] MergeCommitError<StorageError>),
259 #[error("The message is not an external commit.")]
262 NotAnExternalCommit,
263 #[error("The external commit carries no virtual-clients derivation info.")]
266 MissingDerivationInfo,
267 #[error("The external commit references a different derivation epoch.")]
270 EpochIdMismatch,
271 #[error(transparent)]
273 VirtualClientsError(#[from] crate::components::vc_derivation_info::VirtualClientsError),
274 #[error("An error occurred when writing the group to storage.")]
276 StorageError(StorageError),
277}
278
279#[cfg(feature = "virtual-clients-draft")]
285#[derive(Error, Debug)]
286pub enum VcGroupCreationJoinError<StorageError> {
287 #[error(transparent)]
289 LibraryError(#[from] LibraryError),
290 #[error("No ratchet tree available to build the created group's public tree.")]
292 MissingRatchetTree,
293 #[error(transparent)]
296 PublicGroupError(#[from] CreationFromExternalError<StorageError>),
297 #[error("The ratchet tree does not consist of exactly the creator's leaf.")]
299 NotASingleLeafTree,
300 #[error("The creator leaf carries no virtual-clients derivation info.")]
302 MissingDerivationInfo,
303 #[error("The creator leaf references a different derivation epoch.")]
306 EpochIdMismatch,
307 #[error("The creator leaf is not key_package-sourced.")]
310 CreatorLeafNotKeyPackageSourced,
311 #[error("The derived leaf key material does not match the creator leaf.")]
314 LeafKeyMismatch,
315 #[error("The GroupInfo could not be verified against the reconstructed epoch state.")]
318 ConfirmationTagMismatch,
319 #[error(transparent)]
321 VirtualClientsError(#[from] crate::components::vc_derivation_info::VirtualClientsError),
322 #[error("An error occurred when writing the group to storage.")]
324 StorageError(StorageError),
325}
326
327impl<StorageError> From<ExternalCommitBuilderFinalizeError<StorageError>>
328 for ExternalCommitError<StorageError>
329{
330 fn from(error: ExternalCommitBuilderFinalizeError<StorageError>) -> Self {
331 match error {
332 ExternalCommitBuilderFinalizeError::LibraryError(library_error) => {
333 ExternalCommitError::LibraryError(library_error)
334 }
335 ExternalCommitBuilderFinalizeError::StorageError(error) => {
336 ExternalCommitError::StorageError(error)
337 }
338 ExternalCommitBuilderFinalizeError::MergeCommitError(e) => {
339 log::error!("Error merging external commit: {e}");
340 ExternalCommitError::LibraryError(LibraryError::custom(
343 "Error merging external commit",
344 ))
345 }
346 }
347 }
348}
349
350#[derive(Error, Debug, PartialEq, Clone)]
352pub enum StageCommitError {
353 #[cfg(feature = "virtual-clients-draft")]
355 #[error(transparent)]
356 VirtualClientsError(#[from] crate::components::vc_derivation_info::VirtualClientsError),
357 #[cfg(feature = "virtual-clients-draft")]
362 #[error("The commit's virtual-clients Safe AAD item did not parse: {0}")]
363 MalformedVcCommitData(String),
364 #[error(transparent)]
366 LibraryError(#[from] LibraryError),
367 #[error("The epoch of the group context and PublicMessage didn't match.")]
369 EpochMismatch,
370 #[error("The Commit was created by this client but does not match the pending commit.")]
372 OwnCommitMismatch,
373 #[error("stage_commit was called with an PublicMessage that is not a Commit.")]
375 WrongPlaintextContentType,
376 #[error("Unable to verify the leaf node signature.")]
378 PathLeafNodeVerificationFailure,
379 #[error("Unable to determine commit path.")]
381 RequiredPathNotFound,
382 #[error("The confirmation Tag is missing.")]
384 ConfirmationTagMissing,
385 #[error("The confirmation tag is invalid.")]
387 ConfirmationTagMismatch,
388 #[error("The committer can't remove themselves.")]
390 AttemptedSelfRemoval,
391 #[error("The proposal queue is missing a proposal for the commit.")]
393 MissingProposal,
394 #[error("Missing own key to apply proposal.")]
396 OwnKeyNotFound,
397 #[error("External Committer used the wrong index.")]
399 InconsistentSenderIndex,
400 #[error("The sender is of type external, which is not valid.")]
402 SenderTypeExternal,
403 #[error("The sender is of type NewMemberProposal, which is not valid.")]
405 SenderTypeNewMemberProposal,
406 #[error("Too many new members: the tree is full.")]
408 TooManyNewMembers,
409 #[error(transparent)]
411 ProposalValidationError(#[from] ProposalValidationError),
412 #[error(transparent)]
414 PskError(#[from] PskError),
415 #[error(transparent)]
417 ExternalCommitValidation(#[from] ExternalCommitValidationError),
418 #[error(transparent)]
420 UpdatePathError(#[from] ApplyUpdatePathError),
421 #[error("Missing decryption key.")]
423 MissingDecryptionKey,
424 #[error(transparent)]
426 VerifiedUpdatePathError(#[from] UpdatePathError),
427 #[error(transparent)]
429 GroupContextExtensionsProposalValidationError(
430 #[from] GroupContextExtensionsProposalValidationError,
431 ),
432 #[cfg(feature = "extensions-draft")]
433 #[error(transparent)]
435 AppDataUpdateValidationError(#[from] AppDataUpdateValidationError),
436 #[error(transparent)]
438 LeafNodeValidation(#[from] LeafNodeValidationError),
439 #[cfg(feature = "extensions-draft")]
441 #[error(transparent)]
442 ApplyAppDataUpdateError(#[from] ApplyAppDataUpdateError),
443 #[error("Duplicate PSK proposal with PSK ID {0:?}.")]
445 DuplicatePskId(PreSharedKeyId),
446}
447
448#[derive(Error, Debug, PartialEq, Clone)]
450pub enum CreateCommitError {
451 #[error(transparent)]
453 LibraryError(#[from] LibraryError),
454 #[cfg(feature = "virtual-clients-draft")]
456 #[error(transparent)]
457 VirtualClientsError(#[from] crate::components::vc_derivation_info::VirtualClientsError),
458 #[cfg(feature = "virtual-clients-draft")]
461 #[error(transparent)]
462 VcCommitData(#[from] crate::components::vc_commit_data::VcCommitDataError),
463 #[cfg(feature = "virtual-clients-draft")]
466 #[error("A new derivation epoch requires the group to use Safe AAD framing.")]
467 NewDerivationEpochWithoutSafeAad,
468 #[cfg(feature = "virtual-clients-draft")]
472 #[error("A new derivation epoch can only be requested in an emulation group.")]
473 NewDerivationEpochOutsideEmulationGroup,
474 #[error("Missing own key to apply proposal.")]
476 OwnKeyNotFound,
477 #[error("The Commit tried to remove self from the group. This is not possible.")]
479 CannotRemoveSelf,
480 #[error("The proposal queue is missing a proposal for the commit.")]
482 MissingProposal,
483 #[error("A proposal has the wrong sender type.")]
485 WrongProposalSenderType,
486 #[error(transparent)]
488 PskError(#[from] PskError),
489 #[error(transparent)]
491 ProposalValidationError(#[from] ProposalValidationError),
492 #[error(transparent)]
494 SignatureError(#[from] SignatureError),
495 #[error("Credential is missing from external commit.")]
497 MissingCredential,
498 #[error(transparent)]
500 PublicTreeError(#[from] PublicTreeError),
501 #[error(transparent)]
503 InvalidExtensionError(#[from] InvalidExtensionError),
504 #[cfg(feature = "extensions-draft")]
505 #[error(transparent)]
507 AppDataUpdateValidationError(#[from] AppDataUpdateValidationError),
508 #[error(transparent)]
510 GroupContextExtensionsProposalValidationError(
511 #[from] GroupContextExtensionsProposalValidationError,
512 ),
513 #[error(transparent)]
515 ApplyOwnUpdatePath(#[from] ApplyOwnUpdatePathError),
516 #[error("Invalid LeafNodeParameters. CredentialWithKey can't be set with new signer.")]
518 InvalidLeafNodeParameters,
519 #[error("The new signer's signature scheme does not match the group's ciphersuite.")]
521 InvalidSignerCiphersuite,
522 #[error("A new signer cannot be used with an external commit. The credential and signer are the ones passed to the external commit builder.")]
524 ExternalCommitWithNewSigner,
525 #[error("The credential in the LeafNodeParameters differs from the one passed to the external commit builder.")]
527 ExternalCommitCredentialMismatch,
528 #[error("Invalid external commit.")]
530 InvalidExternalCommit(#[from] ExternalCommitValidationError),
531 #[cfg(feature = "extensions-draft")]
533 #[error(transparent)]
534 ApplyAppDataUpdateError(#[from] ApplyAppDataUpdateError),
535 #[error(transparent)]
537 LeafNodeValidation(#[from] LeafNodeValidationError),
538}
539
540#[derive(Error, Debug, PartialEq, Clone)]
542pub enum CommitBuilderStageError<StorageError> {
543 #[error(transparent)]
545 LibraryError(#[from] LibraryError),
546 #[error("Error interacting with storage.")]
548 KeyStoreError(StorageError),
549}
550
551#[derive(Error, Debug, PartialEq, Clone)]
553pub enum ExternalCommitBuilderFinalizeError<StorageError> {
554 #[error(transparent)]
556 LibraryError(#[from] LibraryError),
557 #[error("Error interacting with storage.")]
559 StorageError(StorageError),
560 #[error("Error merging external commit.")]
562 MergeCommitError(#[from] MergePendingCommitError<StorageError>),
563}
564
565#[derive(Error, Debug, PartialEq, Clone)]
567pub enum ValidationError {
568 #[error(transparent)]
570 LibraryError(#[from] LibraryError),
571 #[error("Message group ID differs from the group's group ID.")]
573 WrongGroupId,
574 #[error("Message epoch differs from the group's epoch.")]
576 WrongEpoch,
577 #[error("The PublicMessage is not a Commit despite the sender begin of type NewMemberCommit.")]
579 NotACommit,
580 #[error("The PublicMessage is not an external Add proposal despite the sender begin of type NewMemberProposal.")]
582 NotAnExternalAddProposal,
583 #[error("The Commit doesn't have a path despite the sender being of type NewMemberCommit.")]
585 NoPath,
586 #[error("The PublicMessage contains an application message but was not encrypted.")]
588 UnencryptedApplicationMessage,
589 #[error("Sender is not part of the group.")]
591 UnknownMember,
592 #[error("Membership tag is missing.")]
594 MissingMembershipTag,
595 #[error("Membership tag is invalid.")]
597 InvalidMembershipTag,
598 #[error("The confirmation tag is missing.")]
600 MissingConfirmationTag,
601 #[error("Wrong wire format.")]
603 WrongWireFormat,
604 #[error("Verifying the signature failed.")]
606 InvalidSignature,
607 #[error("An application message was sent from an external sender.")]
609 NonMemberApplicationMessage,
610 #[error(transparent)]
612 UnableToDecrypt(#[from] MessageDecryptionError),
613 #[error("The message is from an epoch too far in the past.")]
615 NoPastEpochData,
616 #[error("The provided external sender is not authorized to send external proposals")]
618 UnauthorizedExternalSender,
619 #[error("The group doesn't contain external senders extension")]
621 NoExternalSendersExtension,
622 #[error(transparent)]
624 KeyPackageVerifyError(#[from] KeyPackageVerifyError),
625 #[error(transparent)]
627 UpdatePathError(#[from] UpdatePathError),
628 #[error("Invalid LeafNode signature.")]
630 InvalidLeafNodeSignature,
631 #[error("Invalid LeafNode source type")]
633 InvalidLeafNodeSourceType,
634 #[error("Invalid sender type")]
636 InvalidSenderType,
637 #[error("The Commit includes update proposals from the committer.")]
639 CommitterIncludedOwnUpdate,
640 #[error(
642 "The ciphersuite in the KeyPackage of the Add proposal does not match the group context."
643 )]
644 InvalidAddProposalCiphersuite,
645 #[error(transparent)]
647 ExternalCommitValidation(#[from] ExternalCommitValidationError),
648 #[error("Invalid extension")]
650 InvalidExtension(#[from] InvalidExtensionError),
651}
652
653#[derive(Error, Debug, PartialEq, Clone)]
655pub enum ProposalValidationError {
656 #[error(transparent)]
658 LibraryError(#[from] LibraryError),
659 #[error("The sender could not be matched to a member of the group.")]
661 UnknownMember,
662 #[error("Duplicate signature key in proposals and group.")]
664 DuplicateSignatureKey,
665 #[error("Duplicate encryption key in proposals and group.")]
667 DuplicateEncryptionKey,
668 #[error("Duplicate init key in proposals.")]
670 DuplicateInitKey,
671 #[error("The HPKE init and encryption keys are the same.")]
673 InitEncryptionKeyCollision,
674 #[error("Duplicate remove proposals for the same member.")]
676 DuplicateMemberRemoval,
677 #[error("The remove proposal referenced a non-existing member.")]
679 UnknownMemberRemoval,
680 #[error("Found an update from a non-member.")]
682 UpdateFromNonMember,
683 #[error("The Commit includes update proposals from the committer.")]
685 CommitterIncludedOwnUpdate,
686 #[error("The capabilities of the add proposal are insufficient for this group.")]
688 InsufficientCapabilities,
689 #[error(
691 "The add proposal's ciphersuite or protocol version do not match the ones in the group context."
692 )]
693 InvalidAddProposalCiphersuiteOrVersion,
694 #[error(transparent)]
696 Psk(#[from] PskError),
697 #[error("The proposal type is not supported by all group members.")]
699 UnsupportedProposalType,
700 #[error(transparent)]
702 LeafNodeValidation(#[from] LeafNodeValidationError),
703 #[error("Found ExternalInit proposal in regular commit")]
705 ExternalInitProposalInRegularCommit,
706 #[error("Found a ReInit proposal alongside other proposals in a commit")]
709 ReInitProposalNotAlone,
710 #[error("ReInit proposal downgrades the protocol version")]
713 ReInitDowngrade,
714 #[error("ReInit proposal contains an unsupported protocol version")]
716 ReInitUnsupportedVersion,
717}
718
719#[derive(Error, Debug, PartialEq, Clone)]
721pub enum ExternalCommitValidationError {
722 #[error(transparent)]
724 LibraryError(#[from] LibraryError),
725 #[error("No ExternalInit proposal found.")]
727 NoExternalInitProposals,
728 #[error("Multiple ExternalInit proposal found.")]
730 MultipleExternalInitProposals,
731 #[error("Found inline Add or Update proposals.")]
733 InvalidInlineProposals,
734 #[error("Found multiple inline Remove proposals.")]
736 MultipleRemoveProposals,
737 #[error("Remove proposal targets the wrong group member.")]
739 InvalidRemoveProposal,
740 #[error("External Commit has to contain a path.")]
742 NoPath,
743 #[error("Found a referenced proposal in an External Commit.")]
745 ReferencedProposal,
746 #[error("External committer's leaf node does not support all group context extensions.")]
748 UnsupportedGroupContextExtensions,
749}
750
751#[derive(Error, Debug, PartialEq, Clone)]
753pub enum CreateAddProposalError {
754 #[error(transparent)]
756 LibraryError(#[from] LibraryError),
757 #[error(transparent)]
759 LeafNodeValidation(#[from] LeafNodeValidationError),
760}
761
762#[derive(Error, Debug, PartialEq, Clone)]
766pub(crate) enum ProposalQueueError {
767 #[error(transparent)]
769 LibraryError(#[from] LibraryError),
770 #[error("Not all proposals in the Commit were found locally.")]
772 ProposalNotFound,
773 #[error("Update proposal from external sender.")]
775 UpdateFromExternalSender,
776 #[error("SelfRemove proposal from a non-Member.")]
778 SelfRemoveFromNonMember,
779}
780
781#[derive(Error, Debug, PartialEq, Clone)]
784pub(crate) enum FromCommittedProposalsError {
785 #[error(transparent)]
787 LibraryError(#[from] LibraryError),
788 #[error("Not all proposals in the Commit were found locally.")]
790 ProposalNotFound,
791 #[error("The sender of a Commit tried to remove themselves.")]
793 SelfRemoval,
794 #[error("Commit contains two PSK proposals the PSK ID {0:?}.")]
796 DuplicatePskId(PreSharedKeyId),
797}
798
799#[derive(Error, Debug, PartialEq, Clone)]
801pub enum CreateGroupContextExtProposalError<StorageError> {
802 #[error(transparent)]
804 LibraryError(#[from] LibraryError),
805 #[error(transparent)]
807 KeyPackageExtensionSupport(#[from] KeyPackageExtensionSupportError),
808 #[error(transparent)]
810 Extension(#[from] ExtensionError),
811 #[error(transparent)]
813 LeafNodeValidation(#[from] LeafNodeValidationError),
814 #[error(transparent)]
816 MlsGroupStateError(#[from] MlsGroupStateError),
817 #[error(transparent)]
819 CreateCommitError(#[from] CreateCommitError),
820 #[error(transparent)]
822 CommitBuilderStageError(#[from] CommitBuilderStageError<StorageError>),
823 #[error("Error writing updated group data to storage.")]
825 StorageError(StorageError),
826 #[error(transparent)]
828 InvalidExtensionError(#[from] InvalidExtensionError),
829}
830
831#[derive(Error, Debug, PartialEq, Clone)]
833pub enum MergeCommitError<StorageError> {
834 #[error(transparent)]
836 LibraryError(#[from] LibraryError),
837 #[error("Error writing updated group data to storage.")]
839 StorageError(StorageError),
840 #[cfg(feature = "virtual-clients-draft")]
843 #[error(transparent)]
844 RegisterVcDerivationEpoch(#[from] crate::group::RegisterVcDerivationEpochError<StorageError>),
845}
846
847#[cfg(feature = "extensions-draft")]
848#[derive(Error, Debug, PartialEq, Clone)]
850pub enum AppDataUpdateValidationError {
851 #[error("AppDataUpdate proposals occur before GroupContextExtensions proposals.")]
855 IncorrectOrder,
856 #[error("Attempted to update the AppDataDictionary in the GroupContextExtensions proposal directly.")]
860 CannotUpdateDictionaryDirectly,
861 #[error("More than one AppDataUpdate proposal per ComponentId had a Remove operation.")]
865 MoreThanOneRemovePerComponentId,
866 #[error("Proposals for a ComponentId had both Remove and Update operations.")]
870 CombinedRemoveAndUpdateOperations,
871 #[error("Proposals for a ComponentId had a Remove for a nonexistent component.")]
875 CannotRemoveNonexistentComponent,
876}
877
878#[derive(Error, Debug, PartialEq, Clone)]
880pub enum GroupContextExtensionsProposalValidationError {
881 #[error("Commit has more than one GroupContextExtensions proposal.")]
883 TooManyGCEProposals,
884
885 #[error(transparent)]
887 LibraryError(#[from] LibraryError),
888
889 #[error(
891 "The new required capabilties contain extension types that are not supported by all group members."
892 )]
893 ExtensionNotSupportedByAllMembers,
894 #[error("Proposal changes the immutable metadata extension, which is not allowed.")]
896 ChangedImmutableMetadata,
897
898 #[error(
900 "The new required capabilties contain extension types that are not supported by all group members."
901 )]
902 RequiredExtensionNotSupportedByAllMembers,
903
904 #[error(
907 "An extension in the group context extensions is not listed in the required capabilties' extension types."
908 )]
909 ExtensionNotInRequiredCapabilities,
910
911 #[error("Expected valid `Extension` for `GroupContextExtension`, got `{wrong:?}`")]
913 InvalidExtensionTypeError {
914 wrong: ExtensionType,
916 },
917}