1 //! Reader trait.
2 
3 pub(crate) mod nested;
4 #[cfg(feature = "pem")]
5 pub(crate) mod pem;
6 pub(crate) mod slice;
7 
8 pub(crate) use nested::NestedReader;
9 
10 use crate::{
11     asn1::ContextSpecific, Decode, DecodeValue, Encode, Error, ErrorKind, FixedTag, Header, Length,
12     Result, Tag, TagMode, TagNumber,
13 };
14 
15 #[cfg(feature = "alloc")]
16 use alloc::vec::Vec;
17 
18 /// Reader trait which reads DER-encoded input.
19 pub trait Reader<'r>: Sized {
20     /// Get the length of the input.
input_len(&self) -> Length21     fn input_len(&self) -> Length;
22 
23     /// Peek at the next byte of input without modifying the cursor.
peek_byte(&self) -> Option<u8>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.
peek_header(&self) -> Result<Header>30     fn peek_header(&self) -> Result<Header>;
31 
32     /// Get the position within the buffer.
position(&self) -> Length33     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
read_slice(&mut self, len: Length) -> Result<&'r [u8]>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`].
context_specific<T>(&mut self, tag_number: TagNumber, tag_mode: TagMode) -> Result<Option<T>> where T: DecodeValue<'r> + FixedTag,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.
decode<T: Decode<'r>>(&mut self) -> Result<T>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.
error(&mut self, kind: ErrorKind) -> Error64     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
finish<T>(self, value: T) -> Result<T>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?
is_finished(&self) -> bool83     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)
offset(&self) -> Length92     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.
peek_tag(&self) -> Result<Tag>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.
read_byte(&mut self) -> Result<u8>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
read_into<'o>(&mut self, buf: &'o mut [u8]) -> Result<&'o [u8]>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.
read_nested<'n, T, F>(&'n mut self, len: Length, f: F) -> Result<T> where F: FnOnce(&mut NestedReader<'n, Self>) -> Result<T>,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")]
read_vec(&mut self, len: Length) -> Result<Vec<u8>>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.
remaining_len(&self) -> Length145     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.
sequence<'n, F, T>(&'n mut self, f: F) -> Result<T> where F: FnOnce(&mut NestedReader<'n, Self>) -> Result<T>,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.
tlv_bytes(&mut self) -> Result<&'r [u8]>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 }
168