Skip to main content

der/
reader.rs

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