der/reader/
pem.rs
1use super::Reader;
4use crate::{Decode, Error, ErrorKind, Header, Length, Result};
5use core::cell::RefCell;
6
7#[allow(clippy::integer_arithmetic)]
8mod utils {
9 use crate::{Error, Length, Result};
10 use pem_rfc7468::Decoder;
11
12 #[derive(Clone)]
13 pub(super) struct BufReader<'i> {
14 decoder: Decoder<'i>,
16
17 remaining: usize,
19
20 buf: [u8; BufReader::CAPACITY],
22
23 pos: usize,
25
26 cap: usize,
28 }
29
30 impl<'i> BufReader<'i> {
31 const CAPACITY: usize = 256;
32
33 pub fn new(pem: &'i [u8]) -> Result<Self> {
34 let decoder = Decoder::new(pem)?;
35 let remaining = decoder.remaining_len();
36
37 Ok(Self {
38 decoder,
39 remaining,
40 buf: [0u8; 256],
41 pos: 0,
42 cap: 0,
43 })
44 }
45
46 pub fn remaining_len(&self) -> usize {
47 self.decoder.remaining_len() + self.cap - self.pos
48 }
49
50 fn fill_buffer(&mut self) -> Result<()> {
51 debug_assert!(self.pos <= self.cap);
52
53 if self.is_empty() {
54 self.pos = 0;
55 self.cap = 0;
56 }
57
58 let end = (self.cap + self.remaining).min(Self::CAPACITY);
59 let writable_slice = &mut self.buf[self.cap..end];
60 if writable_slice.is_empty() {
61 return Ok(());
62 }
63
64 let wrote = self.decoder.decode(writable_slice)?.len();
65 if wrote == 0 {
66 return Err(Error::incomplete(Length::try_from(self.pos)?));
67 }
68
69 self.cap += wrote;
70 self.remaining -= wrote;
71 debug_assert!(self.cap <= Self::CAPACITY);
72
73 Ok(())
74 }
75
76 pub fn type_label(&self) -> &'i str {
79 self.decoder.type_label()
80 }
81
82 fn is_empty(&self) -> bool {
83 self.pos == self.cap
84 }
85
86 fn as_slice(&self) -> &[u8] {
87 &self.buf[self.pos..self.cap]
88 }
89 }
90
91 impl<'i> BufReader<'i> {
92 pub fn peek_byte(&self) -> Option<u8> {
93 let s = self.as_slice();
94 s.first().copied()
95 }
96
97 pub fn copy_to_slice<'o>(&mut self, buf: &'o mut [u8]) -> Result<&'o [u8]> {
98 let mut output_pos = 0;
99
100 while output_pos < buf.len() {
101 if self.is_empty() {
102 self.fill_buffer()?;
103 }
104
105 let available = &self.buf[self.pos..self.cap];
106 let window_len = (buf.len() - output_pos).min(available.len());
107 let window = &mut buf[output_pos..output_pos + window_len];
108
109 window.copy_from_slice(&available[..window_len]);
110 self.pos += window_len;
111 output_pos += window_len;
112 }
113
114 if self.is_empty() && self.decoder.remaining_len() != 0 {
116 self.fill_buffer()?
117 }
118
119 debug_assert_eq!(output_pos, buf.len());
120
121 Ok(buf)
122 }
123 }
124}
125
126#[cfg(feature = "pem")]
128#[derive(Clone)]
129pub struct PemReader<'i> {
130 reader: RefCell<utils::BufReader<'i>>,
132
133 input_len: Length,
135
136 position: Length,
138}
139
140#[cfg(feature = "pem")]
141impl<'i> PemReader<'i> {
142 pub fn new(pem: &'i [u8]) -> Result<Self> {
146 let reader = utils::BufReader::new(pem)?;
147 let input_len = Length::try_from(reader.remaining_len())?;
148
149 Ok(Self {
150 reader: RefCell::new(reader),
151 input_len,
152 position: Length::ZERO,
153 })
154 }
155
156 pub fn type_label(&self) -> &'i str {
159 self.reader.borrow().type_label()
160 }
161}
162
163#[cfg(feature = "pem")]
164impl<'i> Reader<'i> for PemReader<'i> {
165 fn input_len(&self) -> Length {
166 self.input_len
167 }
168
169 fn peek_byte(&self) -> Option<u8> {
170 if self.is_finished() {
171 None
172 } else {
173 self.reader.borrow().peek_byte()
174 }
175 }
176
177 fn peek_header(&self) -> Result<Header> {
178 if self.is_finished() {
179 Err(Error::incomplete(self.offset()))
180 } else {
181 Header::decode(&mut self.clone())
182 }
183 }
184
185 fn position(&self) -> Length {
186 self.position
187 }
188
189 fn read_slice(&mut self, _len: Length) -> Result<&'i [u8]> {
190 Err(ErrorKind::Reader.into())
192 }
193
194 fn read_into<'o>(&mut self, buf: &'o mut [u8]) -> Result<&'o [u8]> {
195 let bytes = self.reader.borrow_mut().copy_to_slice(buf)?;
196
197 self.position = (self.position + bytes.len())?;
198
199 debug_assert_eq!(
200 self.position,
201 (self.input_len - Length::try_from(self.reader.borrow().remaining_len())?)?
202 );
203
204 Ok(bytes)
205 }
206}