Skip to main content

der/
reader.rs

1//! Reader trait.
2
3#[cfg(feature = "pem")]
4pub(crate) mod pem;
5pub(crate) mod slice;
6
7mod position;
8
9use crate::{
10    Decode, DecodeValue, Encode, EncodingRules, Error, ErrorKind, FixedTag, Header, Length, Tag,
11    TagMode, TagNumber, asn1::ContextSpecific,
12};
13
14#[cfg(feature = "alloc")]
15use alloc::vec::Vec;
16
17#[cfg(feature = "ber")]
18use crate::length::indefinite::read_eoc;
19
20/// Reader trait which reads DER-encoded input.
21pub trait Reader<'r>: Clone {
22    /// Does this reader support the `read_slice` method? (i.e. can it borrow from his input?)
23    const CAN_READ_SLICE: bool;
24
25    /// Get the [`EncodingRules`] which should be applied when decoding the input.
26    fn encoding_rules(&self) -> EncodingRules;
27
28    /// Get the length of the input.
29    fn input_len(&self) -> Length;
30
31    /// Get the position within the buffer.
32    fn position(&self) -> Length;
33
34    /// Read nested data of the given length.
35    ///
36    /// # Errors
37    /// If `f` returns an error.
38    fn read_nested<T, F, E>(&mut self, len: Length, f: F) -> Result<T, E>
39    where
40        E: From<Error>,
41        F: FnOnce(&mut Self) -> Result<T, E>;
42
43    /// Attempt to read data borrowed directly from the input as a slice,
44    /// updating the internal cursor position.
45    ///
46    /// # Errors
47    /// - `Err(ErrorKind::Incomplete)` if there is not enough data
48    /// - `Err(ErrorKind::Reader)` if the reader can't borrow from the input
49    fn read_slice(&mut self, len: Length) -> Result<&'r [u8], Error>;
50
51    /// Attempt to decode an ASN.1 `CONTEXT-SPECIFIC` field with the
52    /// provided [`TagNumber`].
53    ///
54    /// # Errors
55    /// If a decoding error occurred.
56    fn context_specific<T>(
57        &mut self,
58        tag_number: TagNumber,
59        tag_mode: TagMode,
60    ) -> Result<Option<T>, T::Error>
61    where
62        T: DecodeValue<'r> + FixedTag + 'r,
63    {
64        Ok(match tag_mode {
65            TagMode::Explicit => ContextSpecific::<T>::decode_explicit(self, tag_number)?,
66            TagMode::Implicit => ContextSpecific::<T>::decode_implicit(self, tag_number)?,
67        }
68        .map(|field| field.value))
69    }
70
71    /// Decode a value which impls the [`Decode`] trait.
72    ///
73    /// # Errors
74    /// Returns `T::Error` if a decoding error occurred.
75    fn decode<T: Decode<'r>>(&mut self) -> Result<T, T::Error> {
76        T::decode(self)
77    }
78
79    /// Drain the given amount of data from the reader, discarding it.
80    ///
81    /// # Errors
82    /// If an error occurred reading the given `amount` of data.
83    fn drain(&mut self, mut amount: Length) -> Result<(), Error> {
84        const BUFFER_SIZE: usize = 16;
85        let mut buffer = [0u8; BUFFER_SIZE];
86
87        while amount > Length::ZERO {
88            let amount_usize = usize::try_from(amount)?;
89
90            let nbytes_drained = if amount_usize >= BUFFER_SIZE {
91                self.read_into(&mut buffer)?;
92                Length::try_from(BUFFER_SIZE)?
93            } else {
94                self.read_into(&mut buffer[..amount_usize])?;
95                amount
96            };
97
98            amount = (amount - nbytes_drained)?;
99        }
100
101        Ok(())
102    }
103
104    /// Return an error with the given [`ErrorKind`], annotating it with
105    /// context about where the error occurred.
106    fn error(&mut self, kind: ErrorKind) -> Error {
107        kind.at(self.position())
108    }
109
110    /// Finish decoding, returning `Ok(())` if there is no
111    /// remaining data, or an error otherwise.
112    ///
113    /// # Errors
114    /// If there is trailing data remaining in the reader.
115    fn finish(self) -> Result<(), Error> {
116        if !self.is_finished() {
117            Err(ErrorKind::TrailingData {
118                decoded: self.position(),
119                remaining: self.remaining_len(),
120            }
121            .at(self.position()))
122        } else {
123            Ok(())
124        }
125    }
126
127    /// Have we read all input data?
128    fn is_finished(&self) -> bool {
129        self.remaining_len().is_zero()
130    }
131
132    /// Offset within the original input stream.
133    ///
134    /// This is used for error reporting, and doesn't need to be overridden
135    /// by any reader implementations (except for the built-in `NestedReader`,
136    /// which consumes nested input messages)
137    fn offset(&self) -> Length {
138        self.position()
139    }
140
141    /// Peek at the next byte of input without modifying the cursor.
142    fn peek_byte(&self) -> Option<u8> {
143        let mut byte = [0];
144        self.peek_into(&mut byte).ok().map(|_| byte[0])
145    }
146
147    /// Peek at the decoded data without updating the internal state, writing into the provided
148    /// output buffer. Attempts to fill the entire buffer.
149    ///
150    /// # Errors
151    /// If there is not enough data.
152    fn peek_into(&self, buf: &mut [u8]) -> Result<(), Error> {
153        let mut reader = self.clone();
154        reader.read_into(buf)?;
155        Ok(())
156    }
157
158    /// Peek forward in the input data, attempting to decode a [`Header`] from
159    /// the data at the current position in the decoder.
160    ///
161    /// Does not modify the decoder's state.
162    ///
163    /// # Errors
164    /// If [`Header::peek`] returns an error.
165    #[deprecated(since = "0.8.0", note = "use `Header::peek` instead")]
166    fn peek_header(&self) -> Result<Header, Error> {
167        Header::peek(self)
168    }
169
170    /// Peek at the next tag in the reader.
171    ///
172    /// # Errors
173    /// If [`Tag::peek`] returns an error.
174    #[deprecated(since = "0.8.0", note = "use `Tag::peek` instead")]
175    fn peek_tag(&self) -> Result<Tag, Error> {
176        Tag::peek(self)
177    }
178
179    /// Read a single byte.
180    ///
181    /// # Errors
182    /// If the byte could not be read.
183    fn read_byte(&mut self) -> Result<u8, Error> {
184        let mut buf = [0];
185        self.read_into(&mut buf)?;
186        Ok(buf[0])
187    }
188
189    /// Attempt to read input data, writing it into the provided buffer, and
190    /// returning a slice on success.
191    ///
192    /// # Errors
193    /// - `ErrorKind::Incomplete` if there is not enough data
194    fn read_into<'o>(&mut self, buf: &'o mut [u8]) -> Result<&'o [u8], Error> {
195        let input = self.read_slice(buf.len().try_into()?)?;
196        buf.copy_from_slice(input);
197        Ok(buf)
198    }
199
200    /// Read a byte vector of the given length.
201    ///
202    /// # Errors
203    /// If a read error occurred.
204    #[cfg(feature = "alloc")]
205    fn read_vec(&mut self, len: Length) -> Result<Vec<u8>, Error> {
206        let mut bytes = vec![0u8; usize::try_from(len)?];
207        self.read_into(&mut bytes)?;
208        Ok(bytes)
209    }
210
211    /// Get the number of bytes still remaining in the buffer.
212    fn remaining_len(&self) -> Length {
213        debug_assert!(self.position() <= self.input_len());
214        self.input_len().saturating_sub(self.position())
215    }
216
217    /// Read an ASN.1 `SEQUENCE`, creating a nested [`Reader`] for the body and
218    /// calling the provided closure with it.
219    ///
220    /// # Errors
221    /// If `f` returns an error, or if a decoding error occurred.
222    fn sequence<F, T, E>(&mut self, f: F) -> Result<T, E>
223    where
224        F: FnOnce(&mut Self) -> Result<T, E>,
225        E: From<Error>,
226    {
227        let header = Header::decode(self)?;
228        header.tag().assert_eq(Tag::Sequence)?;
229        read_value(self, header, |r, _| f(r))
230    }
231
232    /// Obtain a slice of bytes containing a complete TLV production suitable for parsing later.
233    ///
234    /// # Errors
235    /// If a decoding error occurred, or a length calculation overflowed.
236    fn tlv_bytes(&mut self) -> Result<&'r [u8], Error> {
237        let header = Header::peek(self)?;
238        let header_len = header.encoded_len()?;
239        self.read_slice((header_len + header.length())?)
240    }
241}
242
243/// Read a value (i.e. the "V" part of a "TLV" field) using the provided header.
244///
245/// This calls the provided function `f` with a nested reader created using
246/// [`Reader::read_nested`].
247pub(crate) fn read_value<'r, R, T, F, E>(reader: &mut R, header: Header, f: F) -> Result<T, E>
248where
249    R: Reader<'r>,
250    E: From<Error>,
251    F: FnOnce(&mut R, Header) -> Result<T, E>,
252{
253    #[cfg(feature = "ber")]
254    let header = header.with_length(header.length().sans_eoc());
255
256    let ret = reader.read_nested(header.length(), |r| f(r, header))?;
257
258    // Consume EOC marker if the length is indefinite.
259    #[cfg(feature = "ber")]
260    if header.length().is_indefinite() {
261        read_eoc(reader)?;
262    }
263
264    Ok(ret)
265}