use std;
use std::error::Error as _;
use std::fmt;
use std::io::Error;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::JsValue;
use block_modes::{BlockModeError, InvalidKeyIvLength};
use hmac::crypto_mac::InvalidKeyLength;
use hmac::crypto_mac::MacError;
use rand;
#[derive(Debug)]
pub enum DevoCryptoError {
InvalidLength,
InvalidKeyLength,
InvalidOutputLength,
InvalidSignature,
InvalidMac,
InvalidDataType,
UnknownType,
UnknownSubtype,
UnknownVersion,
NullPointer,
CryptoError,
RandomError,
IoError(Error),
}
impl DevoCryptoError {
pub fn error_code(&self) -> i64 {
match *self {
DevoCryptoError::InvalidLength => -1,
DevoCryptoError::InvalidKeyLength => -2,
DevoCryptoError::InvalidOutputLength => -3,
DevoCryptoError::InvalidSignature => -11,
DevoCryptoError::InvalidMac => -12,
DevoCryptoError::InvalidDataType => -13,
DevoCryptoError::UnknownType => -21,
DevoCryptoError::UnknownSubtype => -22,
DevoCryptoError::UnknownVersion => -23,
DevoCryptoError::NullPointer => -31,
DevoCryptoError::CryptoError => -32,
DevoCryptoError::RandomError => -33,
DevoCryptoError::IoError(_) => -34,
}
}
}
#[cfg(target_arch = "wasm32")]
impl DevoCryptoError {
pub fn name(&self) -> &str {
match *self {
DevoCryptoError::InvalidLength => "InvalidLength",
DevoCryptoError::InvalidKeyLength => "InvalidKeyLength",
DevoCryptoError::InvalidOutputLength => "InvalidOutputLength",
DevoCryptoError::InvalidSignature => "InvalidSignature",
DevoCryptoError::InvalidMac => "InvalidMac",
DevoCryptoError::InvalidDataType => "InvalidDataType",
DevoCryptoError::UnknownType => "UnknownType",
DevoCryptoError::UnknownSubtype => "UnknownSubtype",
DevoCryptoError::UnknownVersion => "UnknownVersion",
DevoCryptoError::NullPointer => "NullPointer",
DevoCryptoError::CryptoError => "CryptoError",
DevoCryptoError::RandomError => "RandomError",
DevoCryptoError::IoError(_) => "IoError",
}
}
}
impl fmt::Display for DevoCryptoError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
DevoCryptoError::IoError(ref error) => error.fmt(f),
_ => write!(f, "Error {}: {}", self.error_code(), self.description()),
}
}
}
impl std::error::Error for DevoCryptoError {
fn description(&self) -> &str {
match *self {
DevoCryptoError::InvalidLength => "The provided data has an invalid length.",
DevoCryptoError::InvalidKeyLength => "The key length is invalid.",
DevoCryptoError::InvalidOutputLength => {
"The length of the FFI output buffer is invalid."
}
DevoCryptoError::InvalidSignature => {
"The signature of the data blob does not match 0x0d0c."
}
DevoCryptoError::InvalidMac => "The MAC is invalid.",
DevoCryptoError::InvalidDataType => "The operation cannot be done with this type.",
DevoCryptoError::UnknownType => "The data type is unknown.",
DevoCryptoError::UnknownSubtype => "The data subtype is unknown.",
DevoCryptoError::UnknownVersion => "The data type version is unknown.",
DevoCryptoError::NullPointer => "A null pointer has been passed to the FFI interface.",
DevoCryptoError::CryptoError => "A cryptographic error occurred.",
DevoCryptoError::RandomError => "An error with the Random Number Generator occurred.",
DevoCryptoError::IoError(ref error) => error.description(),
}
}
}
impl From<InvalidKeyLength> for DevoCryptoError {
fn from(_error: InvalidKeyLength) -> DevoCryptoError {
DevoCryptoError::InvalidKeyLength
}
}
impl From<MacError> for DevoCryptoError {
fn from(_error: MacError) -> DevoCryptoError {
DevoCryptoError::InvalidMac
}
}
impl From<InvalidKeyIvLength> for DevoCryptoError {
fn from(_error: InvalidKeyIvLength) -> DevoCryptoError {
DevoCryptoError::InvalidKeyLength
}
}
impl From<BlockModeError> for DevoCryptoError {
fn from(_error: BlockModeError) -> DevoCryptoError {
DevoCryptoError::CryptoError
}
}
impl From<aead::Error> for DevoCryptoError {
fn from(_error: aead::Error) -> DevoCryptoError {
DevoCryptoError::CryptoError
}
}
impl From<rand::Error> for DevoCryptoError {
fn from(_error: rand::Error) -> DevoCryptoError {
DevoCryptoError::RandomError
}
}
impl From<std::io::Error> for DevoCryptoError {
fn from(_error: std::io::Error) -> DevoCryptoError {
DevoCryptoError::RandomError
}
}
#[cfg(target_arch = "wasm32")]
impl From<DevoCryptoError> for JsValue {
fn from(error: DevoCryptoError) -> JsValue {
let js_error = js_sys::Error::new(error.description());
js_error.set_name(error.name());
js_error.into()
}
}