libsignal_service/push_service/
error.rs1use aes::cipher::block_padding;
2use libsignal_core::{curve::CurveError, ServiceId};
3use libsignal_protocol::{
4 FingerprintError, ServiceIdKind, SignalProtocolError,
5};
6use reqwest::StatusCode;
7use serde::Deserialize;
8use zkgroup::{ZkGroupDeserializationFailure, ZkGroupVerificationFailure};
9
10use crate::{
11 cipher::SealedSenderDecryptionError,
12 groups_v2::GroupDecodingError,
13 utils::deserialize_service_id,
14 websocket::registration::{
15 RegistrationLockFailure, RegistrationSessionMetadataResponse,
16 },
17};
18
19use super::{MismatchedDevices, ProofRequired, StaleDevices};
20
21#[derive(Debug, Deserialize)]
22pub struct AccountMismatchedDevices {
23 #[serde(deserialize_with = "deserialize_service_id")]
24 pub uuid: ServiceId,
25 pub devices: MismatchedDevices,
26}
27
28#[derive(Debug, Deserialize)]
29pub struct AccountStaleDevices {
30 #[serde(deserialize_with = "deserialize_service_id")]
31 pub uuid: ServiceId,
32 pub devices: StaleDevices,
33}
34
35#[derive(Debug, Deserialize)]
36#[serde(rename_all = "camelCase")]
37pub struct VerificationDeliveryFailure {
38 #[serde(default)]
39 pub reason: String,
40 pub permanent_failure: bool,
41}
42
43#[derive(thiserror::Error, Debug)]
44pub enum ServiceError {
45 #[error("Service request timed out: {reason}")]
46 Timeout { reason: &'static str },
47
48 #[error("invalid URL: {0}")]
49 InvalidUrl(#[from] url::ParseError),
50
51 #[error("wrong address type: {0}")]
52 InvalidAddressType(ServiceIdKind),
53
54 #[error("invalid phone number")]
55 InvalidPhoneNumber,
56
57 #[error("Error sending request: {reason}")]
58 SendError { reason: String },
59
60 #[error("i/o error")]
61 IO(#[from] std::io::Error),
62
63 #[error("Error decoding JSON: {0}")]
64 JsonDecodeError(#[from] serde_json::Error),
65 #[error("Error decoding protobuf frame: {0}")]
66 ProtobufDecodeError(#[from] prost::DecodeError),
67 #[error("error encoding or decoding bincode: {0}")]
68 BincodeError(#[from] bincode::Error),
69 #[error("error decoding base64 string: {0}")]
70 Base64DecodeError(#[from] base64::DecodeError),
71
72 #[error("Rate limit exceeded: retry after {}", retry_after.map(|a| a.to_string()).unwrap_or_else(|| "unspecified".into()))]
73 RateLimitExceeded {
74 retry_after: Option<chrono::Duration>,
75 },
76 #[error("Authorization failed")]
77 Unauthorized,
78 #[error("Registration lock is set: {0:?}")]
79 Locked(RegistrationLockFailure),
80
81 #[error("Unexpected response: HTTP {status}: {body}")]
82 UnhandledResponseCode { status: StatusCode, body: String },
83
84 #[error("Websocket error: {0}")]
85 WsError(Box<reqwest_websocket::Error>),
86 #[error("Websocket closing: {reason}")]
87 WsClosing { reason: &'static str },
88
89 #[error("Invalid padding: {0}")]
90 Padding(#[from] block_padding::Error),
91
92 #[error("unknown padding version {0}")]
93 PaddingVersion(u32),
94
95 #[error("Invalid frame: {reason}")]
96 InvalidFrame { reason: &'static str },
97
98 #[error("MAC error")]
99 MacError,
100
101 #[error("Protocol error: {0}")]
102 SignalProtocolError(#[from] SignalProtocolError),
103
104 #[error("Sealed sender decryption error: {0}")]
105 SealedSenderDecryptionError(#[from] SealedSenderDecryptionError),
106
107 #[error("invalid device id: {0}")]
108 InvalidDeviceId(#[from] libsignal_core::InvalidDeviceId),
109
110 #[error("Proof required: {0:?}")]
111 ProofRequiredError(ProofRequired),
112
113 #[error("{0:?}")]
114 MismatchedDevicesException(MismatchedDevices),
115
116 #[error("{0:?}")]
117 StaleDevices(StaleDevices),
118
119 #[error(transparent)]
120 CredentialsCacheError(#[from] crate::groups_v2::CredentialsCacheError),
121
122 #[error("groups v2 (zero-knowledge) error")]
123 GroupsV2Error,
124
125 #[error(transparent)]
126 GroupsV2DecryptionError(#[from] GroupDecodingError),
127
128 #[error(transparent)]
129 ZkGroupDeserializationFailure(#[from] ZkGroupDeserializationFailure),
130
131 #[error(transparent)]
132 ZkGroupVerificationFailure(#[from] ZkGroupVerificationFailure),
133
134 #[error("unsupported content")]
135 UnsupportedContent,
136
137 #[error("Not found.")]
138 NotFoundError,
139
140 #[error("failed to decrypt field from device info: {0}")]
141 DecryptDeviceInfoFieldError(&'static str),
142
143 #[error("Unknown CDN version {0}")]
144 UnknownCdnVersion(u32),
145
146 #[error("Device limit reached: {current} out of {max} devices.")]
147 DeviceLimitReached { current: u32, max: u32 },
148
149 #[error("client version too old; upgrade required")]
150 DeprecatedVersion,
151 #[error("request rejected by the server")]
152 ServerRejected,
153 #[error("recipient is not registered")]
154 UnregisteredRecipient,
155 #[error("message too large")]
156 MessageTooLarge,
157 #[error("multi-recipient mismatched devices: {0:?}")]
158 MultiRecipientMismatchedDevices(Vec<AccountMismatchedDevices>),
159 #[error("multi-recipient stale devices: {0:?}")]
160 MultiRecipientStaleDevices(Vec<AccountStaleDevices>),
161 #[error("invalid device verification code")]
162 InvalidDeviceVerificationCode,
163 #[error("device capabilities are a downgrade")]
164 DeviceCapabilityDowngrade,
165 #[error("no such verification session")]
166 NoSuchSession,
167 #[error("invalid or malformed verification session id")]
168 InvalidVerificationSessionId,
169 #[error("verification token rejected: {0:?}")]
170 TokenNotAccepted(RegistrationSessionMetadataResponse),
171 #[error("verification session conflict: {0:?}")]
172 RegistrationSessionConflict(RegistrationSessionMetadataResponse),
173 #[error("verification session rate limited: {session:?}")]
174 VerificationSessionRateLimited {
175 session: RegistrationSessionMetadataResponse,
176 retry_after: Option<chrono::Duration>,
177 },
178 #[error("verification transport not allowed: {0:?}")]
179 InvalidTransportMode(RegistrationSessionMetadataResponse),
180 #[error("verification code delivery failed: {0:?}")]
181 VerificationDeliveryFailed(VerificationDeliveryFailure),
182 #[error("device transfer required")]
183 DeviceTransferAvailable,
184 #[error("no username hash is set for this account")]
185 UsernameHashNotSet,
186 #[error("attachment too large")]
187 AttachmentTooLarge,
188 #[error("challenge token not accepted")]
189 ChallengeNotAccepted,
190
191 #[error("HTTP reqwest error: {0}")]
192 Http(#[from] reqwest::Error),
193
194 #[error(transparent)]
195 Curve(#[from] CurveError),
196
197 #[error("Cryptographic error: {0}")]
200 Hpke(signal_crypto::HpkeError),
201
202 #[error("Fingerprint error: {0}")]
205 Fingerprint(FingerprintError),
206
207 #[error("CDSI lookup error: {0}")]
208 #[cfg(feature = "cdsi")]
209 CdsiLookupError(#[from] libsignal_net::cdsi::LookupError),
210}
211
212impl From<signal_crypto::HpkeError> for ServiceError {
213 fn from(value: signal_crypto::HpkeError) -> Self {
214 ServiceError::Hpke(value)
215 }
216}
217
218impl From<FingerprintError> for ServiceError {
219 fn from(value: FingerprintError) -> Self {
220 ServiceError::Fingerprint(value)
221 }
222}
223
224impl From<reqwest_websocket::Error> for ServiceError {
225 fn from(error: reqwest_websocket::Error) -> Self {
226 Self::WsError(Box::new(error))
227 }
228}