3 pub use core
::str::Utf8Error
;
5 use crate::{Length, Tag}
;
6 use core
::{convert::Infallible, fmt, num::TryFromIntError}
;
8 #[cfg(feature = "oid")]
9 use crate::asn1
::ObjectIdentifier
;
11 #[cfg(feature = "pem")]
15 pub type Result
<T
> = core
::result
::Result
<T
, Error
>;
18 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
23 /// Position inside of message where error occurred.
24 position
: Option
<Length
>,
28 /// Create a new [`Error`].
29 pub fn new(kind
: ErrorKind
, position
: Length
) -> Error
{
32 position
: Some(position
),
36 /// Create a new [`ErrorKind::Incomplete`] for the given length.
38 /// Computes the expected len as being one greater than `actual_len`.
39 pub fn incomplete(actual_len
: Length
) -> Self {
40 match actual_len
+ Length
::ONE
{
41 Ok(expected_len
) => ErrorKind
::Incomplete
{
46 Err(err
) => err
.kind().at(actual_len
),
50 /// Get the [`ErrorKind`] which occurred.
51 pub fn kind(self) -> ErrorKind
{
55 /// Get the position inside of the message where the error occurred.
56 pub fn position(self) -> Option
<Length
> {
60 /// For errors occurring inside of a nested message, extend the position
61 /// count by the location where the nested message occurs.
62 pub(crate) fn nested(self, nested_position
: Length
) -> Self {
63 // TODO(tarcieri): better handle length overflows occurring in this calculation?
64 let position
= (nested_position
+ self.position
.unwrap_or_default()).ok();
73 #[cfg(feature = "std")]
74 impl std
::error
::Error
for Error {}
76 impl fmt
::Display
for Error
{
77 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
78 write
!(f
, "{}", self.kind
)?
;
80 if let Some(pos
) = self.position
{
81 write
!(f
, " at DER byte {}", pos
)?
;
88 impl From
<ErrorKind
> for Error
{
89 fn from(kind
: ErrorKind
) -> Error
{
97 impl From
<Infallible
> for Error
{
98 fn from(_
: Infallible
) -> Error
{
103 impl From
<TryFromIntError
> for Error
{
104 fn from(_
: TryFromIntError
) -> Error
{
106 kind
: ErrorKind
::Overflow
,
112 impl From
<Utf8Error
> for Error
{
113 fn from(err
: Utf8Error
) -> Error
{
115 kind
: ErrorKind
::Utf8(err
),
121 #[cfg(feature = "alloc")]
122 impl From
<alloc
::string
::FromUtf8Error
> for Error
{
123 fn from(err
: alloc
::string
::FromUtf8Error
) -> Error
{
124 ErrorKind
::Utf8(err
.utf8_error()).into()
128 #[cfg(feature = "oid")]
129 impl From
<const_oid
::Error
> for Error
{
130 fn from(_
: const_oid
::Error
) -> Error
{
131 ErrorKind
::OidMalformed
.into()
135 #[cfg(feature = "pem")]
136 impl From
<pem
::Error
> for Error
{
137 fn from(err
: pem
::Error
) -> Error
{
138 ErrorKind
::Pem(err
).into()
142 #[cfg(feature = "std")]
143 impl From
<std
::io
::Error
> for Error
{
144 fn from(err
: std
::io
::Error
) -> Error
{
146 std
::io
::ErrorKind
::NotFound
=> ErrorKind
::FileNotFound
,
147 std
::io
::ErrorKind
::PermissionDenied
=> ErrorKind
::PermissionDenied
,
148 other
=> ErrorKind
::Io(other
),
154 #[cfg(feature = "time")]
155 impl From
<time
::error
::ComponentRange
> for Error
{
156 fn from(_
: time
::error
::ComponentRange
) -> Error
{
157 ErrorKind
::DateTime
.into()
162 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
165 /// Date-and-time related errors.
168 /// This error indicates a previous DER parsing operation resulted in
169 /// an error and tainted the state of a `Decoder` or `Encoder`.
171 /// Once this occurs, the overall operation has failed and cannot be
172 /// subsequently resumed.
175 /// File not found error.
176 #[cfg(feature = "std")]
177 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
180 /// Message is incomplete and does not contain all of the expected data.
182 /// Expected message length.
184 /// Note that this length represents a *minimum* lower bound on how
185 /// much additional data is needed to continue parsing the message.
187 /// It's possible upon subsequent message parsing that the parser will
188 /// discover even more data is needed.
189 expected_len
: Length
,
191 /// Actual length of the message buffer currently being processed.
196 #[cfg(feature = "std")]
197 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
198 Io(std
::io
::ErrorKind
),
200 /// Incorrect length for a given field.
202 /// Tag of the value being decoded.
206 /// Message is not canonically encoded.
208 /// Tag of the value which is not canonically encoded.
212 /// OID is improperly encoded.
217 /// This error is intended to be used by libraries which parse DER-based
218 /// formats which encounter unknown or unsupported OID libraries.
220 /// It enables passing back the OID value to the caller, which allows them
221 /// to determine which OID(s) are causing the error (and then potentially
222 /// contribute upstream support for algorithms they care about).
223 #[cfg(feature = "oid")]
224 #[cfg_attr(docsrs, doc(cfg(feature = "oid")))]
226 /// OID value that was unrecognized by a parser for a DER-based format.
227 oid
: ObjectIdentifier
,
230 /// `SET` ordering error: items not in canonical order.
233 /// Integer overflow occurred (library bug!).
236 /// Message is longer than this library's internal limits support.
239 /// PEM encoding errors.
240 #[cfg(feature = "pem")]
241 #[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
244 /// Permission denied reading file.
245 #[cfg(feature = "std")]
246 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
249 /// Reader does not support the requested operation.
252 /// Unknown tag mode.
255 /// Invalid tag number.
257 /// The "tag number" is the lower 5-bits of a tag's octet.
258 /// This error occurs in the case that all 5-bits are set to `1`,
259 /// which indicates a multi-byte tag which is unsupported by this library.
264 /// Tag the decoder was expecting (if there is a single such tag).
266 /// `None` if multiple tags are expected/allowed, but the `actual` tag
267 /// does not match any of them.
268 expected
: Option
<Tag
>,
270 /// Actual tag encountered in the message.
274 /// Unknown/unsupported tag.
276 /// Raw byte value of the tag.
280 /// Undecoded trailing data at end of message.
282 /// Length of the decoded data.
285 /// Total length of the remaining data left in the buffer.
292 /// Unexpected value.
294 /// Tag of the unexpected value.
300 /// Annotate an [`ErrorKind`] with context about where it occurred,
301 /// returning an error.
302 pub fn at(self, position
: Length
) -> Error
{
303 Error
::new(self, position
)
307 impl fmt
::Display
for ErrorKind
{
308 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
310 ErrorKind
::DateTime
=> write
!(f
, "date/time error"),
311 ErrorKind
::Failed
=> write
!(f
, "operation failed"),
312 #[cfg(feature = "std")]
313 ErrorKind
::FileNotFound
=> write
!(f
, "file not found"),
314 ErrorKind
::Incomplete
{
319 "ASN.1 DER message is incomplete: expected {}, actual {}",
320 expected_len
, actual_len
322 #[cfg(feature = "std")]
323 ErrorKind
::Io(err
) => write
!(f
, "I/O error: {:?}", err
),
324 ErrorKind
::Length { tag }
=> write
!(f
, "incorrect length for {}", tag
),
325 ErrorKind
::Noncanonical { tag }
=> {
326 write
!(f
, "ASN.1 {} not canonically encoded as DER", tag
)
328 ErrorKind
::OidMalformed
=> write
!(f
, "malformed OID"),
329 #[cfg(feature = "oid")]
330 ErrorKind
::OidUnknown { oid }
=> {
331 write
!(f
, "unknown/unsupported OID: {}", oid
)
333 ErrorKind
::SetOrdering
=> write
!(f
, "SET OF ordering error"),
334 ErrorKind
::Overflow
=> write
!(f
, "integer overflow"),
335 ErrorKind
::Overlength
=> write
!(f
, "ASN.1 DER message is too long"),
336 #[cfg(feature = "pem")]
337 ErrorKind
::Pem(e
) => write
!(f
, "PEM error: {}", e
),
338 #[cfg(feature = "std")]
339 ErrorKind
::PermissionDenied
=> write
!(f
, "permission denied"),
340 ErrorKind
::Reader
=> write
!(f
, "reader does not support the requested operation"),
341 ErrorKind
::TagModeUnknown
=> write
!(f
, "unknown tag mode"),
342 ErrorKind
::TagNumberInvalid
=> write
!(f
, "invalid tag number"),
343 ErrorKind
::TagUnexpected { expected, actual }
=> {
344 write
!(f
, "unexpected ASN.1 DER tag: ")?
;
346 if let Some(tag
) = expected
{
347 write
!(f
, "expected {}, ", tag
)?
;
350 write
!(f
, "got {}", actual
)
352 ErrorKind
::TagUnknown { byte }
=> {
353 write
!(f
, "unknown/unsupported ASN.1 DER tag: 0x{:02x}", byte
)
355 ErrorKind
::TrailingData { decoded, remaining }
=> {
358 "trailing data at end of DER message: decoded {} bytes, {} bytes remaining",
362 ErrorKind
::Utf8(e
) => write
!(f
, "{}", e
),
363 ErrorKind
::Value { tag }
=> write
!(f
, "malformed ASN.1 DER value for {}", tag
),