1use super::{Tag, Length};
4use crate::error::{BerError, Result};
5
6#[derive(Debug)]
8pub struct BerReader<'a> {
9 data: &'a [u8],
10 pos: usize,
11}
12
13impl<'a> BerReader<'a> {
14 pub fn new(data: &'a [u8]) -> Self {
16 BerReader { data, pos: 0 }
17 }
18
19 pub fn position(&self) -> usize {
21 self.pos
22 }
23
24 pub fn remaining(&self) -> &[u8] {
26 &self.data[self.pos..]
27 }
28
29 pub fn has_more(&self) -> bool {
31 self.pos < self.data.len()
32 }
33
34 pub fn peek_tag(&self) -> Result<Tag> {
36 let (tag, _) = Tag::decode(self.remaining())?;
37 Ok(tag)
38 }
39
40 pub fn read_tag(&mut self) -> Result<Tag> {
42 let (tag, len) = Tag::decode(self.remaining())?;
43 self.pos += len;
44 Ok(tag)
45 }
46
47 pub fn read_length(&mut self) -> Result<Length> {
49 let (length, len) = Length::decode(self.remaining())?;
50 self.pos += len;
51 Ok(length)
52 }
53
54 pub fn read_bytes(&mut self, count: usize) -> Result<&'a [u8]> {
56 if self.pos + count > self.data.len() {
57 return Err(BerError::UnexpectedEof.into());
58 }
59 let bytes = &self.data[self.pos..self.pos + count];
60 self.pos += count;
61 Ok(bytes)
62 }
63
64 pub fn read_tlv(&mut self) -> Result<(Tag, &'a [u8])> {
66 let tag = self.read_tag()?;
67 let length = self.read_length()?;
68
69 let value = match length {
70 Length::Definite(len) => self.read_bytes(len)?,
71 Length::Indefinite => {
72 let start = self.pos;
74 loop {
75 if self.pos + 1 >= self.data.len() {
76 return Err(BerError::UnexpectedEof.into());
77 }
78 if self.data[self.pos] == 0x00 && self.data[self.pos + 1] == 0x00 {
79 let value = &self.data[start..self.pos];
80 self.pos += 2; break value;
82 }
83 self.pos += 1;
84 }
85 }
86 };
87
88 Ok((tag, value))
89 }
90
91 pub fn read_boolean(&mut self) -> Result<bool> {
93 let (tag, value) = self.read_tlv()?;
94
95 if tag != Tag::BOOLEAN {
96 return Err(BerError::InvalidTag(format!(
97 "expected BOOLEAN tag, got {:?}", tag
98 )).into());
99 }
100
101 if value.len() != 1 {
102 return Err(BerError::invalid_value(
103 "BOOLEAN",
104 format!("expected 1 byte, got {}", value.len())
105 ).into());
106 }
107
108 Ok(value[0] != 0)
109 }
110
111 pub fn read_integer(&mut self) -> Result<i64> {
113 let (tag, value) = self.read_tlv()?;
114
115 if tag != Tag::INTEGER {
116 return Err(BerError::InvalidTag(format!(
117 "expected INTEGER tag, got {:?}", tag
118 )).into());
119 }
120
121 Self::decode_integer(value)
122 }
123
124 pub fn read_context_integer(&mut self, expected_tag: u32) -> Result<i64> {
126 let (tag, value) = self.read_tlv()?;
127
128 if !tag.is_context() || tag.number != expected_tag {
129 return Err(BerError::InvalidTag(format!(
130 "expected context tag [{}], got {:?}", expected_tag, tag
131 )).into());
132 }
133
134 if !value.is_empty() && value[0] == Tag::INTEGER.encode()[0] {
136 let mut inner = BerReader::new(value);
137 inner.read_integer()
138 } else {
139 Self::decode_integer(value)
140 }
141 }
142
143 fn decode_integer(value: &[u8]) -> Result<i64> {
145 if value.is_empty() {
146 return Err(BerError::invalid_value(
147 "INTEGER",
148 "empty value"
149 ).into());
150 }
151
152 if value.len() > 8 {
153 return Err(BerError::invalid_value(
154 "INTEGER",
155 format!("value too large: {} bytes", value.len())
156 ).into());
157 }
158
159 let negative = (value[0] & 0x80) != 0;
161 let mut result: i64 = if negative { -1 } else { 0 };
162
163 for &byte in value {
164 result = (result << 8) | (byte as i64);
165 }
166
167 Ok(result)
168 }
169
170 pub fn read_real(&mut self) -> Result<f64> {
172 let (tag, value) = self.read_tlv()?;
173
174 if tag != Tag::REAL {
175 return Err(BerError::InvalidTag(format!(
176 "expected REAL tag, got {:?}", tag
177 )).into());
178 }
179
180 Self::decode_real(value)
181 }
182
183 fn decode_real(value: &[u8]) -> Result<f64> {
185 if value.is_empty() {
186 return Ok(0.0);
187 }
188
189 let first_byte = value[0];
190
191 if first_byte == 0x40 {
193 return Ok(f64::INFINITY);
194 }
195 if first_byte == 0x41 {
196 return Ok(f64::NEG_INFINITY);
197 }
198 if first_byte == 0x42 {
199 return Ok(f64::NAN);
200 }
201 if first_byte == 0x43 {
202 return Ok(-0.0);
203 }
204
205 if (first_byte & 0x80) != 0 {
207 let sign: f64 = if (first_byte & 0x40) != 0 { -1.0 } else { 1.0 };
208 let base: f64 = match (first_byte >> 4) & 0x03 {
209 0 => 2.0,
210 1 => 8.0,
211 2 => 16.0,
212 _ => return Err(BerError::invalid_value("REAL", "invalid base").into()),
213 };
214 let scale_factor = (first_byte >> 2) & 0x03;
215 let exponent_length = match first_byte & 0x03 {
216 0 => 1,
217 1 => 2,
218 2 => 3,
219 3 => value.get(1).copied().unwrap_or(0) as usize,
220 _ => unreachable!(),
221 };
222
223 let exp_start = if (first_byte & 0x03) == 3 { 2 } else { 1 };
224 if value.len() < exp_start + exponent_length {
225 return Err(BerError::invalid_value("REAL", "truncated exponent").into());
226 }
227
228 let exp_bytes = &value[exp_start..exp_start + exponent_length];
229 let mut exponent: i64 = if !exp_bytes.is_empty() && (exp_bytes[0] & 0x80) != 0 {
230 -1
231 } else {
232 0
233 };
234 for &b in exp_bytes {
235 exponent = (exponent << 8) | (b as i64);
236 }
237
238 let mantissa_start = exp_start + exponent_length;
239 let mantissa_bytes = &value[mantissa_start..];
240 let mut mantissa: u64 = 0;
241 for &b in mantissa_bytes {
242 mantissa = (mantissa << 8) | (b as u64);
243 }
244
245 let scaled_mantissa = (mantissa as f64) * (1 << scale_factor) as f64;
246 let result = sign * scaled_mantissa * base.powi(exponent as i32);
247
248 return Ok(result);
249 }
250
251 if (first_byte & 0xC0) == 0 {
253 let s = std::str::from_utf8(&value[1..])
254 .map_err(|_| BerError::invalid_value("REAL", "invalid decimal string"))?;
255 return s.trim().parse::<f64>()
256 .map_err(|_| BerError::invalid_value("REAL", "invalid decimal value").into());
257 }
258
259 Err(BerError::invalid_value("REAL", "unsupported encoding").into())
260 }
261
262 pub fn read_utf8_string(&mut self) -> Result<String> {
264 let (tag, value) = self.read_tlv()?;
265
266 if tag != Tag::UTF8_STRING {
267 return Err(BerError::InvalidTag(format!(
268 "expected UTF8String tag, got {:?}", tag
269 )).into());
270 }
271
272 Ok(String::from_utf8(value.to_vec())?)
273 }
274
275 pub fn read_octet_string(&mut self) -> Result<Vec<u8>> {
277 let (tag, value) = self.read_tlv()?;
278
279 if tag != Tag::OCTET_STRING {
280 return Err(BerError::InvalidTag(format!(
281 "expected OCTET STRING tag, got {:?}", tag
282 )).into());
283 }
284
285 Ok(value.to_vec())
286 }
287
288 pub fn read_sequence(&mut self) -> Result<BerReader<'a>> {
290 let (tag, value) = self.read_tlv()?;
291
292 if tag != Tag::SEQUENCE {
293 return Err(BerError::InvalidTag(format!(
294 "expected SEQUENCE tag, got {:?}", tag
295 )).into());
296 }
297
298 Ok(BerReader::new(value))
299 }
300
301 pub fn read_context(&mut self, expected_tag: u32) -> Result<BerReader<'a>> {
303 let (tag, value) = self.read_tlv()?;
304
305 if !tag.is_context() || tag.number != expected_tag {
306 return Err(BerError::InvalidTag(format!(
307 "expected context tag [{}], got {:?}", expected_tag, tag
308 )).into());
309 }
310
311 Ok(BerReader::new(value))
312 }
313
314 pub fn read_application(&mut self, expected_tag: u32) -> Result<BerReader<'a>> {
316 let (tag, value) = self.read_tlv()?;
317
318 if !tag.is_application() || tag.number != expected_tag {
319 return Err(BerError::InvalidTag(format!(
320 "expected application tag [{}], got {:?}", expected_tag, tag
321 )).into());
322 }
323
324 Ok(BerReader::new(value))
325 }
326
327 pub fn skip(&mut self) -> Result<()> {
329 let _ = self.read_tlv()?;
330 Ok(())
331 }
332
333 pub fn read_relative_oid(&mut self) -> Result<Vec<u32>> {
335 let (tag, value) = self.read_tlv()?;
336
337 if tag != Tag::RELATIVE_OID {
338 return Err(BerError::InvalidTag(format!(
339 "expected RELATIVE-OID tag, got {:?}", tag
340 )).into());
341 }
342
343 let mut components = Vec::new();
344 let mut current: u32 = 0;
345
346 for &byte in value {
347 current = current
348 .checked_shl(7)
349 .ok_or(BerError::LengthOverflow)?
350 .checked_add((byte & 0x7F) as u32)
351 .ok_or(BerError::LengthOverflow)?;
352
353 if (byte & 0x80) == 0 {
354 components.push(current);
355 current = 0;
356 }
357 }
358
359 Ok(components)
360 }
361}