Skip to main content

devolutions_crypto/
error.rs

1//! Possible errors in the library.
2use cbc::cipher::block_padding::Error as UnpadError;
3
4#[cfg(feature = "wbindgen")]
5use wasm_bindgen::JsValue;
6
7use strum::IntoStaticStr;
8
9use hmac::digest::MacError;
10
11pub type Result<T> = std::result::Result<T, Error>;
12
13/// This crate's error type.
14#[derive(Debug, IntoStaticStr, thiserror::Error)]
15pub enum Error {
16    /// The provided data has an invalid length. Error code: -1
17    #[error("The provided data has an invalid length")]
18    InvalidLength,
19    /// The key length is invalid. Error code: -2
20    #[error("The key length is invalid.")]
21    InvalidKeyLength,
22    /// The length of the FFI output buffer is invalid. Error code: -3
23    #[error("The length of the FFI output buffer is invalid.")]
24    InvalidOutputLength,
25    /// The signature of the data blob does not match 0x0d0c. Error code: -11
26    #[error("The signature of the data blob does not match 0x0d0c.")]
27    InvalidSignature,
28    /// The MAC is invalid. Error code: -12
29    #[error("The MAC is invalid.")]
30    InvalidMac,
31    /// The operation cannot be done with this type. Error code: -13
32    #[error("The operation cannot be done with this type.")]
33    InvalidDataType,
34    /// The data type is unknown. Error code: -21
35    #[error("The data type is unknown.")]
36    UnknownType,
37    /// The data subtype is unknown. Error code: -22
38    #[error("The data subtype is unknown.")]
39    UnknownSubtype,
40    /// The data type version is unknown. Error code: -23
41    #[error("The data type version is unknown.")]
42    UnknownVersion,
43    /// The data is invalid. Error code: -24
44    #[error("The data is invalid.")]
45    InvalidData,
46    /// A null pointer has been passed to the FFI interface. Error code: -31
47    #[error("A null pointer has been passed to the FFI interface.")]
48    NullPointer,
49    /// A cryptographic error occurred. Error code: -32
50    #[error("A cryptographic error occurred.")]
51    CryptoError,
52    /// An error with the Random Number Generator occurred. Error code: -33
53    #[error("An error with the Random Number Generator occurred.")]
54    RandomError,
55    /// A generic IO error has occurred. Error code: -34
56    #[error("Generic IO error: {0}")]
57    IoError(#[from] std::io::Error),
58    /// There is not enough shares to regenerate a secret: -41
59    #[error("There wasn't enough share to regenerate the secret.")]
60    NotEnoughShares,
61    /// The version of the multiple data is inconsistent: -42
62    #[error("The version is not the same for all the data.")]
63    InconsistentVersion,
64    /// The length of the data to encrypt/decrypt during online encryption is not the same as the chunk size: -43
65    #[error("The length of the data to encrypt/decrypt during online encryption is not the same as the chunk size")]
66    InvalidChunkLength,
67    /// The mutex is poisoned and cannot be locked: -44
68    #[error("The mutex is poisoned and cannot be locked")]
69    PoisonedMutex,
70}
71
72impl Error {
73    /// Returns the error code associated with the error.
74    /// This is useful for passing the exception type across a language boundary.
75    pub fn error_code(&self) -> i64 {
76        match *self {
77            Error::InvalidLength => -1,
78            Error::InvalidKeyLength => -2,
79            Error::InvalidOutputLength => -3,
80            Error::InvalidSignature => -11,
81            Error::InvalidMac => -12,
82            Error::InvalidDataType => -13,
83            Error::UnknownType => -21,
84            Error::UnknownSubtype => -22,
85            Error::UnknownVersion => -23,
86            Error::InvalidData => -24,
87            Error::NullPointer => -31,
88            Error::CryptoError => -32,
89            Error::RandomError => -33,
90            Error::IoError(_) => -34,
91            Error::NotEnoughShares => -41,
92            Error::InconsistentVersion => -42,
93            Error::InvalidChunkLength => -43,
94            Error::PoisonedMutex => -44,
95        }
96    }
97}
98
99impl From<hmac::digest::InvalidLength> for Error {
100    fn from(_error: hmac::digest::InvalidLength) -> Error {
101        Error::InvalidKeyLength
102    }
103}
104
105impl From<MacError> for Error {
106    fn from(_error: MacError) -> Error {
107        Error::InvalidMac
108    }
109}
110
111impl From<UnpadError> for Error {
112    fn from(_error: UnpadError) -> Error {
113        Error::CryptoError
114    }
115}
116
117impl From<chacha20poly1305::aead::Error> for Error {
118    fn from(_error: chacha20poly1305::aead::Error) -> Error {
119        Error::InvalidMac
120    }
121}
122
123impl From<argon2::Error> for Error {
124    fn from(_error: argon2::Error) -> Self {
125        Error::CryptoError
126    }
127}
128
129#[cfg(feature = "wbindgen")]
130impl From<Error> for JsValue {
131    fn from(error: Error) -> JsValue {
132        let js_error = js_sys::Error::new(&error.to_string());
133
134        js_error.set_name(error.into());
135        js_error.into()
136    }
137}