der/
reader.rs

1//! Reader trait.
2
3pub(crate) mod nested;
4#[cfg(feature = "pem")]
5pub(crate) mod pem;
6pub(crate) mod slice;
7
8pub(crate) use nested::NestedReader;
9
10use crate::{
11    asn1::ContextSpecific, Decode, DecodeValue, Encode, Error, ErrorKind, FixedTag, Header, Length,
12    Result, Tag, TagMode, TagNumber,
13};
14
15#[cfg(feature = "alloc")]
16use alloc::vec::Vec;
17
18/// Reader trait which reads DER-encoded input.
19pub trait Reader<'r>: Sized {
20    /// Get the length of the input.
21    fn input_len(&self) -> Length;
22
23    /// Peek at the next byte of input without modifying the cursor.
24    fn peek_byte(&self) -> Option<u8>;
25
26    /// Peek forward in the input data, attempting to decode a [`Header`] from
27    /// the data at the current position in the decoder.
28    ///
29    /// Does not modify the decoder's state.
30    fn peek_header(&self) -> Result<Header>;
31
32    /// Get the position within the buffer.
33    fn position(&self) -> Length;
34
35    /// Attempt to read data borrowed directly from the input as a slice,
36    /// updating the internal cursor position.
37    ///
38    /// # Returns
39    /// - `Ok(slice)` on success
40    /// - `Err(ErrorKind::Incomplete)` if there is not enough data
41    /// - `Err(ErrorKind::Reader)` if the reader can't borrow from the input
42    fn read_slice(&mut self, len: Length) -> Result<&'r [u8]>;
43
44    /// Attempt to decode an ASN.1 `CONTEXT-SPECIFIC` field with the
45    /// provided [`TagNumber`].
46    fn context_specific<T>(&mut self, tag_number: TagNumber, tag_mode: TagMode) -> Result<Option<T>>
47    where
48        T: DecodeValue<'r> + FixedTag,
49    {
50        Ok(match tag_mode {
51            TagMode::Explicit => ContextSpecific::<T>::decode_explicit(self, tag_number)?,
52            TagMode::Implicit => ContextSpecific::<T>::decode_implicit(self, tag_number)?,
53        }
54        .map(|field| field.value))
55    }
56
57    /// Decode a value which impls the [`Decode`] trait.
58    fn decode<T: Decode<'r>>(&mut self) -> Result<T> {
59        T::decode(self).map_err(|e| e.nested(self.position()))
60    }
61
62    /// Return an error with the given [`ErrorKind`], annotating it with
63    /// context about where the error occurred.
64    fn error(&mut self, kind: ErrorKind) -> Error {
65        kind.at(self.position())
66    }
67
68    /// Finish decoding, returning the given value if there is no
69    /// remaining data, or an error otherwise
70    fn finish<T>(self, value: T) -> Result<T> {
71        if !self.is_finished() {
72            Err(ErrorKind::TrailingData {
73                decoded: self.position(),
74                remaining: self.remaining_len(),
75            }
76            .at(self.position()))
77        } else {
78            Ok(value)
79        }
80    }
81
82    /// Have we read all of the input data?
83    fn is_finished(&self) -> bool {
84        self.remaining_len().is_zero()
85    }
86
87    /// Offset within the original input stream.
88    ///
89    /// This is used for error reporting, and doesn't need to be overridden
90    /// by any reader implementations (except for the built-in `NestedReader`,
91    /// which consumes nested input messages)
92    fn offset(&self) -> Length {
93        self.position()
94    }
95
96    /// Peek at the next byte in the decoder and attempt to decode it as a
97    /// [`Tag`] value.
98    ///
99    /// Does not modify the decoder's state.
100    fn peek_tag(&self) -> Result<Tag> {
101        match self.peek_byte() {
102            Some(byte) => byte.try_into(),
103            None => Err(Error::incomplete(self.input_len())),
104        }
105    }
106
107    /// Read a single byte.
108    fn read_byte(&mut self) -> Result<u8> {
109        let mut buf = [0];
110        self.read_into(&mut buf)?;
111        Ok(buf[0])
112    }
113
114    /// Attempt to read input data, writing it into the provided buffer, and
115    /// returning a slice on success.
116    ///
117    /// # Returns
118    /// - `Ok(slice)` if there is sufficient data
119    /// - `Err(ErrorKind::Incomplete)` if there is not enough data
120    fn read_into<'o>(&mut self, buf: &'o mut [u8]) -> Result<&'o [u8]> {
121        let input = self.read_slice(buf.len().try_into()?)?;
122        buf.copy_from_slice(input);
123        Ok(buf)
124    }
125
126    /// Read nested data of the given length.
127    fn read_nested<'n, T, F>(&'n mut self, len: Length, f: F) -> Result<T>
128    where
129        F: FnOnce(&mut NestedReader<'n, Self>) -> Result<T>,
130    {
131        let mut reader = NestedReader::new(self, len)?;
132        let ret = f(&mut reader)?;
133        reader.finish(ret)
134    }
135
136    /// Read a byte vector of the given length.
137    #[cfg(feature = "alloc")]
138    fn read_vec(&mut self, len: Length) -> Result<Vec<u8>> {
139        let mut bytes = vec![0u8; usize::try_from(len)?];
140        self.read_into(&mut bytes)?;
141        Ok(bytes)
142    }
143
144    /// Get the number of bytes still remaining in the buffer.
145    fn remaining_len(&self) -> Length {
146        debug_assert!(self.position() <= self.input_len());
147        self.input_len().saturating_sub(self.position())
148    }
149
150    /// Read an ASN.1 `SEQUENCE`, creating a nested [`Reader`] for the body and
151    /// calling the provided closure with it.
152    fn sequence<'n, F, T>(&'n mut self, f: F) -> Result<T>
153    where
154        F: FnOnce(&mut NestedReader<'n, Self>) -> Result<T>,
155    {
156        let header = Header::decode(self)?;
157        header.tag.assert_eq(Tag::Sequence)?;
158        self.read_nested(header.length, f)
159    }
160
161    /// Obtain a slice of bytes contain a complete TLV production suitable for parsing later.
162    fn tlv_bytes(&mut self) -> Result<&'r [u8]> {
163        let header = self.peek_header()?;
164        let header_len = header.encoded_len()?;
165        self.read_slice((header_len + header.length)?)
166    }
167}