/rust/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.10/src/reader.rs
Line | Count | Source (jump to first uncovered line) |
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. |
21 | | fn input_len(&self) -> Length; |
22 | | |
23 | | /// Peek at the next byte of input without modifying the cursor. |
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. |
30 | | fn peek_header(&self) -> Result<Header>; |
31 | | |
32 | | /// Get the position within the buffer. |
33 | | 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 |
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`]. |
46 | 0 | fn context_specific<T>(&mut self, tag_number: TagNumber, tag_mode: TagMode) -> Result<Option<T>> |
47 | 0 | where |
48 | 0 | T: DecodeValue<'r> + FixedTag, |
49 | 0 | { |
50 | 0 | Ok(match tag_mode { |
51 | 0 | TagMode::Explicit => ContextSpecific::<T>::decode_explicit(self, tag_number)?, |
52 | 0 | TagMode::Implicit => ContextSpecific::<T>::decode_implicit(self, tag_number)?, |
53 | | } |
54 | 0 | .map(|field| field.value)) |
55 | 0 | } |
56 | | |
57 | | /// Decode a value which impls the [`Decode`] trait. |
58 | 0 | fn decode<T: Decode<'r>>(&mut self) -> Result<T> { |
59 | 0 | T::decode(self).map_err(|e| e.nested(self.position())) |
60 | 0 | } |
61 | | |
62 | | /// Return an error with the given [`ErrorKind`], annotating it with |
63 | | /// context about where the error occurred. |
64 | 0 | fn error(&mut self, kind: ErrorKind) -> Error { |
65 | 0 | kind.at(self.position()) |
66 | 0 | } |
67 | | |
68 | | /// Finish decoding, returning the given value if there is no |
69 | | /// remaining data, or an error otherwise |
70 | 0 | fn finish<T>(self, value: T) -> Result<T> { |
71 | 0 | if !self.is_finished() { |
72 | 0 | Err(ErrorKind::TrailingData { |
73 | 0 | decoded: self.position(), |
74 | 0 | remaining: self.remaining_len(), |
75 | 0 | } |
76 | 0 | .at(self.position())) |
77 | | } else { |
78 | 0 | Ok(value) |
79 | | } |
80 | 0 | } |
81 | | |
82 | | /// Have we read all of the input data? |
83 | 0 | fn is_finished(&self) -> bool { |
84 | 0 | self.remaining_len().is_zero() |
85 | 0 | } |
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) |
92 | 0 | fn offset(&self) -> Length { |
93 | 0 | self.position() |
94 | 0 | } |
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. |
100 | 0 | fn peek_tag(&self) -> Result<Tag> { |
101 | 0 | match self.peek_byte() { |
102 | 0 | Some(byte) => byte.try_into(), |
103 | 0 | None => Err(Error::incomplete(self.input_len())), |
104 | | } |
105 | 0 | } |
106 | | |
107 | | /// Read a single byte. |
108 | 0 | fn read_byte(&mut self) -> Result<u8> { |
109 | 0 | let mut buf = [0]; |
110 | 0 | self.read_into(&mut buf)?; |
111 | 0 | Ok(buf[0]) |
112 | 0 | } |
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 |
120 | 0 | fn read_into<'o>(&mut self, buf: &'o mut [u8]) -> Result<&'o [u8]> { |
121 | 0 | let input = self.read_slice(buf.len().try_into()?)?; |
122 | 0 | buf.copy_from_slice(input); |
123 | 0 | Ok(buf) |
124 | 0 | } |
125 | | |
126 | | /// Read nested data of the given length. |
127 | 0 | fn read_nested<'n, T, F>(&'n mut self, len: Length, f: F) -> Result<T> |
128 | 0 | where |
129 | 0 | F: FnOnce(&mut NestedReader<'n, Self>) -> Result<T>, |
130 | 0 | { |
131 | 0 | let mut reader = NestedReader::new(self, len)?; |
132 | 0 | let ret = f(&mut reader)?; |
133 | 0 | reader.finish(ret) |
134 | 0 | } |
135 | | |
136 | | /// Read a byte vector of the given length. |
137 | | #[cfg(feature = "alloc")] |
138 | 0 | fn read_vec(&mut self, len: Length) -> Result<Vec<u8>> { |
139 | 0 | let mut bytes = vec![0u8; usize::try_from(len)?]; |
140 | 0 | self.read_into(&mut bytes)?; |
141 | 0 | Ok(bytes) |
142 | 0 | } |
143 | | |
144 | | /// Get the number of bytes still remaining in the buffer. |
145 | 0 | fn remaining_len(&self) -> Length { |
146 | 0 | debug_assert!(self.position() <= self.input_len()); |
147 | 0 | self.input_len().saturating_sub(self.position()) |
148 | 0 | } |
149 | | |
150 | | /// Read an ASN.1 `SEQUENCE`, creating a nested [`Reader`] for the body and |
151 | | /// calling the provided closure with it. |
152 | 0 | fn sequence<'n, F, T>(&'n mut self, f: F) -> Result<T> |
153 | 0 | where |
154 | 0 | F: FnOnce(&mut NestedReader<'n, Self>) -> Result<T>, |
155 | 0 | { |
156 | 0 | let header = Header::decode(self)?; |
157 | 0 | header.tag.assert_eq(Tag::Sequence)?; |
158 | 0 | self.read_nested(header.length, f) |
159 | 0 | } |
160 | | |
161 | | /// Obtain a slice of bytes contain a complete TLV production suitable for parsing later. |
162 | 0 | fn tlv_bytes(&mut self) -> Result<&'r [u8]> { |
163 | 0 | let header = self.peek_header()?; |
164 | 0 | let header_len = header.encoded_len()?; |
165 | 0 | self.read_slice((header_len + header.length)?) |
166 | 0 | } |
167 | | } |