asnfuzzgen_codecs/per/
mod.rs

1#![allow(dead_code)]
2//! ASN.1 PER Encoding
3
4pub mod error;
5
6pub mod aper;
7
8pub mod uper;
9
10mod common;
11
12pub use error::Error as PerCodecError;
13
14use bitvec::prelude::*;
15use std::convert::TryFrom;
16
17/// Structure representing an APER Codec.
18///
19/// While En(De)coding ASN.1 Types using the APER encoding scheme, the encoded data is stored in a
20/// `BitVec`.
21#[derive(Default, Debug)]
22pub struct PerCodecData {
23    bits: BitVec<u8, Msb0>,
24    decode_offset: usize,
25    key: Option<i128>,
26    aligned: bool,
27}
28
29impl PerCodecData {
30    /// Default `PerCodecData` for AperCodec
31    pub fn new_aper() -> Self {
32        Self {
33            aligned: true,
34            ..Self::default()
35        }
36    }
37
38    /// Default `PerCodecData` for UperCodec
39    pub fn new_uper() -> Self {
40        Self::default()
41    }
42
43    /// Create Our `PerCodecData` Structure from a slice of u8 for AperCodec
44    pub fn from_slice_aper(bytes: &[u8]) -> Self {
45        Self::from_slice_internal(bytes, true)
46    }
47
48    /// Create Our `PerCodecData` Structure from a slice of u8 for UperCodec
49    pub fn from_slice_uper(bytes: &[u8]) -> Self {
50        Self::from_slice_internal(bytes, false)
51    }
52
53    fn from_slice_internal(bytes: &[u8], aligned: bool) -> Self {
54        Self {
55            bits: BitSlice::<_, _>::from_slice(bytes).to_bitvec(),
56            decode_offset: 0,
57            key: None,
58            aligned,
59        }
60    }
61
62    /// Get's the inner buffer as a `Vec<u8>` consuming the struct.
63    pub fn into_bytes(self) -> Vec<u8> {
64        self.bits.into()
65    }
66
67    /// Align to 8 bit boundry during decode.
68    pub fn decode_align(&mut self) -> Result<(), PerCodecError> {
69        if self.decode_offset % 8 == 0 {
70            return Ok(());
71        }
72
73        let remaining = 8 - (self.decode_offset & 0x7_usize);
74
75        if !self.bits[self.decode_offset..self.decode_offset + remaining]
76            .iter()
77            .all(|b| b == false)
78        {
79            Err(PerCodecError::new(
80                format!(
81                    "{} Padding bits at Offset {} not all '0'.",
82                    remaining, self.decode_offset,
83                )
84                .as_str(),
85            ))
86        } else {
87            self.decode_offset += remaining;
88            Ok(())
89        }
90    }
91
92    fn decode_bool(&mut self) -> Result<bool, PerCodecError> {
93        if self.bits.len() == self.decode_offset {
94            return Err(PerCodecError::new(
95                "perCodec:DecodeError:End of Bitstream reached while trying to decode bool.",
96            ));
97        }
98        let bit = *self.bits.get(self.decode_offset).as_deref().unwrap();
99        self.advance_maybe_err(1, true)?;
100
101        Ok(bit)
102    }
103
104    fn decode_bits_as_integer(&mut self, bits: usize, signed: bool) -> Result<i128, PerCodecError> {
105        let remaining = self.bits.len() - self.decode_offset;
106        if remaining < bits {
107            //            panic!("Requested Bits thingy");
108            Err(PerCodecError::new(
109                format!(
110                    "PerCodec:DecodeError:Requested Bits to decode {}, Remaining bits {}",
111                    bits, remaining
112                )
113                .as_str(),
114            ))
115        } else {
116            let value = if !signed {
117                if bits == 0 {
118                    0_i128
119                } else if bits > 128 {
120                    return Err(PerCodecError::new(format!(
121                        "For an unsigned number, requested bits {} not supported!",
122                        bits
123                    )));
124                } else {
125                    let unsigned_value =
126                        self.bits[self.decode_offset..self.decode_offset + bits].load_be::<u128>();
127                    match i128::try_from(unsigned_value) {
128                        Ok(v) => v,
129                        Err(_) => {
130                            return Err(PerCodecError::new(format!(
131                                "Unsigned value {} exceeded signed bounds for 128-bit integer!",
132                                unsigned_value
133                            )))
134                        }
135                    }
136                }
137            } else {
138                match bits {
139                    8 => {
140                        let inner = self.bits[self.decode_offset..self.decode_offset + bits]
141                            .load_be::<u128>() as i8;
142                        inner as i128
143                    }
144                    16 => {
145                        let inner = self.bits[self.decode_offset..self.decode_offset + bits]
146                            .load_be::<u128>() as i16;
147                        inner as i128
148                    }
149                    24 => {
150                        let inner = self.bits[self.decode_offset..self.decode_offset + bits]
151                            .load_be::<u32>();
152                        let inner = if self.bits[self.decode_offset] {
153                            // Bit is 1 negative no.
154                            inner | 0xFF000000
155                        } else {
156                            inner & 0x00FFFFFF
157                        };
158                        let inner = inner as i32;
159                        inner as i128
160                    }
161                    32 => {
162                        let inner = self.bits[self.decode_offset..self.decode_offset + bits]
163                            .load_be::<u128>() as i32;
164                        inner as i128
165                    }
166                    40 => {
167                        let inner = self.bits[self.decode_offset..self.decode_offset + bits]
168                            .load_be::<u64>();
169                        let inner = if self.bits[self.decode_offset] {
170                            // Bit is 1 negative no.
171                            inner | 0xFFFFFF0000000000
172                        } else {
173                            inner & 0x000000FFFFFFFFFF
174                        };
175                        let inner = inner as i64;
176                        inner as i128
177                    }
178                    48 => {
179                        let inner = self.bits[self.decode_offset..self.decode_offset + bits]
180                            .load_be::<u64>();
181                        let inner = if self.bits[self.decode_offset] {
182                            // Bit is 1 negative no.
183                            inner | 0xFFFF000000000000
184                        } else {
185                            inner & 0x0000FFFFFFFFFFFF
186                        };
187                        let inner = inner as i64;
188                        inner as i128
189                    }
190                    56 => {
191                        let inner = self.bits[self.decode_offset..self.decode_offset + bits]
192                            .load_be::<u64>();
193                        let inner = if self.bits[self.decode_offset] {
194                            // Bit is 1 negative no.
195                            inner | 0xFF00000000000000
196                        } else {
197                            inner & 0x00FFFFFFFFFFFFFF
198                        };
199                        let inner = inner as i64;
200                        inner as i128
201                    }
202                    64 => {
203                        let inner = self.bits[self.decode_offset..self.decode_offset + bits]
204                            .load_be::<u128>() as i64;
205                        inner as i128
206                    }
207                    128 => {
208                        let inner = self.bits[self.decode_offset..self.decode_offset + bits]
209                            .load_be::<u128>();
210                        inner as i128
211                    }
212                    _ => {
213                        return Err(
214                            PerCodecError::new(
215                                format!(
216                                    "For a signed number in 2's compliment form, requested bits {} not supported!",
217                                    bits)));
218                    }
219                }
220            };
221            self.advance_maybe_err(bits, false)?;
222            Ok(value)
223        }
224    }
225
226    /// Advance the decode offset by a given number of bits.
227    /// If there are not enough bits remaining, the behaviour depends on the `ignore` argument.
228    /// -  If `true`, the offset is advanced to the end of the buffer, and Ok is returned.
229    /// -  If `false`, the offset is left unchanged, and Err is returned.
230    pub fn advance_maybe_err(&mut self, bits: usize, ignore: bool) -> Result<(), PerCodecError> {
231        let offset = self.decode_offset + bits;
232        if offset > self.bits.len() {
233            if ignore {
234                self.decode_offset = self.bits.len()
235            } else {
236                let remaining = self.bits.len() - self.decode_offset;
237                return Err(PerCodecError::new(
238                    format!(
239                        "PerCodec:DecodeError:Requested Bits to advance {}, Remaining bits {}",
240                        bits, remaining
241                    )
242                    .as_str(),
243                ));
244            }
245        } else {
246            self.decode_offset = offset
247        }
248        Ok(())
249    }
250
251    fn get_bit(&self) -> Result<bool, PerCodecError> {
252        if self.decode_offset >= self.bits.len() {
253            return Err(PerCodecError::new(
254                format!(
255                    "PerCodec:GetBitError:Requested Bit {}, Remaining bits {}",
256                    self.decode_offset,
257                    self.bits.len() - self.decode_offset
258                )
259                .as_str(),
260            ));
261        }
262        let bit = *self.bits.get(self.decode_offset).as_deref().unwrap();
263        Ok(bit)
264    }
265
266    fn get_bitvec(&mut self, length: usize) -> Result<BitVec<u8, Msb0>, PerCodecError> {
267        if length + self.decode_offset > self.bits.len() {
268            return Err(PerCodecError::new(
269                format!(
270                    "PerCodec:GetBitError:Requested Bit {}, Remaining bits {}",
271                    length,
272                    self.bits.len() - self.decode_offset
273                )
274                .as_str(),
275            ));
276        }
277        let bv = BitVec::from_bitslice(&self.bits[self.decode_offset..self.decode_offset + length]);
278        self.advance_maybe_err(length, true)?;
279
280        Ok(bv)
281    }
282
283    fn get_bytes(&mut self, length: usize) -> Result<Vec<u8>, PerCodecError> {
284        let length = length * 8;
285        if length + self.decode_offset > self.bits.len() {
286            return Err(PerCodecError::new(
287                format!(
288                    "PerCodec:GetBitError:Requested Bits {}, Remaining bits {}",
289                    length,
290                    self.bits.len() - self.decode_offset
291                )
292                .as_str(),
293            ));
294        }
295        let mut bv = self.bits[self.decode_offset..self.decode_offset + length].to_bitvec();
296        bv.force_align();
297        self.advance_maybe_err(length, true)?;
298        Ok(BitVec::into_vec(bv))
299    }
300
301    pub fn get_inner(&self) -> Result<Vec<u8>, PerCodecError> {
302        Ok(BitVec::into_vec(self.bits.to_bitvec()))
303    }
304
305    /// Get's the current `key` value.
306    ///
307    /// This value will be used by a decoder to determine which 'decode' function is to be called
308    /// (for example in an `enum`, it will be used to determine which `variant` of the `enum` will
309    /// be decoded.
310    pub fn get_key(&self) -> Option<i128> {
311        self.key
312    }
313
314    /// Sets the current `key` value.
315    ///
316    /// During decoding 'open' types, the 'key' used to decode the type further is determined by a
317    /// `key_value` field. ie. a field with attribute `key_value` set in a struct (derived from a
318    /// SEQUENCE ASN.1 type.) This value is passed to the 'decoder' logic further through `set_key`
319    /// function, which updates the internal state of the decoder data.
320    pub fn set_key(&mut self, key: i128) {
321        let _ = self.key.replace(key);
322    }
323
324    /// Dump current 'offset'.
325    #[inline]
326    pub fn dump(&self) {
327    }
328
329    #[inline]
330    pub fn dump_encode(&self) {
331    }
332
333    /// Reserve certain bits at the current `offset`.
334    #[inline]
335    pub fn reserve(&mut self, count: usize) {
336        self.bits.reserve(count);
337        self.decode_offset = count;
338    }
339
340    /// `seek` pointer to the offset in the internal buffer
341    #[inline]
342    pub fn seek(&mut self, offset: usize) {
343        self.decode_offset = offset;
344    }
345
346    pub fn swap_bits(&mut self, other: &mut BitSlice<u8, Msb0>, offset: usize) {
347        self.bits[offset..other.len() + offset].swap_with_bitslice(other);
348    }
349
350    pub fn set_bit(&mut self, index: usize, value: bool) {
351        self.bits.set(index, value);
352    }
353    // Encoding functions.
354
355    /// Encode a bool.
356    fn encode_bool(&mut self, value: bool) {
357        self.bits.push(value);
358    }
359
360    /// Add bits to the encoding buffer.
361    fn append_bits(&mut self, bits: &BitSlice<u8, Msb0>) {
362        self.bits.extend_from_bitslice(bits);
363    }
364
365    /// Byte align the encoding buffer by padding with zero bits.
366    fn align(&mut self) {
367        let remaining = 8 - (self.bits.len() & 0x7_usize);
368        if remaining < 8 {
369            self.bits.resize(self.bits.len() + remaining, false);
370        }
371    }
372
373    /// Get the length of the data in bytes
374    /// This is useful when encoding an open type.
375    pub fn length_in_bytes(&self) -> usize {
376        (self.bits.len() + 7) / 8
377    }
378
379    /// Append one encoding to another preserving byte alignment.
380    /// This is useful when encoding an open type.
381    pub fn append_aligned(&mut self, other: &mut Self) {
382        self.align();
383        other.align();
384        self.append_bits(&other.bits)
385    }
386}