wolfcose 0.1.0

Safe Rust API for wolfSSL wolfCOSE.
use crate::raw;
use core::fmt;

/// Result type used by this crate.
pub type Result<T> = core::result::Result<T, Error>;

/// wolfCOSE error code wrapper.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Error {
    /// Invalid argument.
    InvalidArgument,
    /// Output or scratch buffer was too small.
    BufferTooSmall,
    /// Malformed CBOR input.
    CborMalformed,
    /// Unexpected CBOR type.
    CborType,
    /// CBOR integer or length overflow.
    CborOverflow,
    /// CBOR nesting exceeded configured limit.
    CborDepth,
    /// Bad COSE tag.
    CoseBadTag,
    /// Bad or unsupported COSE algorithm.
    CoseBadAlgorithm,
    /// Signature verification failed.
    CoseSignatureFailed,
    /// Decryption failed.
    CoseDecryptFailed,
    /// Bad COSE header.
    CoseBadHeader,
    /// COSE key type mismatch.
    CoseKeyType,
    /// COSE MAC verification failed.
    CoseMacFailed,
    /// wolfCrypt error.
    Crypto,
    /// Unsupported operation or algorithm.
    Unsupported,
    /// MAC verification failed.
    MacFailed,
    /// Detached payload/ciphertext was required but absent.
    DetachedPayload,
    /// Unknown raw wolfCOSE return code.
    Unknown(i32),
}

impl Error {
    /// Convert a raw wolfCOSE status code into a Rust result.
    pub fn from_code(code: i32) -> Result<()> {
        if code == raw::WOLFCOSE_SUCCESS as i32 {
            Ok(())
        } else {
            Err(Self::from(code))
        }
    }

    /// Return the raw wolfCOSE error code.
    pub fn code(self) -> i32 {
        match self {
            Self::InvalidArgument => raw::WOLFCOSE_E_INVALID_ARG,
            Self::BufferTooSmall => raw::WOLFCOSE_E_BUFFER_TOO_SMALL,
            Self::CborMalformed => raw::WOLFCOSE_E_CBOR_MALFORMED,
            Self::CborType => raw::WOLFCOSE_E_CBOR_TYPE,
            Self::CborOverflow => raw::WOLFCOSE_E_CBOR_OVERFLOW,
            Self::CborDepth => raw::WOLFCOSE_E_CBOR_DEPTH,
            Self::CoseBadTag => raw::WOLFCOSE_E_COSE_BAD_TAG,
            Self::CoseBadAlgorithm => raw::WOLFCOSE_E_COSE_BAD_ALG,
            Self::CoseSignatureFailed => raw::WOLFCOSE_E_COSE_SIG_FAIL,
            Self::CoseDecryptFailed => raw::WOLFCOSE_E_COSE_DECRYPT_FAIL,
            Self::CoseBadHeader => raw::WOLFCOSE_E_COSE_BAD_HDR,
            Self::CoseKeyType => raw::WOLFCOSE_E_COSE_KEY_TYPE,
            Self::CoseMacFailed => raw::WOLFCOSE_E_COSE_MAC_FAIL,
            Self::Crypto => raw::WOLFCOSE_E_CRYPTO,
            Self::Unsupported => raw::WOLFCOSE_E_UNSUPPORTED,
            Self::MacFailed => raw::WOLFCOSE_E_MAC_FAIL,
            Self::DetachedPayload => raw::WOLFCOSE_E_DETACHED_PAYLOAD,
            Self::Unknown(code) => code,
        }
    }
}

impl From<i32> for Error {
    fn from(code: i32) -> Self {
        match code {
            raw::WOLFCOSE_E_INVALID_ARG => Self::InvalidArgument,
            raw::WOLFCOSE_E_BUFFER_TOO_SMALL => Self::BufferTooSmall,
            raw::WOLFCOSE_E_CBOR_MALFORMED => Self::CborMalformed,
            raw::WOLFCOSE_E_CBOR_TYPE => Self::CborType,
            raw::WOLFCOSE_E_CBOR_OVERFLOW => Self::CborOverflow,
            raw::WOLFCOSE_E_CBOR_DEPTH => Self::CborDepth,
            raw::WOLFCOSE_E_COSE_BAD_TAG => Self::CoseBadTag,
            raw::WOLFCOSE_E_COSE_BAD_ALG => Self::CoseBadAlgorithm,
            raw::WOLFCOSE_E_COSE_SIG_FAIL => Self::CoseSignatureFailed,
            raw::WOLFCOSE_E_COSE_DECRYPT_FAIL => Self::CoseDecryptFailed,
            raw::WOLFCOSE_E_COSE_BAD_HDR => Self::CoseBadHeader,
            raw::WOLFCOSE_E_COSE_KEY_TYPE => Self::CoseKeyType,
            raw::WOLFCOSE_E_COSE_MAC_FAIL => Self::CoseMacFailed,
            raw::WOLFCOSE_E_CRYPTO => Self::Crypto,
            raw::WOLFCOSE_E_UNSUPPORTED => Self::Unsupported,
            raw::WOLFCOSE_E_MAC_FAIL => Self::MacFailed,
            raw::WOLFCOSE_E_DETACHED_PAYLOAD => Self::DetachedPayload,
            other => Self::Unknown(other),
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "wolfCOSE error {}", self.code())
    }
}

#[cfg(feature = "std")]
impl std::error::Error for Error {}