wacore_libsignal/protocol/
error.rs1use std::panic::UnwindSafe;
7
8use crate::{
9 core::{
10 ProtocolAddress,
11 curve::{CurveError, KeyType},
12 },
13 crypto::CryptoProviderError,
14 protocol::CiphertextMessageType,
15};
16use thiserror::Error;
17
18pub type Result<T> = std::result::Result<T, SignalProtocolError>;
19
20#[derive(Debug, Error)]
21pub enum SignalProtocolError {
22 #[error("invalid argument: {0}")]
23 InvalidArgument(String),
24 #[error("invalid state for call to {0} to succeed: {1}")]
25 InvalidState(&'static str, String),
26
27 #[error("backend store error in {0}")]
28 BackendError(
29 &'static str,
30 #[source] Box<dyn std::error::Error + Send + Sync>,
31 ),
32
33 #[error("protobuf encoding was invalid")]
34 InvalidProtobufEncoding,
35
36 #[error("ciphertext serialized bytes were too short <{0}>")]
37 CiphertextMessageTooShort(usize),
38 #[error("ciphertext version was too old <{0}>")]
39 LegacyCiphertextVersion(u8),
40 #[error("ciphertext version was unrecognized <{0}>")]
41 UnrecognizedCiphertextVersion(u8),
42 #[error("unrecognized message version <{0}>")]
43 UnrecognizedMessageVersion(u32),
44
45 #[error("fingerprint version number mismatch them {0} us {1}")]
46 FingerprintVersionMismatch(u32, u32),
47 #[error("fingerprint parsing error")]
48 FingerprintParsingError,
49
50 #[error("no key type identifier")]
51 NoKeyTypeIdentifier,
52 #[error("bad key type <{0:#04x}>")]
53 BadKeyType(u8),
54 #[error("bad key length <{1}> for key with type <{0}>")]
55 BadKeyLength(KeyType, usize),
56
57 #[error("invalid signature detected")]
58 SignatureValidationFailed,
59
60 #[error("the active crypto provider failed the key agreement")]
61 KeyAgreementFailed(#[source] CryptoProviderError),
62
63 #[error("untrusted identity for address {0}")]
64 UntrustedIdentity(ProtocolAddress),
65
66 #[error("invalid prekey identifier")]
67 InvalidPreKeyId,
68 #[error("invalid signed prekey identifier")]
69 InvalidSignedPreKeyId,
70
71 #[error("invalid MAC key length <{0}>")]
72 InvalidMacKeyLength(usize),
73
74 #[error("no sender key state: {0}")]
75 NoSenderKeyState(String),
76
77 #[error("session with {0} not found")]
78 SessionNotFound(ProtocolAddress),
79 #[error("invalid session: {0}")]
80 InvalidSessionStructure(&'static str),
81 #[error("invalid sender key session")]
82 InvalidSenderKeySession,
83 #[error("session for {0} has invalid registration ID {1:X}")]
84 InvalidRegistrationId(ProtocolAddress, u32),
85
86 #[error("message with old counter {0} / {1}")]
87 DuplicatedMessage(u32, u32),
88 #[error("invalid {0:?} message: {1}")]
89 InvalidMessage(CiphertextMessageType, &'static str),
90 #[error("MAC verification failed for {0:?} message")]
91 BadMac(CiphertextMessageType),
92
93 #[error("error while invoking an ffi callback: {0}")]
94 FfiBindingError(String),
95 #[error("error in method call '{0}': {1}")]
96 ApplicationCallbackError(
97 &'static str,
98 #[source] Box<dyn std::error::Error + Send + Sync + UnwindSafe + 'static>,
99 ),
100
101 #[error("invalid sealed sender message: {0}")]
102 InvalidSealedSenderMessage(String),
103 #[error("unknown sealed sender message version {0}")]
104 UnknownSealedSenderVersion(u8),
105 #[error("self send of a sealed sender message")]
106 SealedSenderSelfSend,
107}
108
109impl From<CurveError> for SignalProtocolError {
110 fn from(e: CurveError) -> Self {
111 match e {
112 CurveError::NoKeyTypeIdentifier => Self::NoKeyTypeIdentifier,
113 CurveError::BadKeyType(raw) => Self::BadKeyType(raw),
114 CurveError::BadKeyLength(key_type, len) => Self::BadKeyLength(key_type, len),
115 CurveError::AgreementFailed(source) => Self::KeyAgreementFailed(source),
116 }
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[derive(Debug, thiserror::Error)]
125 #[error("synthetic backend failure: {code}")]
126 struct DummyBackendError {
127 code: u32,
128 }
129
130 #[test]
131 fn backend_error_preserves_typed_source_via_downcast() {
132 let dummy = DummyBackendError { code: 42 };
133 let spe = SignalProtocolError::BackendError("test_context", Box::new(dummy));
134 let src = std::error::Error::source(&spe).expect("source preserved");
135 let inner = src
136 .downcast_ref::<DummyBackendError>()
137 .expect("downcasts to DummyBackendError");
138 assert_eq!(inner.code, 42);
139 }
140}