asn1_rs/
error.rs

1use crate::{Class, Tag};
2use alloc::str;
3use alloc::string;
4use alloc::string::String;
5use displaydoc::Display;
6use nom::error::{ErrorKind, FromExternalError, ParseError};
7use nom::IResult;
8#[cfg(feature = "std")]
9use std::io;
10#[cfg(feature = "std")]
11use thiserror::Error;
12
13#[cfg(feature = "std")]
14impl std::error::Error for DerConstraint {}
15
16#[derive(Clone, Copy, Debug, Display, PartialEq, Eq)]
17/// Error types for DER constraints
18pub enum DerConstraint {
19    /// Indefinite length not allowed
20    IndefiniteLength,
21    /// Object must not be constructed
22    Constructed,
23    /// Object must be constructed
24    NotConstructed,
25    /// DateTime object is missing timezone
26    MissingTimeZone,
27    /// DateTime object is missing seconds
28    MissingSeconds,
29    /// Bitstring unused bits must be set to zero
30    UnusedBitsNotZero,
31    /// Boolean value must be 0x00 of 0xff
32    InvalidBoolean,
33    /// Integer must not be empty
34    IntegerEmpty,
35    /// Leading zeroes in Integer encoding
36    IntegerLeadingZeroes,
37    /// Leading 0xff in negative Integer encoding
38    IntegerLeadingFF,
39}
40
41// XXX
42// thiserror does not work in no_std
43// see https://github.com/dtolnay/thiserror/pull/64
44
45#[cfg(feature = "std")]
46impl std::error::Error for Error {}
47
48/// The error type for operations of the [`FromBer`](crate::FromBer),
49/// [`FromDer`](crate::FromDer), and associated traits.
50#[derive(Clone, Debug, Display, PartialEq, Eq)]
51// #[cfg_attr(feature = "std", derive(Error))]
52pub enum Error {
53    /// BER object does not have the expected type
54    BerTypeError,
55    /// BER object does not have the expected value
56    BerValueError,
57    /// Invalid Length
58    InvalidLength,
59    /// Invalid Value when parsing object with tag {tag:?} {msg:}
60    InvalidValue { tag: Tag, msg: String },
61    /// Invalid Tag
62    InvalidTag,
63    /// Unknown tag: {0:?}
64    UnknownTag(u32),
65    /// Unexpected Tag (expected: {expected:?}, actual: {actual:?})
66    UnexpectedTag { expected: Option<Tag>, actual: Tag },
67    /// Unexpected Class (expected: {expected:?}, actual: {actual:?})
68    UnexpectedClass {
69        expected: Option<Class>,
70        actual: Class,
71    },
72
73    /// Indefinite length not allowed
74    IndefiniteLengthUnexpected,
75
76    /// DER object was expected to be constructed (and found to be primitive)
77    ConstructExpected,
78    /// DER object was expected to be primitive (and found to be constructed)
79    ConstructUnexpected,
80
81    /// Integer too large to fit requested type
82    IntegerTooLarge,
83    /// BER integer is negative, while an unsigned integer was requested
84    IntegerNegative,
85    /// BER recursive parsing reached maximum depth
86    BerMaxDepth,
87
88    /// Invalid encoding or forbidden characters in string
89    StringInvalidCharset,
90    /// Invalid Date or Time
91    InvalidDateTime,
92
93    /// DER Failed constraint
94    DerConstraintFailed(DerConstraint),
95
96    /// Requesting borrowed data from a temporary object
97    LifetimeError,
98    /// Feature is not yet implemented
99    Unsupported,
100
101    /// incomplete data, missing: {0:?}
102    Incomplete(nom::Needed),
103
104    /// nom error: {0:?}
105    NomError(ErrorKind),
106}
107
108impl Error {
109    /// Build an error from the provided invalid value
110    #[inline]
111    pub const fn invalid_value(tag: Tag, msg: String) -> Self {
112        Self::InvalidValue { tag, msg }
113    }
114
115    /// Build an error from the provided unexpected class
116    #[inline]
117    pub const fn unexpected_class(expected: Option<Class>, actual: Class) -> Self {
118        Self::UnexpectedClass { expected, actual }
119    }
120
121    /// Build an error from the provided unexpected tag
122    #[inline]
123    pub const fn unexpected_tag(expected: Option<Tag>, actual: Tag) -> Self {
124        Self::UnexpectedTag { expected, actual }
125    }
126}
127
128impl<'a> ParseError<&'a [u8]> for Error {
129    fn from_error_kind(_input: &'a [u8], kind: ErrorKind) -> Self {
130        Error::NomError(kind)
131    }
132    fn append(_input: &'a [u8], kind: ErrorKind, _other: Self) -> Self {
133        Error::NomError(kind)
134    }
135}
136
137impl From<Error> for nom::Err<Error> {
138    fn from(e: Error) -> Self {
139        nom::Err::Error(e)
140    }
141}
142
143impl From<str::Utf8Error> for Error {
144    fn from(_: str::Utf8Error) -> Self {
145        Error::StringInvalidCharset
146    }
147}
148
149impl From<string::FromUtf8Error> for Error {
150    fn from(_: string::FromUtf8Error) -> Self {
151        Error::StringInvalidCharset
152    }
153}
154
155impl From<string::FromUtf16Error> for Error {
156    fn from(_: string::FromUtf16Error) -> Self {
157        Error::StringInvalidCharset
158    }
159}
160
161impl From<nom::Err<Error>> for Error {
162    fn from(e: nom::Err<Error>) -> Self {
163        match e {
164            nom::Err::Incomplete(n) => Self::Incomplete(n),
165            nom::Err::Error(e) | nom::Err::Failure(e) => e,
166        }
167    }
168}
169
170impl<I, E> FromExternalError<I, E> for Error {
171    fn from_external_error(_input: I, kind: ErrorKind, _e: E) -> Error {
172        Error::NomError(kind)
173    }
174}
175
176/// Holds the result of BER/DER serialization functions
177pub type ParseResult<'a, T, E = Error> = IResult<&'a [u8], T, E>;
178
179/// A specialized `Result` type for all operations from this crate.
180pub type Result<T, E = Error> = core::result::Result<T, E>;
181
182/// The error type for serialization operations of the [`ToDer`](crate::ToDer) trait.
183#[cfg(feature = "std")]
184#[derive(Debug, Error)]
185pub enum SerializeError {
186    #[error("ASN.1 error: {0:?}")]
187    ASN1Error(#[from] Error),
188
189    #[error("Invalid Class {class:}")]
190    InvalidClass { class: u8 },
191
192    #[error("Invalid Length")]
193    InvalidLength,
194
195    #[error("I/O error: {0:?}")]
196    IOError(#[from] io::Error),
197}
198
199#[cfg(feature = "std")]
200/// Holds the result of BER/DER encoding functions
201pub type SerializeResult<T> = std::result::Result<T, SerializeError>;