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}