1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
//! CryptoError covers all errors not covered by StorageError. It is returned by
//! every function in this crate returning a Result except those used in the
//! `Storer` trait.

use std::{
    error::Error,
    fmt::{self, Display, Formatter},
};

/// Error that wraps all possible errors out of the redact-crypto crate
#[derive(Debug)]
pub enum CryptoError {
    /// Represents an error which occurred in some internal system
    InternalError {
        source: Box<dyn Error + Send + Sync>,
    },

    /// The requested resource was not found
    NotFound {
        source: Box<dyn Error + Send + Sync>,
    },

    /// Ciphertext failed veri fication before decryption
    CiphertextFailedVerification,

    /// Provided bytes are not the right length for the
    InvalidKeyLength { expected: usize, actual: usize },

    /// Given value was not of the right type to be downcasted to the requested type
    NotDowncastable,

    /// Given bytes could not be serialized to a base data type
    NotDeserializableToBaseDataType,

    /// Wrong nonce was provided during seal/unseal operation
    WrongNonceType,
}

impl Error for CryptoError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        match *self {
            CryptoError::InternalError { ref source } => Some(source.as_ref()),
            CryptoError::NotFound { ref source } => Some(source.as_ref()),
            CryptoError::CiphertextFailedVerification => None,
            CryptoError::InvalidKeyLength { .. } => None,
            CryptoError::NotDowncastable => None,
            CryptoError::NotDeserializableToBaseDataType => None,
            CryptoError::WrongNonceType => None,
        }
    }
}

impl Display for CryptoError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        match *self {
            CryptoError::InternalError { .. } => {
                write!(f, "Internal error occurred")
            }
            CryptoError::NotFound { .. } => {
                write!(f, "Requested resource not found")
            }
            CryptoError::CiphertextFailedVerification => {
                write!(f, "Ciphertext failed verification before decryption")
            }
            CryptoError::InvalidKeyLength {
                ref expected,
                ref actual,
            } => {
                write!(
                    f,
                    "Provided key was not the correct length, expected: {}, actual: {}",
                    expected, actual,
                )
            }
            CryptoError::NotDowncastable => {
                write!(
                    f,
                    "Could not downcast the Types-value into the requested variant"
                )
            }
            CryptoError::NotDeserializableToBaseDataType => {
                write!(f, "Given bytes could not be deserialized to one of: bool, u64, i64, f64, or string")
            }
            CryptoError::WrongNonceType => {
                write!(f, "Invalid type of nonce was provided for the operation")
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::CryptoError;

    #[test]
    fn test_to_string_internal_error() {
        let s = CryptoError::InternalError {
            source: Box::new(CryptoError::NotDowncastable),
        }
        .to_string();
        assert_eq!(s, "Internal error occurred");
    }

    #[test]
    fn test_to_string_not_found() {
        let s = CryptoError::NotDowncastable.to_string();
        assert_eq!(
            s,
            "Could not downcast the Types-value into the requested variant"
        );
    }
}