• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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