libsignal_protocol/
error.rs1use std::fmt::{Display, Formatter};
7use std::panic::UnwindSafe;
8
9use displaydoc::Display;
10use libsignal_core::curve::{CurveError, KeyType};
11use thiserror::Error;
12use uuid::Uuid;
13
14use crate::kem;
15
16pub type Result<T> = std::result::Result<T, SignalProtocolError>;
17
18#[derive(Debug, Display, Error)]
19pub enum SignalProtocolError {
20 InvalidArgument(String),
22 InvalidState(&'static str, String),
24
25 InvalidProtobufEncoding,
27
28 CiphertextMessageTooShort(usize),
30 LegacyCiphertextVersion(u8),
32 UnrecognizedCiphertextVersion(u8),
34 UnrecognizedMessageVersion(u32),
36
37 NoKeyTypeIdentifier,
39 BadKeyType(u8),
41 BadKeyLength(KeyType, usize),
43
44 InvalidKeyAgreement,
46
47 SignatureValidationFailed,
49
50 UntrustedIdentity(crate::ProtocolAddress),
52
53 InvalidPreKeyId,
55 InvalidSignedPreKeyId,
57 InvalidKyberPreKeyId,
59
60 InvalidMacKeyLength(usize),
62
63 NoSenderKeyState { distribution_id: Uuid },
65
66 InvalidProtocolAddress { name: String, device_id: u32 },
68 SessionNotFound(SessionNotFound),
70 InvalidSessionStructure(&'static str),
72 InvalidSenderKeySession { distribution_id: Uuid },
74 InvalidRegistrationId(crate::ProtocolAddress, u32),
76
77 DuplicatedMessage(u32, u32),
79 InvalidMessage(crate::CiphertextMessageType, String),
81
82 FfiBindingError(String),
84 ApplicationCallbackError(
86 &'static str,
87 #[source] Box<dyn std::error::Error + Send + Sync + UnwindSafe + 'static>,
88 ),
89
90 InvalidSealedSenderMessage(String),
92 UnknownSealedSenderVersion(u8),
94 SealedSenderSelfSend,
96 UnknownSealedSenderServerCertificateId(u32),
98
99 BadKEMKeyType(u8),
101 WrongKEMKeyType(u8, u8),
103 BadKEMKeyLength(kem::KeyType, usize),
105 BadKEMCiphertextLength(kem::KeyType, usize),
107}
108
109#[derive(Debug)]
110pub struct SessionNotFound {
111 pub address: Option<crate::ProtocolAddress>,
112 pub op: &'static str,
113}
114
115impl SessionNotFound {
116 pub const fn without_address(op: &'static str) -> Self {
117 Self { address: None, op }
118 }
119
120 pub const fn new(address: crate::ProtocolAddress, op: &'static str) -> Self {
121 Self {
122 address: Some(address),
123 op,
124 }
125 }
126}
127
128impl Display for SessionNotFound {
129 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
130 write!(f, "session")?;
131 if let Some(address) = &self.address {
132 write!(f, " with {address}")?;
133 }
134 write!(f, " not found: {}", self.op)
135 }
136}
137
138impl SignalProtocolError {
139 #[inline]
141 pub fn for_application_callback<E: std::error::Error + Send + Sync + UnwindSafe + 'static>(
142 method: &'static str,
143 ) -> impl FnOnce(E) -> Self {
144 move |error| Self::ApplicationCallbackError(method, Box::new(error))
145 }
146}
147
148impl From<CurveError> for SignalProtocolError {
149 fn from(e: CurveError) -> Self {
150 match e {
151 CurveError::NoKeyTypeIdentifier => Self::NoKeyTypeIdentifier,
152 CurveError::BadKeyType(raw) => Self::BadKeyType(raw),
153 CurveError::BadKeyLength(key_type, len) => Self::BadKeyLength(key_type, len),
154 CurveError::InvalidKeyAgreement => Self::InvalidKeyAgreement,
155 }
156 }
157}