asn1_rs/asn1_types/
bitstring.rs

1use crate::*;
2use bitvec::order::Msb0;
3use bitvec::slice::BitSlice;
4use bitvec::vec::BitVec;
5
6const BITSTRING_MAX_RECURSION: usize = 5;
7
8/// ASN.1 `BITSTRING` type
9///
10/// This objects owns data (it makes one copy during parsing). Internally, it relies on [`BitVec`].
11///
12/// Use [`BitString::as_bitslice`] to access content and [`BitString::as_mut_bitslice`] to modify content.
13///
14/// This type supports constructed objects, but all data segments are appended during parsing
15/// (_i.e_ object structure is not kept after parsing).
16#[derive(Clone, Debug, Default, Eq, PartialEq)]
17pub struct BitString {
18    bitvec: BitVec<u8, Msb0>,
19}
20
21impl BitString {
22    /// Build a new `BitString`
23    ///
24    /// # Safety
25    /// panic if `unused_bits` is greater than 7 or greater than input length
26    pub fn new(unused_bits: u8, s: &[u8]) -> Self {
27        let unused_bits = usize::from(unused_bits);
28        let mut bitvec = BitVec::from_slice(s);
29        assert!(unused_bits < 8 && unused_bits < bitvec.len());
30        bitvec.truncate(bitvec.len() - unused_bits);
31
32        BitString { bitvec }
33    }
34
35    /// Gets the length of the `BitString` (number of bits)
36    pub fn len(&self) -> usize {
37        self.bitvec.len()
38    }
39
40    /// Tests if the `BitString` is empty
41    pub fn is_empty(&self) -> bool {
42        self.bitvec.is_empty()
43    }
44
45    /// Test if bit `bitnum` is set
46    ///
47    /// Return false if bit is not set, or if index is outside range.
48    pub fn is_set(&self, bitnum: usize) -> bool {
49        self.as_bitslice()
50            .get(bitnum)
51            .map(|bitref| bitref == true)
52            .unwrap_or(false)
53    }
54
55    /// Return a shared `BitSlice` over the object data.
56    pub fn as_bitslice(&self) -> &BitSlice<u8, Msb0> {
57        self.bitvec.as_bitslice()
58    }
59
60    /// Return a mutable `BitSlice` over the object data.
61    pub fn as_mut_bitslice(&mut self) -> &mut BitSlice<u8, Msb0> {
62        self.bitvec.as_mut_bitslice()
63    }
64
65    /// Return a view over bit-slice bytes
66    pub fn as_raw_slice(&self) -> &[u8] {
67        self.bitvec.as_raw_slice()
68    }
69}
70
71impl AsRef<[u8]> for BitString {
72    fn as_ref(&self) -> &[u8] {
73        self.as_raw_slice()
74    }
75}
76
77impl_tryfrom_any!(BitString);
78
79impl From<&BitSlice<u8, Msb0>> for BitString {
80    fn from(slice: &BitSlice<u8, Msb0>) -> Self {
81        let bitvec = BitVec::from_bitslice(slice);
82        Self { bitvec }
83    }
84}
85
86impl<'i> BerParser<'i> for BitString {
87    type Error = BerError<Input<'i>>;
88
89    fn from_ber_content(
90        header: &'_ Header<'i>,
91        input: Input<'i>,
92    ) -> IResult<Input<'i>, Self, Self::Error> {
93        // Encoding shall either be primitive or constructed (X.690: 8.6.1)
94
95        if !header.constructed() {
96            let (rem, data) = ber_get_content(header, input)?;
97
98            if data.is_empty() {
99                return Err(BerError::nom_err_input(&data, InnerError::InvalidLength));
100            }
101
102            // safety: data cannot be empty (tested just above)
103            let (ignored, bytes) = data.as_bytes2().split_at(1);
104
105            // handle unused bits
106            // safety: we have split at index 1
107            match ignored[0] {
108                ignored @ 0..=7 => {
109                    let mut bitvec = BitVec::from_slice(bytes);
110                    let new_len = bitvec
111                        .len()
112                        .checked_sub(usize::from(ignored))
113                        .ok_or(BerError::nom_err_input(&data, InnerError::InvalidLength))?;
114                    bitvec.truncate(new_len);
115                    Ok((rem, Self { bitvec }))
116                }
117                _ => Err(BerError::nom_err_input(
118                    &data,
119                    InnerError::invalid_value(Tag::BitString, "Invalid unused bits"),
120                )),
121            }
122        } else {
123            // parse_segmented_bitstring(&header, input, BITSTRING_MAX_RECURSION)?
124            parse_ber_segmented(header, input, BITSTRING_MAX_RECURSION)
125        }
126    }
127}
128
129impl<'i> DerParser<'i> for BitString {
130    type Error = BerError<Input<'i>>;
131
132    fn from_der_content(
133        header: &'_ Header<'i>,
134        input: Input<'i>,
135    ) -> IResult<Input<'i>, Self, Self::Error> {
136        // Encoding shall be primitive (X.690: 10.2)
137        header.assert_primitive_input(&input).map_err(Err::Error)?;
138
139        <BitString>::from_ber_content(header, input)
140    }
141}
142
143impl CheckDerConstraints for BitString {
144    fn check_constraints(any: &Any) -> Result<()> {
145        // X.690 section 10.2
146        any.header.assert_primitive()?;
147        // Check that padding bits are all 0 (X.690 section 11.2.1)
148        let s = any.data.as_bytes2();
149        match s.len() {
150            0 => Err(Error::InvalidLength),
151            1 => {
152                // X.690 section 11.2.2 Note 2
153                if s[0] == 0 {
154                    Ok(())
155                } else {
156                    Err(Error::InvalidLength)
157                }
158            }
159            len => {
160                let unused_bits = s[0];
161                let last_byte = s[len - 1];
162                if last_byte.trailing_zeros() < unused_bits as u32 {
163                    return Err(Error::DerConstraintFailed(DerConstraint::UnusedBitsNotZero));
164                }
165
166                Ok(())
167            }
168        }
169    }
170}
171
172impl DerAutoDerive for BitString {}
173
174impl Tagged for BitString {
175    const TAG: Tag = Tag::BitString;
176}
177
178impl Appendable for BitString {
179    fn append(&mut self, other: &mut Self) {
180        self.bitvec.append(&mut other.bitvec);
181    }
182}
183
184#[cfg(feature = "std")]
185const _: () = {
186    use std::io::Write;
187
188    impl ToBer for BitString {
189        type Encoder = Primitive<{ Tag::BitString.0 }>;
190
191        fn ber_content_len(&self) -> Length {
192            let len = 1 + ((self.len() + 7) / 8);
193            Length::Definite(len)
194        }
195
196        fn ber_write_content<W: Write>(&self, target: &mut W) -> SerializeResult<usize> {
197            let data = self.as_raw_slice();
198            // ignored bits
199            let ignored = (8 * data.len()) - self.len();
200            target.write_all(&[ignored as u8])?;
201            // content
202            target.write_all(data)?;
203
204            Ok(1 + data.len())
205        }
206
207        fn ber_tag_info(&self) -> (Class, bool, Tag) {
208            (Self::CLASS, false, Self::TAG)
209        }
210    }
211
212    impl_toder_from_tober!(TY BitString);
213};
214
215#[cfg(test)]
216mod tests {
217    use hex_literal::hex;
218
219    use crate::{parse_ber_segmented, BerParser, Header, Input};
220
221    use super::BitString;
222
223    #[test]
224    fn test_bitstring_is_set() {
225        let obj = BitString::new(0, &[0x0f, 0x00, 0x40]);
226        assert!(!obj.is_set(0));
227        assert!(obj.is_set(7));
228        assert!(!obj.is_set(9));
229        assert!(obj.is_set(17));
230    }
231
232    #[test]
233    fn test_bitstring_to_bitvec() {
234        let obj = BitString::new(0, &[0x0f, 0x00, 0x40]);
235        let bv = obj.as_bitslice();
236        assert_eq!(bv.get(0).as_deref(), Some(&false));
237        assert_eq!(bv.get(7).as_deref(), Some(&true));
238        assert_eq!(bv.get(9).as_deref(), Some(&false));
239        assert_eq!(bv.get(17).as_deref(), Some(&true));
240    }
241
242    #[test]
243    fn test_bitstring_parse_segmented_primitive() {
244        //--- Ok: valid data (primitive)
245        // example data from X.690 section 8.6.4.2
246        let bytes = &hex!("0307 040A3B5F291CD0");
247        let (data, header) = Header::parse_ber(Input::from(bytes)).expect("header");
248        let (rem, b) = parse_ber_segmented::<BitString>(&header, data, 5).expect("parsing failed");
249        assert!(rem.is_empty());
250        // compare bitvector length to bitstring bytes, minus ignored bits
251        assert_eq!(b.len(), bytes[3..].len() * 8 - usize::from(bytes[2]));
252
253        //--- Fail: invalid length (only ignored bits)
254        let bytes = &hex!("0301 04");
255        let (data, header) = Header::parse_ber(Input::from(bytes)).expect("header");
256        let _ = parse_ber_segmented::<BitString>(&header, data, 5).expect_err("invalid length");
257
258        //--- Fail: invalid length (invalid ignored bits)
259        let bytes = &hex!("0302 0901");
260        let (data, header) = Header::parse_ber(Input::from(bytes)).expect("header");
261        let _ = parse_ber_segmented::<BitString>(&header, data, 5).expect_err("invalid length");
262    }
263
264    #[test]
265    fn test_bitstring_parse_segmented_constructed() {
266        //--- Ok: valid data (primitive)
267        // example data from X.690 section 8.6.4.2
268        let bytes = &hex!(
269            "23 80\
270            0303 000A3B\
271            0305 045F291CD0\
272            00 00"
273        );
274        let (data, header) = Header::parse_ber(Input::from(bytes)).expect("header");
275        let (rem, b) = parse_ber_segmented::<BitString>(&header, data, 5).expect("parsing failed");
276        assert!(rem.is_empty());
277        assert_eq!(b.len(), 44);
278
279        // Fail: hit recursion limit
280        let (data, header) = Header::parse_ber(Input::from(bytes)).expect("header");
281        let _ = parse_ber_segmented::<BitString>(&header, data, 1).expect_err("recursion limit");
282    }
283
284    #[cfg(feature = "std")]
285    mod tests_std {
286        use bitvec::{bits, order::Msb0};
287        use hex_literal::hex;
288
289        use crate::{BitString, ToBer};
290
291        #[test]
292        fn tober_bitstring() {
293            let immut = bits![u8, Msb0; 0, 1, 0, 0, 1, 0, 0, 1];
294            let bitstring = BitString::from(immut);
295            let mut v: Vec<u8> = Vec::new();
296            bitstring.ber_encode(&mut v).expect("serialization failed");
297            assert_eq!(&v, &hex! {"03020049"});
298        }
299    }
300}