]> git.proxmox.com Git - rustc.git/blob - vendor/der/src/reader.rs
New upstream version 1.70.0+dfsg2
[rustc.git] / vendor / der / src / reader.rs
1 //! Reader trait.
2
3 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 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.
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.
64 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
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?
83 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)
92 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.
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.
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
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.
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")]
138 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
139 fn read_vec(&mut self, len: Length) -> Result<Vec<u8>> {
140 let mut bytes = vec![0u8; usize::try_from(len)?];
141 self.read_into(&mut bytes)?;
142 Ok(bytes)
143 }
144
145 /// Get the number of bytes still remaining in the buffer.
146 fn remaining_len(&self) -> Length {
147 debug_assert!(self.position() <= self.input_len());
148 self.input_len().saturating_sub(self.position())
149 }
150
151 /// Read an ASN.1 `SEQUENCE`, creating a nested [`Reader`] for the body and
152 /// calling the provided closure with it.
153 fn sequence<'n, F, T>(&'n mut self, f: F) -> Result<T>
154 where
155 F: FnOnce(&mut NestedReader<'n, Self>) -> Result<T>,
156 {
157 let header = Header::decode(self)?;
158 header.tag.assert_eq(Tag::Sequence)?;
159 self.read_nested(header.length, f)
160 }
161
162 /// Obtain a slice of bytes contain a complete TLV production suitable for parsing later.
163 fn tlv_bytes(&mut self) -> Result<&'r [u8]> {
164 let header = self.peek_header()?;
165 let header_len = header.encoded_len()?;
166 self.read_slice((header_len + header.length)?)
167 }
168 }