1 //! Error type for BER/DER parsers 2 3 use crate::ber::BerObject; 4 use crate::der::DerObject; 5 use alloc::fmt; 6 use nom::error::{ErrorKind, FromExternalError, ParseError}; 7 use nom::IResult; 8 9 /// Holds the result of parsing functions 10 /// 11 /// `O` is the output type, and defaults to a `BerObject`. 12 /// 13 /// Note that this type is also a `Result`, so usual functions (`map`, `unwrap` etc.) are available. 14 /// 15 /// This type is a wrapper around nom's IResult type 16 pub type BerResult<'a, O = BerObject<'a>> = IResult<&'a [u8], O, BerError>; 17 18 /// Holds the result of parsing functions (DER) 19 /// 20 /// Note that this type is also a `Result`, so usual functions (`map`, `unwrap` etc.) are available. 21 pub type DerResult<'a> = BerResult<'a, DerObject<'a>>; 22 23 /// Error for BER/DER parsers 24 #[derive(Debug, PartialEq, Copy, Clone)] 25 pub enum BerError { 26 /// BER object does not have the expected type 27 BerTypeError, 28 /// BER object does not have the expected value 29 BerValueError, 30 31 InvalidTag, 32 InvalidClass, 33 InvalidLength, 34 35 IndefiniteLengthUnexpected, 36 37 /// DER object was expected to be constructed (and found to be primitive) 38 ConstructExpected, 39 /// DER object was expected to be primitive (and found to be constructed) 40 ConstructUnexpected, 41 42 /// BER string has characters forbidden in standard 43 StringInvalidCharset, 44 45 /// BER integer is too large to fit in a native type. Use `as_bigint()` 46 IntegerTooLarge, 47 /// BER integer is negative, while an unsigned integer was requested 48 IntegerNegative, 49 50 /// BER recursive parsing reached maximum depth (See 51 /// [MAX_RECURSION](../ber/constant.MAX_RECURSION.html)) 52 BerMaxDepth, 53 54 /// When parsing a defined sequence, some items could not be found 55 ObjectTooShort, 56 57 /// A DER constraint failed (object may be using BER encoding?) 58 DerConstraintFailed, 59 60 UnknownTag, 61 /// Feature is not yet implemented 62 Unsupported, 63 64 /// Custom error type left for parsers on top of this crate, so they can handle their custom 65 /// errors 66 Custom(u32), 67 68 /// Error raised by the underlying nom parser 69 NomError(ErrorKind), 70 } 71 72 impl From<BerError> for nom::Err<BerError> { from(e: BerError) -> nom::Err<BerError>73 fn from(e: BerError) -> nom::Err<BerError> { 74 nom::Err::Error(e) 75 } 76 } 77 78 impl<I> ParseError<I> for BerError { from_error_kind(_input: I, kind: ErrorKind) -> Self79 fn from_error_kind(_input: I, kind: ErrorKind) -> Self { 80 BerError::NomError(kind) 81 } append(_input: I, kind: ErrorKind, _other: Self) -> Self82 fn append(_input: I, kind: ErrorKind, _other: Self) -> Self { 83 BerError::NomError(kind) 84 } 85 } 86 87 impl<I, E> FromExternalError<I, E> for BerError { from_external_error(_input: I, kind: ErrorKind, _e: E) -> BerError88 fn from_external_error(_input: I, kind: ErrorKind, _e: E) -> BerError { 89 BerError::NomError(kind) 90 } 91 } 92 93 impl fmt::Display for BerError { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result94 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 95 write!(f, "{:?}", self) 96 } 97 } 98 99 #[cfg(feature = "std")] 100 impl std::error::Error for BerError {} 101 102 #[cfg(all(test, feature = "std"))] 103 mod tests { 104 use super::*; 105 use std::boxed::Box; 106 use std::error::Error; 107 108 #[test] test_unwrap_bererror()109 fn test_unwrap_bererror() { 110 let e = BerError::IntegerTooLarge; 111 // println!("{}", e); 112 let _: Result<(), Box<dyn Error>> = Err(Box::new(e)); 113 } 114 } 115