olm_rs/
errors.rs

1// Copyright 2020 Johannes Hayeß
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! A collection of all errors that can be returned by `libolm`.
16//!
17//! All error enums additionally contain an error named `Unknown`,
18//! for returning an error, in case an error is encountered by `libolm`,
19//! but no error code is provided.
20
21use std::error::Error;
22use std::fmt;
23use std::fmt::Debug;
24
25/// Since libolm does not do heap allocation and instead relies on the user to
26/// provide already allocated buffers, a lot of potential errors regarding
27/// buffer size can be encountered.
28/// In most places in this library we create such buffers exactly the way
29/// libolm would want, and as such a lot of potential errors would be eliminated.
30/// If such an error is still encountered, it would indicate that something else
31/// is seriously wrong with the execution environment, so we panic unrecoverably.
32pub(crate) fn handle_fatal_error<E>(error: E)
33where
34    E: Debug,
35{
36    unreachable!("Encountered fatal error: {:?}", error);
37}
38
39pub(crate) fn olm_error() -> usize {
40    unsafe { olm_sys::olm_error() }
41}
42
43static BAD_ACCOUNT_KEY: &str = "The supplied account key is invalid";
44static INVALID_BASE64: &str = "The input base64 was invalid";
45static BAD_MSG_KEY_ID: &str = "The message references an unknown key id";
46static BAD_MSG_FMT: &str = "The message couldn't be decoded";
47static BAD_MSG_MAC: &str = "The message couldn't be decrypted";
48static BAD_MSG_VERSION: &str = "The message version is unsupported";
49static BAD_SESSION_KEY: &str = "Can't initialise the inbound group session, invalid session key";
50static BAD_MSG_INDEX: &str =
51    "Can't decode the message, message index is earlier than our earliest known session key";
52static NOT_ENOUGH_RAND: &str = "Not enough entropy was supplied";
53static BUFFER_SMALL: &str = "Supplied output buffer is too small";
54static INPUT_BUFFER_SMALL: &str = "Supplied input buffer is too small";
55static UNKNOWN: &str = "An unknown error occured.";
56
57/// All errors that could be caused by an operation regarding an
58/// [`OlmAccount`](crate::account::OlmAccount).
59/// Errors are named exactly like the ones in libolm.
60#[derive(Debug, PartialEq)]
61pub enum OlmAccountError {
62    BadAccountKey,
63    BadMessageKeyId,
64    InvalidBase64,
65    NotEnoughRandom,
66    OutputBufferTooSmall,
67    Unknown,
68}
69
70impl fmt::Display for OlmAccountError {
71    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72        let message = match self {
73            OlmAccountError::BadAccountKey => BAD_ACCOUNT_KEY,
74            OlmAccountError::BadMessageKeyId => BAD_MSG_KEY_ID,
75            OlmAccountError::InvalidBase64 => INVALID_BASE64,
76            OlmAccountError::NotEnoughRandom => NOT_ENOUGH_RAND,
77            OlmAccountError::OutputBufferTooSmall => BUFFER_SMALL,
78            OlmAccountError::Unknown => UNKNOWN,
79        };
80        write!(f, "{}", message)
81    }
82}
83
84impl Error for OlmAccountError {}
85impl Error for OlmSessionError {}
86impl Error for OlmGroupSessionError {}
87impl Error for OlmPkDecryptionError {}
88impl Error for OlmPkSigningError {}
89
90/// All errors that could be caused by an operation regarding [`OlmUitlity`](crate::utility::OlmUtility).
91/// Errors are named exactly like the ones in libolm.
92#[derive(Debug, PartialEq)]
93pub enum OlmUtilityError {
94    InvalidBase64,
95    OutputBufferTooSmall,
96    BadMessageMac,
97    Unknown,
98}
99
100/// All errors that could be caused by an operation regarding an [`OlmSession`](crate::session::OlmSession).
101/// Errors are named exactly like the ones in libolm.
102#[derive(Debug, PartialEq)]
103pub enum OlmSessionError {
104    BadAccountKey,
105    BadMessageFormat,
106    BadMessageKeyId,
107    BadMessageMac,
108    BadMessageVersion,
109    InvalidBase64,
110    NotEnoughRandom,
111    OutputBufferTooSmall,
112    Unknown,
113}
114
115impl fmt::Display for OlmSessionError {
116    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117        let message = match self {
118            OlmSessionError::BadAccountKey => BAD_ACCOUNT_KEY,
119            OlmSessionError::BadMessageKeyId => BAD_MSG_KEY_ID,
120            OlmSessionError::BadMessageFormat => BAD_MSG_FMT,
121            OlmSessionError::BadMessageMac => BAD_MSG_MAC,
122            OlmSessionError::BadMessageVersion => BAD_MSG_VERSION,
123            OlmSessionError::InvalidBase64 => INVALID_BASE64,
124            OlmSessionError::NotEnoughRandom => NOT_ENOUGH_RAND,
125            OlmSessionError::OutputBufferTooSmall => BUFFER_SMALL,
126            OlmSessionError::Unknown => UNKNOWN,
127        };
128        write!(f, "{}", message)
129    }
130}
131
132/// All errors that could be caused by an operation regarding
133/// [`OlmOutboundGroupSession`](crate::outbound_group_session::OlmOutboundGroupSession) and
134/// [`OlmInboundGroupSession`](crate::inbound_group_session::OlmInboundGroupSession).
135/// Errors are named exactly like the ones in libolm.
136#[derive(Debug, PartialEq)]
137pub enum OlmGroupSessionError {
138    BadAccountKey,
139    BadMessageFormat,
140    BadMessageMac,
141    BadMessageVersion,
142    BadSessionKey,
143    InvalidBase64,
144    NotEnoughRandom,
145    OutputBufferTooSmall,
146    UnknownMessageIndex,
147    Unknown,
148}
149
150impl fmt::Display for OlmGroupSessionError {
151    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
152        let message = match self {
153            OlmGroupSessionError::BadAccountKey => BAD_ACCOUNT_KEY,
154            OlmGroupSessionError::BadSessionKey => BAD_SESSION_KEY,
155            OlmGroupSessionError::UnknownMessageIndex => BAD_MSG_INDEX,
156            OlmGroupSessionError::BadMessageFormat => BAD_MSG_FMT,
157            OlmGroupSessionError::BadMessageMac => BAD_MSG_MAC,
158            OlmGroupSessionError::BadMessageVersion => BAD_MSG_VERSION,
159            OlmGroupSessionError::InvalidBase64 => INVALID_BASE64,
160            OlmGroupSessionError::NotEnoughRandom => NOT_ENOUGH_RAND,
161            OlmGroupSessionError::OutputBufferTooSmall => BUFFER_SMALL,
162            OlmGroupSessionError::Unknown => UNKNOWN,
163        };
164        write!(f, "{}", message)
165    }
166}
167
168/// All errors that could be caused by an operation regarding
169/// [`OlmSas`](crate::sas::OlmSas).
170/// Errors are named exactly like the ones in libolm.
171#[derive(Debug, PartialEq)]
172pub enum OlmSasError {
173    NotEnoughRandom,
174    OutputBufferTooSmall,
175    InputBufferTooSmall,
176    OtherPublicKeyUnset,
177    InvalidLength,
178    Unknown,
179}
180
181impl fmt::Display for OlmSasError {
182    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
183        let message = match self {
184            OlmSasError::NotEnoughRandom => NOT_ENOUGH_RAND,
185            OlmSasError::OutputBufferTooSmall => BUFFER_SMALL,
186            OlmSasError::InputBufferTooSmall => INPUT_BUFFER_SMALL,
187            OlmSasError::OtherPublicKeyUnset => "The other public key isn't set",
188            OlmSasError::InvalidLength => "The length can't be zero",
189            OlmSasError::Unknown => UNKNOWN,
190        };
191        write!(f, "{}", message)
192    }
193}
194
195/// All errors that could be caused by an operation regarding
196/// [`OlmPkSigning`](crate::pk::OlmPkSigning).
197/// Errors are named exactly like the ones in libolm.
198#[derive(Debug, PartialEq)]
199pub enum OlmPkSigningError {
200    InvalidSeed,
201    OutputBufferTooSmall,
202    InputBufferTooSmall,
203    Unknown,
204}
205
206impl fmt::Display for OlmPkSigningError {
207    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
208        let message = match self {
209            OlmPkSigningError::InvalidSeed => "The given seed is too short",
210            OlmPkSigningError::OutputBufferTooSmall => BUFFER_SMALL,
211            OlmPkSigningError::InputBufferTooSmall => INPUT_BUFFER_SMALL,
212            OlmPkSigningError::Unknown => UNKNOWN,
213        };
214        write!(f, "{}", message)
215    }
216}
217
218impl From<&str> for OlmPkSigningError {
219    fn from(value: &str) -> Self {
220        match value {
221            "OUTPUT_BUFFER_TOO_SMALL" => OlmPkSigningError::OutputBufferTooSmall,
222            "INPUT_BUFFER_TOO_SMALL" => OlmPkSigningError::OutputBufferTooSmall,
223            _ => OlmPkSigningError::Unknown,
224        }
225    }
226}
227
228/// All errors that could be caused by an operation regarding
229/// [`OlmPkEncryption`](crate::pk::OlmPkEncryption).
230/// Errors are named exactly like the ones in libolm.
231#[derive(Debug, PartialEq)]
232pub enum OlmPkEncryptionError {
233    OutputBufferTooSmall,
234    InputBufferTooSmall,
235    Unknown,
236}
237
238impl fmt::Display for OlmPkEncryptionError {
239    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
240        let message = match self {
241            OlmPkEncryptionError::OutputBufferTooSmall => BUFFER_SMALL,
242            OlmPkEncryptionError::InputBufferTooSmall => INPUT_BUFFER_SMALL,
243            OlmPkEncryptionError::Unknown => UNKNOWN,
244        };
245        write!(f, "{}", message)
246    }
247}
248
249impl From<&str> for OlmPkEncryptionError {
250    fn from(value: &str) -> Self {
251        match value {
252            "OUTPUT_BUFFER_TOO_SMALL" => OlmPkEncryptionError::OutputBufferTooSmall,
253            "INPUT_BUFFER_TOO_SMALL" => OlmPkEncryptionError::OutputBufferTooSmall,
254            _ => OlmPkEncryptionError::Unknown,
255        }
256    }
257}
258
259/// All errors that could be caused by an operation regarding
260/// [`OlmPkDecryption`](crate::pk::OlmPkDecryption).
261/// Errors are named exactly like the ones in libolm.
262#[derive(Debug, PartialEq)]
263pub enum OlmPkDecryptionError {
264    BadAccountKey,
265    BadMessageMac,
266    InvalidBase64,
267    OutputBufferTooSmall,
268    InputBufferTooSmall,
269    Unknown(String),
270}
271
272impl fmt::Display for OlmPkDecryptionError {
273    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
274        let message = match self {
275            OlmPkDecryptionError::InvalidBase64 => INVALID_BASE64,
276            OlmPkDecryptionError::BadAccountKey => BAD_ACCOUNT_KEY,
277            OlmPkDecryptionError::BadMessageMac => BAD_MSG_MAC,
278            OlmPkDecryptionError::OutputBufferTooSmall => BUFFER_SMALL,
279            OlmPkDecryptionError::InputBufferTooSmall => INPUT_BUFFER_SMALL,
280            OlmPkDecryptionError::Unknown(e) => e,
281        };
282        write!(f, "{}", message)
283    }
284}
285
286impl From<&str> for OlmPkDecryptionError {
287    fn from(value: &str) -> Self {
288        match value {
289            "INVALID_BASE64" => OlmPkDecryptionError::InvalidBase64,
290            "BAD_MESSAGE_MAC" => OlmPkDecryptionError::BadMessageMac,
291            "BAD_ACCOUNT_KEY" => OlmPkDecryptionError::BadAccountKey,
292            "OUTPUT_BUFFER_TOO_SMALL" => OlmPkDecryptionError::OutputBufferTooSmall,
293            "INPUT_BUFFER_TOO_SMALL" => OlmPkDecryptionError::OutputBufferTooSmall,
294            m => OlmPkDecryptionError::Unknown(m.to_owned()),
295        }
296    }
297}