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