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 error::LibraryError,
16 extensions::errors::{ExtensionError, InvalidExtensionError},
17 framing::errors::MessageDecryptionError,
18 group::commit_builder::external_commits::ExternalCommitBuilderError,
19 key_packages::errors::{KeyPackageExtensionSupportError, KeyPackageVerifyError},
20 messages::{group_info::GroupInfoError, GroupSecretsError},
21 prelude::ExtensionType,
22 schedule::{
23 errors::{KeyScheduleError, PskError},
24 PreSharedKeyId,
25 },
26 treesync::errors::*,
27};
28
29#[cfg(doc)]
30use crate::{group::GroupId, treesync::LeafNodeParameters};
31
32#[derive(Error, Debug, PartialEq, Clone)]
34pub enum WelcomeError<StorageError> {
35 #[error(transparent)]
37 GroupSecrets(#[from] GroupSecretsError),
38 #[error("Private part of `init_key` not found in key store.")]
40 PrivateInitKeyNotFound,
41 #[error(transparent)]
43 LibraryError(#[from] LibraryError),
44 #[error("Ciphersuites in Welcome and key package bundle don't match.")]
46 CiphersuiteMismatch,
47 #[error(transparent)]
49 GroupInfo(#[from] GroupInfoError),
50 #[error("No joiner secret found in the Welcome message.")]
52 JoinerSecretNotFound,
53 #[error("No ratchet tree available to build initial tree after receiving a Welcome message.")]
55 MissingRatchetTree,
56 #[error("The computed confirmation tag does not match the expected one.")]
58 ConfirmationTagMismatch,
59 #[error("The signature on the GroupInfo is not valid.")]
61 InvalidGroupInfoSignature,
62 #[error("We don't support the version of the group we are trying to join.")]
64 UnsupportedMlsVersion,
65 #[error("We don't support all capabilities of the group.")]
67 UnsupportedCapability,
68 #[error("Ciphersuite {0:?} of the group we are trying to join is not supported by the crypto provider.")]
70 UnsupportedCiphersuite(Ciphersuite),
71 #[error("Sender not found in tree.")]
73 UnknownSender,
74 #[error("Not a Welcome message.")]
76 NotAWelcomeMessage,
77 #[error("Malformed Welcome message.")]
79 MalformedWelcomeMessage,
80 #[error("Could not decrypt the Welcome message.")]
82 UnableToDecrypt,
83 #[error("Unsupported extensions found in the GroupContext or KeyPackage of another member.")]
85 UnsupportedExtensions,
86 #[error(transparent)]
88 Psk(#[from] PskError),
89 #[error("No matching encryption key was found in the key store.")]
91 NoMatchingEncryptionKey,
92 #[error("No matching key package was found in the key store.")]
94 NoMatchingKeyPackage,
95 #[error(transparent)]
97 PublicTreeError(#[from] PublicTreeError),
98 #[error(transparent)]
101 PublicGroupError(#[from] CreationFromExternalError<StorageError>),
102 #[error(transparent)]
104 LeafNodeValidation(#[from] LeafNodeValidationError),
105 #[error("An error occurred when querying storage")]
107 StorageError(StorageError),
108 #[error("A group with this [`GroupId`] already exists.")]
110 GroupAlreadyExists,
111 #[cfg(feature = "virtual-clients-draft")]
114 #[error(transparent)]
115 VirtualClientsError(#[from] crate::components::vc_derivation_info::VirtualClientsError),
116 #[cfg(feature = "virtual-clients-draft")]
119 #[error(transparent)]
120 RegisterVcDerivationEpoch(#[from] crate::group::RegisterVcDerivationEpochError<StorageError>),
121 #[error(transparent)]
123 KeySchedule(#[from] KeyScheduleError),
124 #[error("The subgroup's protocol version or ciphersuite does not match the parent group.")]
127 SubgroupParameterMismatch,
128 #[error("The subgroup is not at epoch 1.")]
131 SubgroupEpochInvalid,
132 #[error("A member of the subgroup does not match any member of the parent group.")]
135 SubgroupLeafMismatch,
136 #[error("The subgroup's branch PSK does not reference the provided parent group/epoch.")]
139 SubgroupParentMismatch,
140 #[error("The successor group's parameters do not match the ReInit proposal.")]
143 ReInitParameterMismatch,
144 #[error("The successor group is not at epoch 1.")]
147 ReInitEpochInvalid,
148 #[error("Members of the successor group do not match those of the old group.")]
151 ReInitLeafMismatch,
152 #[error("The group's reinit PSK does not reference the provided predecessor group/epoch.")]
155 ReInitPredecessorMismatch,
156}
157
158#[derive(Error, Debug, PartialEq, Clone)]
160pub enum ExternalCommitError<StorageError> {
161 #[error(transparent)]
163 LibraryError(#[from] LibraryError),
164 #[error("No ratchet tree available to build initial tree.")]
166 MissingRatchetTree,
167 #[error("No external_pub extension available to join group by external commit.")]
169 MissingExternalPub,
170 #[error("Ciphersuite {0:?} of the group we are trying to join is not supported by the crypto provider.")]
172 UnsupportedCiphersuite(Ciphersuite),
173 #[error("Sender not found in tree.")]
175 UnknownSender,
176 #[error("The signature over the given group info is invalid.")]
178 InvalidGroupInfoSignature,
179 #[error("Error creating external commit.")]
181 CommitError(#[from] CreateCommitError),
182 #[error(transparent)]
185 PublicGroupError(#[from] CreationFromExternalError<StorageError>),
186 #[error("Credential is missing from external commit.")]
188 MissingCredential,
189 #[error("An error occurred when writing group to storage.")]
191 StorageError(StorageError),
192}
193
194impl<StorageError> From<ExternalCommitBuilderError<StorageError>>
195 for ExternalCommitError<StorageError>
196{
197 fn from(error: ExternalCommitBuilderError<StorageError>) -> Self {
198 match error {
199 ExternalCommitBuilderError::LibraryError(library_error) => {
200 ExternalCommitError::LibraryError(library_error)
201 }
202 ExternalCommitBuilderError::MissingRatchetTree => {
203 ExternalCommitError::MissingRatchetTree
204 }
205 ExternalCommitBuilderError::MissingExternalPub => {
206 ExternalCommitError::MissingExternalPub
207 }
208 ExternalCommitBuilderError::UnsupportedCiphersuite(ciphersuite) => {
209 ExternalCommitError::UnsupportedCiphersuite(ciphersuite)
210 }
211 ExternalCommitBuilderError::PublicGroupError(creation_from_external_error) => {
212 ExternalCommitError::PublicGroupError(creation_from_external_error)
213 }
214 ExternalCommitBuilderError::StorageError(error) => {
215 ExternalCommitError::StorageError(error)
216 }
217 ExternalCommitBuilderError::InvalidProposal(e) => {
220 log::error!("Error validating proposal in external commit: {e}");
221 ExternalCommitError::LibraryError(LibraryError::custom(
222 "Error creating external commit",
223 ))
224 }
225 }
226 }
227}
228
229#[cfg(feature = "virtual-clients-draft")]
235#[derive(Error, Debug)]
236pub enum VcExternalCommitJoinError<StorageError> {
237 #[error(transparent)]
239 LibraryError(#[from] LibraryError),
240 #[error("No ratchet tree available to build the prior-epoch public group.")]
242 MissingRatchetTree,
243 #[error(transparent)]
245 PublicGroupError(#[from] CreationFromExternalError<StorageError>),
246 #[error(transparent)]
248 ProcessMessageError(#[from] ProcessMessageError<StorageError>),
249 #[error(transparent)]
251 StageCommitError(#[from] StageCommitError),
252 #[error(transparent)]
254 MergeCommitError(#[from] MergeCommitError<StorageError>),
255 #[error("The message is not an external commit.")]
258 NotAnExternalCommit,
259 #[error("The external commit carries no virtual-clients derivation info.")]
262 MissingDerivationInfo,
263 #[error("The external commit references a different derivation epoch.")]
266 EpochIdMismatch,
267 #[error(transparent)]
269 VirtualClientsError(#[from] crate::components::vc_derivation_info::VirtualClientsError),
270 #[error("An error occurred when writing the group to storage.")]
272 StorageError(StorageError),
273}
274
275#[cfg(feature = "virtual-clients-draft")]
281#[derive(Error, Debug)]
282pub enum VcGroupCreationJoinError<StorageError> {
283 #[error(transparent)]
285 LibraryError(#[from] LibraryError),
286 #[error("No ratchet tree available to build the created group's public tree.")]
288 MissingRatchetTree,
289 #[error(transparent)]
292 PublicGroupError(#[from] CreationFromExternalError<StorageError>),
293 #[error("The ratchet tree does not consist of exactly the creator's leaf.")]
295 NotASingleLeafTree,
296 #[error("The creator leaf carries no virtual-clients derivation info.")]
298 MissingDerivationInfo,
299 #[error("The creator leaf references a different derivation epoch.")]
302 EpochIdMismatch,
303 #[error("The creator leaf is not key_package-sourced.")]
306 CreatorLeafNotKeyPackageSourced,
307 #[error("The derived leaf key material does not match the creator leaf.")]
310 LeafKeyMismatch,
311 #[error("The GroupInfo could not be verified against the reconstructed epoch state.")]
314 ConfirmationTagMismatch,
315 #[error(transparent)]
317 VirtualClientsError(#[from] crate::components::vc_derivation_info::VirtualClientsError),
318 #[error("An error occurred when writing the group to storage.")]
320 StorageError(StorageError),
321}
322
323impl<StorageError> From<ExternalCommitBuilderFinalizeError<StorageError>>
324 for ExternalCommitError<StorageError>
325{
326 fn from(error: ExternalCommitBuilderFinalizeError<StorageError>) -> Self {
327 match error {
328 ExternalCommitBuilderFinalizeError::LibraryError(library_error) => {
329 ExternalCommitError::LibraryError(library_error)
330 }
331 ExternalCommitBuilderFinalizeError::StorageError(error) => {
332 ExternalCommitError::StorageError(error)
333 }
334 ExternalCommitBuilderFinalizeError::MergeCommitError(e) => {
335 log::error!("Error merging external commit: {e}");
336 ExternalCommitError::LibraryError(LibraryError::custom(
339 "Error merging external commit",
340 ))
341 }
342 }
343 }
344}
345
346#[derive(Error, Debug, PartialEq, Clone)]
348pub enum StageCommitError {
349 #[cfg(feature = "virtual-clients-draft")]
351 #[error(transparent)]
352 VirtualClientsError(#[from] crate::components::vc_derivation_info::VirtualClientsError),
353 #[cfg(feature = "virtual-clients-draft")]
358 #[error("The commit's virtual-clients Safe AAD item did not parse: {0}")]
359 MalformedVcCommitData(String),
360 #[error(transparent)]
362 LibraryError(#[from] LibraryError),
363 #[error("The epoch of the group context and PublicMessage didn't match.")]
365 EpochMismatch,
366 #[error("The Commit was created by this client but does not match the pending commit.")]
368 OwnCommitMismatch,
369 #[error("stage_commit was called with an PublicMessage that is not a Commit.")]
371 WrongPlaintextContentType,
372 #[error("Unable to verify the leaf node signature.")]
374 PathLeafNodeVerificationFailure,
375 #[error("Unable to determine commit path.")]
377 RequiredPathNotFound,
378 #[error("The confirmation Tag is missing.")]
380 ConfirmationTagMissing,
381 #[error("The confirmation tag is invalid.")]
383 ConfirmationTagMismatch,
384 #[error("The committer can't remove themselves.")]
386 AttemptedSelfRemoval,
387 #[error("The proposal queue is missing a proposal for the commit.")]
389 MissingProposal,
390 #[error("Missing own key to apply proposal.")]
392 OwnKeyNotFound,
393 #[error("External Committer used the wrong index.")]
395 InconsistentSenderIndex,
396 #[error("The sender is of type external, which is not valid.")]
398 SenderTypeExternal,
399 #[error("The sender is of type NewMemberProposal, which is not valid.")]
401 SenderTypeNewMemberProposal,
402 #[error("Too many new members: the tree is full.")]
404 TooManyNewMembers,
405 #[error(transparent)]
407 ProposalValidationError(#[from] ProposalValidationError),
408 #[error(transparent)]
410 PskError(#[from] PskError),
411 #[error(transparent)]
413 ExternalCommitValidation(#[from] ExternalCommitValidationError),
414 #[error(transparent)]
416 UpdatePathError(#[from] ApplyUpdatePathError),
417 #[error("Missing decryption key.")]
419 MissingDecryptionKey,
420 #[error(transparent)]
422 VerifiedUpdatePathError(#[from] UpdatePathError),
423 #[error(transparent)]
425 GroupContextExtensionsProposalValidationError(
426 #[from] GroupContextExtensionsProposalValidationError,
427 ),
428 #[cfg(feature = "extensions-draft")]
429 #[error(transparent)]
431 AppDataUpdateValidationError(#[from] AppDataUpdateValidationError),
432 #[error(transparent)]
434 LeafNodeValidation(#[from] LeafNodeValidationError),
435 #[cfg(feature = "extensions-draft")]
437 #[error(transparent)]
438 ApplyAppDataUpdateError(#[from] ApplyAppDataUpdateError),
439 #[error("Duplicate PSK proposal with PSK ID {0:?}.")]
441 DuplicatePskId(PreSharedKeyId),
442}
443
444#[derive(Error, Debug, PartialEq, Clone)]
446pub enum CreateCommitError {
447 #[error(transparent)]
449 LibraryError(#[from] LibraryError),
450 #[cfg(feature = "virtual-clients-draft")]
452 #[error(transparent)]
453 VirtualClientsError(#[from] crate::components::vc_derivation_info::VirtualClientsError),
454 #[cfg(feature = "virtual-clients-draft")]
457 #[error(transparent)]
458 VcCommitData(#[from] crate::components::vc_commit_data::VcCommitDataError),
459 #[cfg(feature = "virtual-clients-draft")]
462 #[error("A new derivation epoch requires the group to use Safe AAD framing.")]
463 NewDerivationEpochWithoutSafeAad,
464 #[cfg(feature = "virtual-clients-draft")]
468 #[error("A new derivation epoch can only be requested in an emulation group.")]
469 NewDerivationEpochOutsideEmulationGroup,
470 #[error("Missing own key to apply proposal.")]
472 OwnKeyNotFound,
473 #[error("The Commit tried to remove self from the group. This is not possible.")]
475 CannotRemoveSelf,
476 #[error("The proposal queue is missing a proposal for the commit.")]
478 MissingProposal,
479 #[error("A proposal has the wrong sender type.")]
481 WrongProposalSenderType,
482 #[error(transparent)]
484 PskError(#[from] PskError),
485 #[error(transparent)]
487 ProposalValidationError(#[from] ProposalValidationError),
488 #[error(transparent)]
490 SignatureError(#[from] SignatureError),
491 #[error("Credential is missing from external commit.")]
493 MissingCredential,
494 #[error(transparent)]
496 PublicTreeError(#[from] PublicTreeError),
497 #[error(transparent)]
499 InvalidExtensionError(#[from] InvalidExtensionError),
500 #[cfg(feature = "extensions-draft")]
501 #[error(transparent)]
503 AppDataUpdateValidationError(#[from] AppDataUpdateValidationError),
504 #[error(transparent)]
506 GroupContextExtensionsProposalValidationError(
507 #[from] GroupContextExtensionsProposalValidationError,
508 ),
509 #[error(transparent)]
511 ApplyOwnUpdatePath(#[from] ApplyOwnUpdatePathError),
512 #[error("Invalid LeafNodeParameters. CredentialWithKey can't be set with new signer.")]
514 InvalidLeafNodeParameters,
515 #[error("The new signer's signature scheme does not match the group's ciphersuite.")]
517 InvalidSignerCiphersuite,
518 #[error("A new signer cannot be used with an external commit. The credential and signer are the ones passed to the external commit builder.")]
520 ExternalCommitWithNewSigner,
521 #[error("The credential in the LeafNodeParameters differs from the one passed to the external commit builder.")]
523 ExternalCommitCredentialMismatch,
524 #[error("Invalid external commit.")]
526 InvalidExternalCommit(#[from] ExternalCommitValidationError),
527 #[cfg(feature = "extensions-draft")]
529 #[error(transparent)]
530 ApplyAppDataUpdateError(#[from] ApplyAppDataUpdateError),
531 #[error(transparent)]
533 LeafNodeValidation(#[from] LeafNodeValidationError),
534}
535
536#[derive(Error, Debug, PartialEq, Clone)]
538pub enum CommitBuilderStageError<StorageError> {
539 #[error(transparent)]
541 LibraryError(#[from] LibraryError),
542 #[error("Error interacting with storage.")]
544 KeyStoreError(StorageError),
545}
546
547#[derive(Error, Debug, PartialEq, Clone)]
549pub enum ExternalCommitBuilderFinalizeError<StorageError> {
550 #[error(transparent)]
552 LibraryError(#[from] LibraryError),
553 #[error("Error interacting with storage.")]
555 StorageError(StorageError),
556 #[error("Error merging external commit.")]
558 MergeCommitError(#[from] MergePendingCommitError<StorageError>),
559}
560
561#[derive(Error, Debug, PartialEq, Clone)]
563pub enum ValidationError {
564 #[error(transparent)]
566 LibraryError(#[from] LibraryError),
567 #[error("Message group ID differs from the group's group ID.")]
569 WrongGroupId,
570 #[error("Message epoch differs from the group's epoch.")]
572 WrongEpoch,
573 #[error("The PublicMessage is not a Commit despite the sender begin of type NewMemberCommit.")]
575 NotACommit,
576 #[error("The PublicMessage is not an external Add proposal despite the sender begin of type NewMemberProposal.")]
578 NotAnExternalAddProposal,
579 #[error("The Commit doesn't have a path despite the sender being of type NewMemberCommit.")]
581 NoPath,
582 #[error("The PublicMessage contains an application message but was not encrypted.")]
584 UnencryptedApplicationMessage,
585 #[error("Sender is not part of the group.")]
587 UnknownMember,
588 #[error("Membership tag is missing.")]
590 MissingMembershipTag,
591 #[error("Membership tag is invalid.")]
593 InvalidMembershipTag,
594 #[error("The confirmation tag is missing.")]
596 MissingConfirmationTag,
597 #[error("Wrong wire format.")]
599 WrongWireFormat,
600 #[error("Verifying the signature failed.")]
602 InvalidSignature,
603 #[error("An application message was sent from an external sender.")]
605 NonMemberApplicationMessage,
606 #[error(transparent)]
608 UnableToDecrypt(#[from] MessageDecryptionError),
609 #[error("The message is from an epoch too far in the past.")]
611 NoPastEpochData,
612 #[error("The provided external sender is not authorized to send external proposals")]
614 UnauthorizedExternalSender,
615 #[error("The group doesn't contain external senders extension")]
617 NoExternalSendersExtension,
618 #[error(transparent)]
620 KeyPackageVerifyError(#[from] KeyPackageVerifyError),
621 #[error(transparent)]
623 UpdatePathError(#[from] UpdatePathError),
624 #[error("Invalid LeafNode signature.")]
626 InvalidLeafNodeSignature,
627 #[error("Invalid LeafNode source type")]
629 InvalidLeafNodeSourceType,
630 #[error("Invalid sender type")]
632 InvalidSenderType,
633 #[error("The Commit includes update proposals from the committer.")]
635 CommitterIncludedOwnUpdate,
636 #[error(
638 "The ciphersuite in the KeyPackage of the Add proposal does not match the group context."
639 )]
640 InvalidAddProposalCiphersuite,
641 #[error(transparent)]
643 ExternalCommitValidation(#[from] ExternalCommitValidationError),
644 #[error("Invalid extension")]
646 InvalidExtension(#[from] InvalidExtensionError),
647}
648
649#[derive(Error, Debug, PartialEq, Clone)]
651pub enum ProposalValidationError {
652 #[error(transparent)]
654 LibraryError(#[from] LibraryError),
655 #[error("The sender could not be matched to a member of the group.")]
657 UnknownMember,
658 #[error("Duplicate signature key in proposals and group.")]
660 DuplicateSignatureKey,
661 #[error("Duplicate encryption key in proposals and group.")]
663 DuplicateEncryptionKey,
664 #[error("Duplicate init key in proposals.")]
666 DuplicateInitKey,
667 #[error("The HPKE init and encryption keys are the same.")]
669 InitEncryptionKeyCollision,
670 #[error("Duplicate remove proposals for the same member.")]
672 DuplicateMemberRemoval,
673 #[error("The remove proposal referenced a non-existing member.")]
675 UnknownMemberRemoval,
676 #[error("Found an update from a non-member.")]
678 UpdateFromNonMember,
679 #[error("The Commit includes update proposals from the committer.")]
681 CommitterIncludedOwnUpdate,
682 #[error("The capabilities of the add proposal are insufficient for this group.")]
684 InsufficientCapabilities,
685 #[error(
687 "The add proposal's ciphersuite or protocol version do not match the ones in the group context."
688 )]
689 InvalidAddProposalCiphersuiteOrVersion,
690 #[error(transparent)]
692 Psk(#[from] PskError),
693 #[error("The proposal type is not supported by all group members.")]
695 UnsupportedProposalType,
696 #[error(transparent)]
698 LeafNodeValidation(#[from] LeafNodeValidationError),
699 #[error("Found ExternalInit proposal in regular commit")]
701 ExternalInitProposalInRegularCommit,
702 #[error("Found a ReInit proposal alongside other proposals in a commit")]
705 ReInitProposalNotAlone,
706 #[error("ReInit proposal downgrades the protocol version")]
709 ReInitDowngrade,
710 #[error("ReInit proposal contains an unsupported protocol version")]
712 ReInitUnsupportedVersion,
713}
714
715#[derive(Error, Debug, PartialEq, Clone)]
717pub enum ExternalCommitValidationError {
718 #[error(transparent)]
720 LibraryError(#[from] LibraryError),
721 #[error("No ExternalInit proposal found.")]
723 NoExternalInitProposals,
724 #[error("Multiple ExternalInit proposal found.")]
726 MultipleExternalInitProposals,
727 #[error("Found inline Add or Update proposals.")]
729 InvalidInlineProposals,
730 #[error("Found multiple inline Remove proposals.")]
732 MultipleRemoveProposals,
733 #[error("Remove proposal targets the wrong group member.")]
735 InvalidRemoveProposal,
736 #[error("External Commit has to contain a path.")]
738 NoPath,
739 #[error("Found a referenced proposal in an External Commit.")]
741 ReferencedProposal,
742 #[error("External committer's leaf node does not support all group context extensions.")]
744 UnsupportedGroupContextExtensions,
745}
746
747#[derive(Error, Debug, PartialEq, Clone)]
749pub enum CreateAddProposalError {
750 #[error(transparent)]
752 LibraryError(#[from] LibraryError),
753 #[error(transparent)]
755 LeafNodeValidation(#[from] LeafNodeValidationError),
756}
757
758#[derive(Error, Debug, PartialEq, Clone)]
762pub(crate) enum ProposalQueueError {
763 #[error(transparent)]
765 LibraryError(#[from] LibraryError),
766 #[error("Not all proposals in the Commit were found locally.")]
768 ProposalNotFound,
769 #[error("Update proposal from external sender.")]
771 UpdateFromExternalSender,
772 #[error("SelfRemove proposal from a non-Member.")]
774 SelfRemoveFromNonMember,
775}
776
777#[derive(Error, Debug, PartialEq, Clone)]
780pub(crate) enum FromCommittedProposalsError {
781 #[error(transparent)]
783 LibraryError(#[from] LibraryError),
784 #[error("Not all proposals in the Commit were found locally.")]
786 ProposalNotFound,
787 #[error("The sender of a Commit tried to remove themselves.")]
789 SelfRemoval,
790 #[error("Commit contains two PSK proposals the PSK ID {0:?}.")]
792 DuplicatePskId(PreSharedKeyId),
793}
794
795#[derive(Error, Debug, PartialEq, Clone)]
797pub enum CreateGroupContextExtProposalError<StorageError> {
798 #[error(transparent)]
800 LibraryError(#[from] LibraryError),
801 #[error(transparent)]
803 KeyPackageExtensionSupport(#[from] KeyPackageExtensionSupportError),
804 #[error(transparent)]
806 Extension(#[from] ExtensionError),
807 #[error(transparent)]
809 LeafNodeValidation(#[from] LeafNodeValidationError),
810 #[error(transparent)]
812 MlsGroupStateError(#[from] MlsGroupStateError),
813 #[error(transparent)]
815 CreateCommitError(#[from] CreateCommitError),
816 #[error(transparent)]
818 CommitBuilderStageError(#[from] CommitBuilderStageError<StorageError>),
819 #[error("Error writing updated group data to storage.")]
821 StorageError(StorageError),
822 #[error(transparent)]
824 InvalidExtensionError(#[from] InvalidExtensionError),
825}
826
827#[derive(Error, Debug, PartialEq, Clone)]
829pub enum MergeCommitError<StorageError> {
830 #[error(transparent)]
832 LibraryError(#[from] LibraryError),
833 #[error("Error writing updated group data to storage.")]
835 StorageError(StorageError),
836 #[cfg(feature = "virtual-clients-draft")]
839 #[error(transparent)]
840 RegisterVcDerivationEpoch(#[from] crate::group::RegisterVcDerivationEpochError<StorageError>),
841}
842
843#[cfg(feature = "extensions-draft")]
844#[derive(Error, Debug, PartialEq, Clone)]
846pub enum AppDataUpdateValidationError {
847 #[error("AppDataUpdate proposals occur before GroupContextExtensions proposals.")]
851 IncorrectOrder,
852 #[error("Attempted to update the AppDataDictionary in the GroupContextExtensions proposal directly.")]
856 CannotUpdateDictionaryDirectly,
857 #[error("More than one AppDataUpdate proposal per ComponentId had a Remove operation.")]
861 MoreThanOneRemovePerComponentId,
862 #[error("Proposals for a ComponentId had both Remove and Update operations.")]
866 CombinedRemoveAndUpdateOperations,
867 #[error("Proposals for a ComponentId had a Remove for a nonexistent component.")]
871 CannotRemoveNonexistentComponent,
872}
873
874#[derive(Error, Debug, PartialEq, Clone)]
876pub enum GroupContextExtensionsProposalValidationError {
877 #[error("Commit has more than one GroupContextExtensions proposal.")]
879 TooManyGCEProposals,
880
881 #[error(transparent)]
883 LibraryError(#[from] LibraryError),
884
885 #[error(
887 "The new required capabilties contain extension types that are not supported by all group members."
888 )]
889 ExtensionNotSupportedByAllMembers,
890 #[error("Proposal changes the immutable metadata extension, which is not allowed.")]
892 ChangedImmutableMetadata,
893
894 #[error(
896 "The new required capabilties contain extension types that are not supported by all group members."
897 )]
898 RequiredExtensionNotSupportedByAllMembers,
899
900 #[error(
903 "An extension in the group context extensions is not listed in the required capabilties' extension types."
904 )]
905 ExtensionNotInRequiredCapabilities,
906
907 #[error("Expected valid `Extension` for `GroupContextExtension`, got `{wrong:?}`")]
909 InvalidExtensionTypeError {
910 wrong: ExtensionType,
912 },
913}