1use thiserror::Error;
6
7pub use super::mls_group::errors::*;
8use super::public_group::errors::CreationFromExternalError;
9use crate::{
10 ciphersuite::signable::SignatureError,
11 error::LibraryError,
12 extensions::errors::{ExtensionError, InvalidExtensionError},
13 framing::errors::MessageDecryptionError,
14 group::commit_builder::external_commits::ExternalCommitBuilderError,
15 key_packages::errors::{KeyPackageExtensionSupportError, KeyPackageVerifyError},
16 messages::{group_info::GroupInfoError, GroupSecretsError},
17 schedule::errors::PskError,
18 treesync::errors::*,
19};
20
21#[cfg(doc)]
22use crate::treesync::LeafNodeParameters;
23
24#[derive(Error, Debug, PartialEq, Clone)]
26pub enum WelcomeError<StorageError> {
27 #[error(transparent)]
29 GroupSecrets(#[from] GroupSecretsError),
30 #[error("Private part of `init_key` not found in key store.")]
32 PrivateInitKeyNotFound,
33 #[error(transparent)]
35 LibraryError(#[from] LibraryError),
36 #[error("Ciphersuites in Welcome and key package bundle don't match.")]
38 CiphersuiteMismatch,
39 #[error(transparent)]
41 GroupInfo(#[from] GroupInfoError),
42 #[error("No joiner secret found in the Welcome message.")]
44 JoinerSecretNotFound,
45 #[error("No ratchet tree available to build initial tree after receiving a Welcome message.")]
47 MissingRatchetTree,
48 #[error("The computed confirmation tag does not match the expected one.")]
50 ConfirmationTagMismatch,
51 #[error("The signature on the GroupInfo is not valid.")]
53 InvalidGroupInfoSignature,
54 #[error("We don't support the version of the group we are trying to join.")]
56 UnsupportedMlsVersion,
57 #[error("We don't support all capabilities of the group.")]
59 UnsupportedCapability,
60 #[error("Sender not found in tree.")]
62 UnknownSender,
63 #[error("Not a Welcome message.")]
65 NotAWelcomeMessage,
66 #[error("Malformed Welcome message.")]
68 MalformedWelcomeMessage,
69 #[error("Could not decrypt the Welcome message.")]
71 UnableToDecrypt,
72 #[error("Unsupported extensions found in the KeyPackage of another member.")]
74 UnsupportedExtensions,
75 #[error(transparent)]
77 Psk(#[from] PskError),
78 #[error("No matching encryption key was found in the key store.")]
80 NoMatchingEncryptionKey,
81 #[error("No matching key package was found in the key store.")]
83 NoMatchingKeyPackage,
84 #[error(transparent)]
86 PublicTreeError(#[from] PublicTreeError),
87 #[error(transparent)]
90 PublicGroupError(#[from] CreationFromExternalError<StorageError>),
91 #[error(transparent)]
93 LeafNodeValidation(#[from] LeafNodeValidationError),
94 #[error("An error occurred when querying storage")]
96 StorageError(StorageError),
97}
98
99#[derive(Error, Debug, PartialEq, Clone)]
101pub enum ExternalCommitError<StorageError> {
102 #[error(transparent)]
104 LibraryError(#[from] LibraryError),
105 #[error("No ratchet tree available to build initial tree.")]
107 MissingRatchetTree,
108 #[error("No external_pub extension available to join group by external commit.")]
110 MissingExternalPub,
111 #[error("We don't support the ciphersuite of the group we are trying to join.")]
113 UnsupportedCiphersuite,
114 #[error("Sender not found in tree.")]
116 UnknownSender,
117 #[error("The signature over the given group info is invalid.")]
119 InvalidGroupInfoSignature,
120 #[error("Error creating external commit.")]
122 CommitError(#[from] CreateCommitError),
123 #[error(transparent)]
126 PublicGroupError(#[from] CreationFromExternalError<StorageError>),
127 #[error("Credential is missing from external commit.")]
129 MissingCredential,
130 #[error("An error occurred when writing group to storage.")]
132 StorageError(StorageError),
133}
134
135impl<StorageError> From<ExternalCommitBuilderError<StorageError>>
136 for ExternalCommitError<StorageError>
137{
138 fn from(error: ExternalCommitBuilderError<StorageError>) -> Self {
139 match error {
140 ExternalCommitBuilderError::LibraryError(library_error) => {
141 ExternalCommitError::LibraryError(library_error)
142 }
143 ExternalCommitBuilderError::MissingRatchetTree => {
144 ExternalCommitError::MissingRatchetTree
145 }
146 ExternalCommitBuilderError::MissingExternalPub => {
147 ExternalCommitError::MissingExternalPub
148 }
149 ExternalCommitBuilderError::UnsupportedCiphersuite => {
150 ExternalCommitError::UnsupportedCiphersuite
151 }
152 ExternalCommitBuilderError::PublicGroupError(creation_from_external_error) => {
153 ExternalCommitError::PublicGroupError(creation_from_external_error)
154 }
155 ExternalCommitBuilderError::StorageError(error) => {
156 ExternalCommitError::StorageError(error)
157 }
158 ExternalCommitBuilderError::InvalidProposal(e) => {
161 log::error!("Error validating proposal in external commit: {e}");
162 ExternalCommitError::LibraryError(LibraryError::custom(
163 "Error creating external commit",
164 ))
165 }
166 }
167 }
168}
169
170impl<StorageError> From<ExternalCommitBuilderFinalizeError<StorageError>>
171 for ExternalCommitError<StorageError>
172{
173 fn from(error: ExternalCommitBuilderFinalizeError<StorageError>) -> Self {
174 match error {
175 ExternalCommitBuilderFinalizeError::LibraryError(library_error) => {
176 ExternalCommitError::LibraryError(library_error)
177 }
178 ExternalCommitBuilderFinalizeError::StorageError(error) => {
179 ExternalCommitError::StorageError(error)
180 }
181 ExternalCommitBuilderFinalizeError::MergeCommitError(e) => {
182 log::error!("Error merging external commit: {e}");
183 ExternalCommitError::LibraryError(LibraryError::custom(
186 "Error merging external commit",
187 ))
188 }
189 }
190 }
191}
192
193#[derive(Error, Debug, PartialEq, Clone)]
195pub enum StageCommitError {
196 #[error(transparent)]
198 LibraryError(#[from] LibraryError),
199 #[error("The epoch of the group context and PublicMessage didn't match.")]
201 EpochMismatch,
202 #[error("The Commit was created by this client.")]
204 OwnCommit,
205 #[error("stage_commit was called with an PublicMessage that is not a Commit.")]
207 WrongPlaintextContentType,
208 #[error("Unable to verify the leaf node signature.")]
210 PathLeafNodeVerificationFailure,
211 #[error("Unable to determine commit path.")]
213 RequiredPathNotFound,
214 #[error("The confirmation Tag is missing.")]
216 ConfirmationTagMissing,
217 #[error("The confirmation tag is invalid.")]
219 ConfirmationTagMismatch,
220 #[error("The committer can't remove themselves.")]
222 AttemptedSelfRemoval,
223 #[error("The proposal queue is missing a proposal for the commit.")]
225 MissingProposal,
226 #[error("Missing own key to apply proposal.")]
228 OwnKeyNotFound,
229 #[error("External Committer used the wrong index.")]
231 InconsistentSenderIndex,
232 #[error("The sender is of type external, which is not valid.")]
234 SenderTypeExternal,
235 #[error("The sender is of type NewMemberProposal, which is not valid.")]
237 SenderTypeNewMemberProposal,
238 #[error("Too many new members: the tree is full.")]
240 TooManyNewMembers,
241 #[error(transparent)]
243 ProposalValidationError(#[from] ProposalValidationError),
244 #[error(transparent)]
246 PskError(#[from] PskError),
247 #[error(transparent)]
249 ExternalCommitValidation(#[from] ExternalCommitValidationError),
250 #[error(transparent)]
252 UpdatePathError(#[from] ApplyUpdatePathError),
253 #[error("Missing decryption key.")]
255 MissingDecryptionKey,
256 #[error(transparent)]
258 VerifiedUpdatePathError(#[from] UpdatePathError),
259 #[error(transparent)]
261 GroupContextExtensionsProposalValidationError(
262 #[from] GroupContextExtensionsProposalValidationError,
263 ),
264 #[error(transparent)]
266 LeafNodeValidation(#[from] LeafNodeValidationError),
267}
268
269#[derive(Error, Debug, PartialEq, Clone)]
271pub enum CreateCommitError {
272 #[error(transparent)]
274 LibraryError(#[from] LibraryError),
275 #[error("Missing own key to apply proposal.")]
277 OwnKeyNotFound,
278 #[error("The Commit tried to remove self from the group. This is not possible.")]
280 CannotRemoveSelf,
281 #[error("The proposal queue is missing a proposal for the commit.")]
283 MissingProposal,
284 #[error("A proposal has the wrong sender type.")]
286 WrongProposalSenderType,
287 #[error(transparent)]
289 PskError(#[from] PskError),
290 #[error(transparent)]
292 ProposalValidationError(#[from] ProposalValidationError),
293 #[error(transparent)]
295 SignatureError(#[from] SignatureError),
296 #[error("Credential is missing from external commit.")]
298 MissingCredential,
299 #[error(transparent)]
301 PublicTreeError(#[from] PublicTreeError),
302 #[error(transparent)]
304 InvalidExtensionError(#[from] InvalidExtensionError),
305 #[error(transparent)]
307 GroupContextExtensionsProposalValidationError(
308 #[from] GroupContextExtensionsProposalValidationError,
309 ),
310 #[error(transparent)]
312 TreeSyncAddLeaf(#[from] TreeSyncAddLeaf),
313 #[error("Invalid LeafNodeParameters. CredentialWithKey can't be set with new signer.")]
315 InvalidLeafNodeParameters,
316 #[error("Invalid external commit.")]
318 InvalidExternalCommit(#[from] ExternalCommitValidationError),
319}
320
321#[derive(Error, Debug, PartialEq, Clone)]
323pub enum CommitBuilderStageError<StorageError> {
324 #[error(transparent)]
326 LibraryError(#[from] LibraryError),
327 #[error("Error interacting with storage.")]
329 KeyStoreError(StorageError),
330}
331
332#[derive(Error, Debug, PartialEq, Clone)]
334pub enum ExternalCommitBuilderFinalizeError<StorageError> {
335 #[error(transparent)]
337 LibraryError(#[from] LibraryError),
338 #[error("Error interacting with storage.")]
340 StorageError(StorageError),
341 #[error("Error merging external commit.")]
343 MergeCommitError(#[from] MergePendingCommitError<StorageError>),
344}
345
346#[derive(Error, Debug, PartialEq, Clone)]
348pub enum ValidationError {
349 #[error(transparent)]
351 LibraryError(#[from] LibraryError),
352 #[error("Message group ID differs from the group's group ID.")]
354 WrongGroupId,
355 #[error("Message epoch differs from the group's epoch.")]
357 WrongEpoch,
358 #[error("The PublicMessage is not a Commit despite the sender begin of type NewMemberCommit.")]
360 NotACommit,
361 #[error("The PublicMessage is not an external Add proposal despite the sender begin of type NewMemberProposal.")]
363 NotAnExternalAddProposal,
364 #[error("The Commit doesn't have a path despite the sender being of type NewMemberCommit.")]
366 NoPath,
367 #[error("The PublicMessage contains an application message but was not encrypted.")]
369 UnencryptedApplicationMessage,
370 #[error("Sender is not part of the group.")]
372 UnknownMember,
373 #[error("Membership tag is missing.")]
375 MissingMembershipTag,
376 #[error("Membership tag is invalid.")]
378 InvalidMembershipTag,
379 #[error("The confirmation tag is missing.")]
381 MissingConfirmationTag,
382 #[error("Wrong wire format.")]
384 WrongWireFormat,
385 #[error("Verifying the signature failed.")]
387 InvalidSignature,
388 #[error("An application message was sent from an external sender.")]
390 NonMemberApplicationMessage,
391 #[error(transparent)]
393 UnableToDecrypt(#[from] MessageDecryptionError),
394 #[error("The message is from an epoch too far in the past.")]
396 NoPastEpochData,
397 #[error("The provided external sender is not authorized to send external proposals")]
399 UnauthorizedExternalSender,
400 #[error("The group doesn't contain external senders extension")]
402 NoExternalSendersExtension,
403 #[error(transparent)]
405 KeyPackageVerifyError(#[from] KeyPackageVerifyError),
406 #[error(transparent)]
408 UpdatePathError(#[from] UpdatePathError),
409 #[error("Invalid LeafNode signature.")]
411 InvalidLeafNodeSignature,
412 #[error("Invalid LeafNode source type")]
414 InvalidLeafNodeSourceType,
415 #[error("Invalid sender type")]
417 InvalidSenderType,
418 #[error("The Commit includes update proposals from the committer.")]
420 CommitterIncludedOwnUpdate,
421 #[error(
423 "The ciphersuite in the KeyPackage of the Add proposal does not match the group context."
424 )]
425 InvalidAddProposalCiphersuite,
426 #[error("Cannot decrypt own messages.")]
428 CannotDecryptOwnMessage,
429 #[error(transparent)]
431 ExternalCommitValidation(#[from] ExternalCommitValidationError),
432}
433
434#[derive(Error, Debug, PartialEq, Clone)]
436pub enum ProposalValidationError {
437 #[error(transparent)]
439 LibraryError(#[from] LibraryError),
440 #[error("The sender could not be matched to a member of the group.")]
442 UnknownMember,
443 #[error("Duplicate signature key in proposals and group.")]
445 DuplicateSignatureKey,
446 #[error("Duplicate encryption key in proposals and group.")]
448 DuplicateEncryptionKey,
449 #[error("Duplicate init key in proposals.")]
451 DuplicateInitKey,
452 #[error("The HPKE init and encryption keys are the same.")]
454 InitEncryptionKeyCollision,
455 #[error("Duplicate remove proposals for the same member.")]
457 DuplicateMemberRemoval,
458 #[error("The remove proposal referenced a non-existing member.")]
460 UnknownMemberRemoval,
461 #[error("Found an update from a non-member.")]
463 UpdateFromNonMember,
464 #[error("The Commit includes update proposals from the committer.")]
466 CommitterIncludedOwnUpdate,
467 #[error("The capabilities of the add proposal are insufficient for this group.")]
469 InsufficientCapabilities,
470 #[error(
472 "The add proposal's ciphersuite or protocol version do not match the ones in the group context."
473 )]
474 InvalidAddProposalCiphersuiteOrVersion,
475 #[error(transparent)]
477 Psk(#[from] PskError),
478 #[error("The proposal type is not supported by all group members.")]
480 UnsupportedProposalType,
481 #[error(transparent)]
483 LeafNodeValidation(#[from] LeafNodeValidationError),
484 #[error("Found ExternalInit proposal in regular commit")]
486 ExternalInitProposalInRegularCommit,
487}
488
489#[derive(Error, Debug, PartialEq, Clone)]
491pub enum ExternalCommitValidationError {
492 #[error(transparent)]
494 LibraryError(#[from] LibraryError),
495 #[error("No ExternalInit proposal found.")]
497 NoExternalInitProposals,
498 #[error("Multiple ExternalInit proposal found.")]
500 MultipleExternalInitProposals,
501 #[error("Found inline Add or Update proposals.")]
503 InvalidInlineProposals,
504 #[error("Found multiple inline Remove proposals.")]
506 MultipleRemoveProposals,
507 #[error("Remove proposal targets the wrong group member.")]
509 InvalidRemoveProposal,
510 #[error("External Commit has to contain a path.")]
512 NoPath,
513 #[error("Found a referenced proposal in an External Commit.")]
515 ReferencedProposal,
516}
517
518#[derive(Error, Debug, PartialEq, Clone)]
520pub enum CreateAddProposalError {
521 #[error(transparent)]
523 LibraryError(#[from] LibraryError),
524 #[error(transparent)]
526 LeafNodeValidation(#[from] LeafNodeValidationError),
527}
528
529#[derive(Error, Debug, PartialEq, Clone)]
533pub(crate) enum ProposalQueueError {
534 #[error(transparent)]
536 LibraryError(#[from] LibraryError),
537 #[error("Not all proposals in the Commit were found locally.")]
539 ProposalNotFound,
540 #[error("Update proposal from external sender.")]
542 UpdateFromExternalSender,
543 #[error("SelfRemove proposal from a non-Member.")]
545 SelfRemoveFromNonMember,
546}
547
548#[derive(Error, Debug, PartialEq, Clone)]
551pub(crate) enum FromCommittedProposalsError {
552 #[error(transparent)]
554 LibraryError(#[from] LibraryError),
555 #[error("Not all proposals in the Commit were found locally.")]
557 ProposalNotFound,
558 #[error("The sender of a Commit tried to remove themselves.")]
560 SelfRemoval,
561}
562
563#[derive(Error, Debug, PartialEq, Clone)]
565pub enum CreateGroupContextExtProposalError<StorageError> {
566 #[error(transparent)]
568 LibraryError(#[from] LibraryError),
569 #[error(transparent)]
571 KeyPackageExtensionSupport(#[from] KeyPackageExtensionSupportError),
572 #[error(transparent)]
574 Extension(#[from] ExtensionError),
575 #[error(transparent)]
577 LeafNodeValidation(#[from] LeafNodeValidationError),
578 #[error(transparent)]
580 MlsGroupStateError(#[from] MlsGroupStateError),
581 #[error(transparent)]
583 CreateCommitError(#[from] CreateCommitError),
584 #[error(transparent)]
586 CommitBuilderStageError(#[from] CommitBuilderStageError<StorageError>),
587 #[error("Error writing updated group data to storage.")]
589 StorageError(StorageError),
590}
591
592#[derive(Error, Debug, PartialEq, Clone)]
594pub enum MergeCommitError<StorageError> {
595 #[error(transparent)]
597 LibraryError(#[from] LibraryError),
598 #[error("Error writing updated group data to storage.")]
600 StorageError(StorageError),
601}
602
603#[derive(Error, Debug, PartialEq, Clone)]
605pub enum GroupContextExtensionsProposalValidationError {
606 #[error("Commit has more than one GroupContextExtensions proposal.")]
608 TooManyGCEProposals,
609
610 #[error(transparent)]
612 LibraryError(#[from] LibraryError),
613
614 #[error(
616 "The new required capabilties contain extension types that are not supported by all group members."
617 )]
618 ExtensionNotSupportedByAllMembers,
619 #[error("Proposal changes the immutable metadata extension, which is not allowed.")]
621 ChangedImmutableMetadata,
622
623 #[error(
625 "The new required capabilties contain extension types that are not supported by all group members."
626 )]
627 RequiredExtensionNotSupportedByAllMembers,
628
629 #[error(
632 "An extension in the group context extensions is not listed in the required capabilties' extension types."
633 )]
634 ExtensionNotInRequiredCapabilities,
635}