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
113
114
115
116
use crate::{Class, Tag};
use nom::error::{ErrorKind, ParseError};
use nom::IResult;
use std::io;
use std::str;
use std::string;
use thiserror::Error;

#[derive(Debug, Error, PartialEq)]
pub enum Error {
    #[error("Invalid Length")]
    InvalidLength,
    #[error("Invalid Value when parsing object with tag {tag:?} {msg:}")]
    InvalidValue { tag: Tag, msg: String },
    #[error("Invalid Tag")]
    InvalidTag,
    #[error("Unknown tag: {0:?}")]
    UnknownTag(u32),
    #[error("Unexpected Tag (expected: {expected:?}, actual: {actual:?})")]
    UnexpectedTag { expected: Option<Tag>, actual: Tag },
    #[error("Unexpected Class (expected: {0:?}")]
    UnexpectedClass(Class),

    #[error("Indefinite length not allowed")]
    IndefiniteLengthUnexpected,

    #[error("DER object was expected to be constructed (and found to be primitive)")]
    ConstructExpected,
    #[error("DER object was expected to be primitive (and found to be constructed)")]
    ConstructUnexpected,

    #[error("Integer too large")]
    IntegerTooLarge,
    #[error("BER recursive parsing reached maximum depth")]
    BerMaxDepth,

    #[error("Invalid encoding or forbidden characters in string")]
    StringInvalidCharset,

    #[error("DER Failed constraint")]
    DerConstraintFailed,

    #[error("Requesting borrowed data from a temporary object")]
    LifetimeError,
    #[error("Feature is not yet implemented")]
    Unsupported,

    #[error("incomplete data, missing: {0:?}")]
    Incomplete(nom::Needed),

    #[error("nom error: {0:?}")]
    NomError(ErrorKind),
}

impl<'a> ParseError<&'a [u8]> for Error {
    fn from_error_kind(_input: &'a [u8], kind: ErrorKind) -> Self {
        Error::NomError(kind)
    }
    fn append(_input: &'a [u8], kind: ErrorKind, _other: Self) -> Self {
        Error::NomError(kind)
    }
}

impl From<Error> for nom::Err<Error> {
    fn from(e: Error) -> Self {
        nom::Err::Failure(e)
    }
}

impl From<str::Utf8Error> for Error {
    fn from(_: str::Utf8Error) -> Self {
        Error::StringInvalidCharset
    }
}

impl From<string::FromUtf8Error> for Error {
    fn from(_: string::FromUtf8Error) -> Self {
        Error::StringInvalidCharset
    }
}

impl From<string::FromUtf16Error> for Error {
    fn from(_: string::FromUtf16Error) -> Self {
        Error::StringInvalidCharset
    }
}

impl From<nom::Err<Error>> for Error {
    fn from(e: nom::Err<Error>) -> Self {
        match e {
            nom::Err::Incomplete(n) => Self::Incomplete(n),
            nom::Err::Error(e) | nom::Err::Failure(e) => e,
        }
    }
}

/// Holds the result of BER/DER serialization functions
pub type ParseResult<'a, T> = IResult<&'a [u8], T, Error>;

/// A specialized `Result` type for all operations from this crate.
pub type Result<T> = std::result::Result<T, Error>;

#[derive(Debug, Error)]
pub enum SerializeError {
    #[error("ASN.1 error: {0:?}")]
    ASN1Error(#[from] Error),

    #[error("Invalid Length")]
    InvalidLength,

    #[error("I/O error: {0:?}")]
    IOError(#[from] io::Error),
}

/// Holds the result of BER/DER encoding functions
pub type SerializeResult<T> = std::result::Result<T, SerializeError>;