Skip to main content

libsignal_service/push_service/
error.rs

1use 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    // HpkeError does not implement StdError, so we need a manual display,
198    // and manual From impl.
199    #[error("Cryptographic error: {0}")]
200    Hpke(signal_crypto::HpkeError),
201
202    // FingerprintError does not implement StdError, so we need a manual display,
203    // and manual From impl.
204    #[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}