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