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}