der/asn1/
bit_string.rs

1//! ASN.1 `BIT STRING` support.
2
3use crate::{
4    BytesRef, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind, FixedTag, Header, Length, Reader,
5    Result, Tag, ValueOrd, Writer,
6};
7use core::{cmp::Ordering, iter::FusedIterator};
8
9/// ASN.1 `BIT STRING` type.
10///
11/// This type contains a sequence of any number of bits, modeled internally as
12/// a sequence of bytes with a known number of "unused bits".
13///
14/// This is a zero-copy reference type which borrows from the input data.
15#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
16pub struct BitStringRef<'a> {
17    /// Number of unused bits in the final octet.
18    unused_bits: u8,
19
20    /// Length of this `BIT STRING` in bits.
21    bit_length: usize,
22
23    /// Bitstring represented as a slice of bytes.
24    inner: BytesRef<'a>,
25}
26
27impl<'a> BitStringRef<'a> {
28    /// Maximum number of unused bits allowed.
29    pub const MAX_UNUSED_BITS: u8 = 7;
30
31    /// Create a new ASN.1 `BIT STRING` from a byte slice.
32    ///
33    /// Accepts an optional number of "unused bits" (0-7) which are omitted
34    /// from the final octet. This number is 0 if the value is octet-aligned.
35    pub fn new(unused_bits: u8, bytes: &'a [u8]) -> Result<Self> {
36        if (unused_bits > Self::MAX_UNUSED_BITS) || (unused_bits != 0 && bytes.is_empty()) {
37            return Err(Self::TAG.value_error());
38        }
39
40        let inner = BytesRef::new(bytes).map_err(|_| Self::TAG.length_error())?;
41
42        let bit_length = usize::try_from(inner.len())?
43            .checked_mul(8)
44            .and_then(|n| n.checked_sub(usize::from(unused_bits)))
45            .ok_or(ErrorKind::Overflow)?;
46
47        Ok(Self {
48            unused_bits,
49            bit_length,
50            inner,
51        })
52    }
53
54    /// Create a new ASN.1 `BIT STRING` from the given bytes.
55    ///
56    /// The "unused bits" are set to 0.
57    pub fn from_bytes(bytes: &'a [u8]) -> Result<Self> {
58        Self::new(0, bytes)
59    }
60
61    /// Get the number of unused bits in this byte slice.
62    pub fn unused_bits(&self) -> u8 {
63        self.unused_bits
64    }
65
66    /// Is the number of unused bits a value other than 0?
67    pub fn has_unused_bits(&self) -> bool {
68        self.unused_bits != 0
69    }
70
71    /// Get the length of this `BIT STRING` in bits.
72    pub fn bit_len(&self) -> usize {
73        self.bit_length
74    }
75
76    /// Get the number of bytes/octets needed to represent this `BIT STRING`
77    /// when serialized in an octet-aligned manner.
78    pub fn byte_len(&self) -> Length {
79        self.inner.len()
80    }
81
82    /// Is the inner byte slice empty?
83    pub fn is_empty(&self) -> bool {
84        self.inner.is_empty()
85    }
86
87    /// Borrow the inner byte slice.
88    ///
89    /// Returns `None` if the number of unused bits is *not* equal to zero,
90    /// i.e. if the `BIT STRING` is not octet aligned.
91    ///
92    /// Use [`BitString::raw_bytes`] to obtain access to the raw value
93    /// regardless of the presence of unused bits.
94    pub fn as_bytes(&self) -> Option<&'a [u8]> {
95        if self.has_unused_bits() {
96            None
97        } else {
98            Some(self.raw_bytes())
99        }
100    }
101
102    /// Borrow the raw bytes of this `BIT STRING`.
103    ///
104    /// Note that the byte string may contain extra unused bits in the final
105    /// octet. If the number of unused bits is expected to be 0, the
106    /// [`BitStringRef::as_bytes`] function can be used instead.
107    pub fn raw_bytes(&self) -> &'a [u8] {
108        self.inner.as_slice()
109    }
110
111    /// Iterator over the bits of this `BIT STRING`.
112    pub fn bits(self) -> BitStringIter<'a> {
113        BitStringIter {
114            bit_string: self,
115            position: 0,
116        }
117    }
118}
119
120impl_any_conversions!(BitStringRef<'a>, 'a);
121
122impl<'a> DecodeValue<'a> for BitStringRef<'a> {
123    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
124        let header = Header {
125            tag: header.tag,
126            length: (header.length - Length::ONE)?,
127        };
128
129        let unused_bits = reader.read_byte()?;
130        let inner = BytesRef::decode_value(reader, header)?;
131        Self::new(unused_bits, inner.as_slice())
132    }
133}
134
135impl EncodeValue for BitStringRef<'_> {
136    fn value_len(&self) -> Result<Length> {
137        self.byte_len() + Length::ONE
138    }
139
140    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
141        writer.write_byte(self.unused_bits)?;
142        writer.write(self.raw_bytes())
143    }
144}
145
146impl ValueOrd for BitStringRef<'_> {
147    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
148        match self.unused_bits.cmp(&other.unused_bits) {
149            Ordering::Equal => self.inner.der_cmp(&other.inner),
150            ordering => Ok(ordering),
151        }
152    }
153}
154
155impl<'a> From<&BitStringRef<'a>> for BitStringRef<'a> {
156    fn from(value: &BitStringRef<'a>) -> BitStringRef<'a> {
157        *value
158    }
159}
160
161impl<'a> TryFrom<&'a [u8]> for BitStringRef<'a> {
162    type Error = Error;
163
164    fn try_from(bytes: &'a [u8]) -> Result<BitStringRef<'a>> {
165        BitStringRef::from_bytes(bytes)
166    }
167}
168
169/// Hack for simplifying the custom derive use case.
170impl<'a> TryFrom<&&'a [u8]> for BitStringRef<'a> {
171    type Error = Error;
172
173    fn try_from(bytes: &&'a [u8]) -> Result<BitStringRef<'a>> {
174        BitStringRef::from_bytes(bytes)
175    }
176}
177
178impl<'a> TryFrom<BitStringRef<'a>> for &'a [u8] {
179    type Error = Error;
180
181    fn try_from(bit_string: BitStringRef<'a>) -> Result<&'a [u8]> {
182        bit_string
183            .as_bytes()
184            .ok_or_else(|| Tag::BitString.value_error())
185    }
186}
187
188impl<'a> FixedTag for BitStringRef<'a> {
189    const TAG: Tag = Tag::BitString;
190}
191
192// Implement by hand because the derive would create invalid values.
193// Use the constructor to create a valid value.
194#[cfg(feature = "arbitrary")]
195impl<'a> arbitrary::Arbitrary<'a> for BitStringRef<'a> {
196    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
197        Self::new(
198            u.int_in_range(0..=Self::MAX_UNUSED_BITS)?,
199            BytesRef::arbitrary(u)?.as_slice(),
200        )
201        .map_err(|_| arbitrary::Error::IncorrectFormat)
202    }
203
204    fn size_hint(depth: usize) -> (usize, Option<usize>) {
205        arbitrary::size_hint::and(u8::size_hint(depth), BytesRef::size_hint(depth))
206    }
207}
208
209#[cfg(feature = "alloc")]
210pub use self::allocating::BitString;
211
212#[cfg(feature = "alloc")]
213mod allocating {
214    use super::*;
215    use crate::referenced::*;
216    use alloc::vec::Vec;
217
218    /// Owned form of ASN.1 `BIT STRING` type.
219    ///
220    /// This type provides the same functionality as [`BitStringRef`] but owns the
221    /// backing data.
222    #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
223    pub struct BitString {
224        /// Number of unused bits in the final octet.
225        unused_bits: u8,
226
227        /// Length of this `BIT STRING` in bits.
228        bit_length: usize,
229
230        /// Bitstring represented as a slice of bytes.
231        inner: Vec<u8>,
232    }
233
234    impl BitString {
235        /// Maximum number of unused bits allowed.
236        pub const MAX_UNUSED_BITS: u8 = 7;
237
238        /// Create a new ASN.1 `BIT STRING` from a byte slice.
239        ///
240        /// Accepts an optional number of "unused bits" (0-7) which are omitted
241        /// from the final octet. This number is 0 if the value is octet-aligned.
242        pub fn new(unused_bits: u8, bytes: impl Into<Vec<u8>>) -> Result<Self> {
243            let inner = bytes.into();
244
245            // Ensure parameters parse successfully as a `BitStringRef`.
246            let bit_length = BitStringRef::new(unused_bits, &inner)?.bit_length;
247
248            Ok(BitString {
249                unused_bits,
250                bit_length,
251                inner,
252            })
253        }
254
255        /// Create a new ASN.1 `BIT STRING` from the given bytes.
256        ///
257        /// The "unused bits" are set to 0.
258        pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
259            Self::new(0, bytes)
260        }
261
262        /// Get the number of unused bits in the octet serialization of this
263        /// `BIT STRING`.
264        pub fn unused_bits(&self) -> u8 {
265            self.unused_bits
266        }
267
268        /// Is the number of unused bits a value other than 0?
269        pub fn has_unused_bits(&self) -> bool {
270            self.unused_bits != 0
271        }
272
273        /// Get the length of this `BIT STRING` in bits.
274        pub fn bit_len(&self) -> usize {
275            self.bit_length
276        }
277
278        /// Is the inner byte slice empty?
279        pub fn is_empty(&self) -> bool {
280            self.inner.is_empty()
281        }
282
283        /// Borrow the inner byte slice.
284        ///
285        /// Returns `None` if the number of unused bits is *not* equal to zero,
286        /// i.e. if the `BIT STRING` is not octet aligned.
287        ///
288        /// Use [`BitString::raw_bytes`] to obtain access to the raw value
289        /// regardless of the presence of unused bits.
290        pub fn as_bytes(&self) -> Option<&[u8]> {
291            if self.has_unused_bits() {
292                None
293            } else {
294                Some(self.raw_bytes())
295            }
296        }
297
298        /// Borrow the raw bytes of this `BIT STRING`.
299        pub fn raw_bytes(&self) -> &[u8] {
300            self.inner.as_slice()
301        }
302
303        /// Iterator over the bits of this `BIT STRING`.
304        pub fn bits(&self) -> BitStringIter<'_> {
305            BitStringRef::from(self).bits()
306        }
307    }
308
309    impl_any_conversions!(BitString);
310
311    impl<'a> DecodeValue<'a> for BitString {
312        fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
313            let inner_len = (header.length - Length::ONE)?;
314            let unused_bits = reader.read_byte()?;
315            let inner = reader.read_vec(inner_len)?;
316            Self::new(unused_bits, inner)
317        }
318    }
319
320    impl EncodeValue for BitString {
321        fn value_len(&self) -> Result<Length> {
322            Length::ONE + Length::try_from(self.inner.len())?
323        }
324
325        fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
326            writer.write_byte(self.unused_bits)?;
327            writer.write(&self.inner)
328        }
329    }
330
331    impl FixedTag for BitString {
332        const TAG: Tag = Tag::BitString;
333    }
334
335    impl<'a> From<&'a BitString> for BitStringRef<'a> {
336        fn from(bit_string: &'a BitString) -> BitStringRef<'a> {
337            // Ensured to parse successfully in constructor
338            BitStringRef::new(bit_string.unused_bits, &bit_string.inner)
339                .expect("invalid BIT STRING")
340        }
341    }
342
343    impl ValueOrd for BitString {
344        fn value_cmp(&self, other: &Self) -> Result<Ordering> {
345            match self.unused_bits.cmp(&other.unused_bits) {
346                Ordering::Equal => self.inner.der_cmp(&other.inner),
347                ordering => Ok(ordering),
348            }
349        }
350    }
351
352    // Implement by hand because the derive would create invalid values.
353    // Use the constructor to create a valid value.
354    #[cfg(feature = "arbitrary")]
355    impl<'a> arbitrary::Arbitrary<'a> for BitString {
356        fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
357            Self::new(
358                u.int_in_range(0..=Self::MAX_UNUSED_BITS)?,
359                BytesRef::arbitrary(u)?.as_slice(),
360            )
361            .map_err(|_| arbitrary::Error::IncorrectFormat)
362        }
363
364        fn size_hint(depth: usize) -> (usize, Option<usize>) {
365            arbitrary::size_hint::and(u8::size_hint(depth), BytesRef::size_hint(depth))
366        }
367    }
368
369    impl<'a> RefToOwned<'a> for BitStringRef<'a> {
370        type Owned = BitString;
371        fn ref_to_owned(&self) -> Self::Owned {
372            BitString {
373                unused_bits: self.unused_bits,
374                bit_length: self.bit_length,
375                inner: Vec::from(self.inner.as_slice()),
376            }
377        }
378    }
379
380    impl OwnedToRef for BitString {
381        type Borrowed<'a> = BitStringRef<'a>;
382        fn owned_to_ref(&self) -> Self::Borrowed<'_> {
383            self.into()
384        }
385    }
386}
387
388/// Iterator over the bits of a [`BitString`].
389pub struct BitStringIter<'a> {
390    /// [`BitString`] being iterated over.
391    bit_string: BitStringRef<'a>,
392
393    /// Current bit position within the iterator.
394    position: usize,
395}
396
397impl<'a> Iterator for BitStringIter<'a> {
398    type Item = bool;
399
400    #[allow(clippy::integer_arithmetic)]
401    fn next(&mut self) -> Option<bool> {
402        if self.position >= self.bit_string.bit_len() {
403            return None;
404        }
405
406        let byte = self.bit_string.raw_bytes().get(self.position / 8)?;
407        let bit = 1u8 << (7 - (self.position % 8));
408        self.position = self.position.checked_add(1)?;
409        Some(byte & bit != 0)
410    }
411}
412
413impl<'a> ExactSizeIterator for BitStringIter<'a> {
414    fn len(&self) -> usize {
415        self.bit_string.bit_len()
416    }
417}
418
419impl<'a> FusedIterator for BitStringIter<'a> {}
420
421#[cfg(feature = "flagset")]
422impl<T: flagset::Flags> FixedTag for flagset::FlagSet<T> {
423    const TAG: Tag = BitStringRef::TAG;
424}
425
426#[cfg(feature = "flagset")]
427impl<T> ValueOrd for flagset::FlagSet<T>
428where
429    T: flagset::Flags,
430    T::Type: Ord,
431{
432    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
433        Ok(self.bits().cmp(&other.bits()))
434    }
435}
436
437#[cfg(feature = "flagset")]
438#[allow(clippy::integer_arithmetic)]
439impl<'a, T> DecodeValue<'a> for flagset::FlagSet<T>
440where
441    T: flagset::Flags,
442    T::Type: From<bool>,
443    T::Type: core::ops::Shl<usize, Output = T::Type>,
444{
445    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
446        let position = reader.position();
447        let bits = BitStringRef::decode_value(reader, header)?;
448
449        let mut flags = T::none().bits();
450
451        if bits.bit_len() > core::mem::size_of_val(&flags) * 8 {
452            return Err(Error::new(ErrorKind::Overlength, position));
453        }
454
455        for (i, bit) in bits.bits().enumerate() {
456            flags |= T::Type::from(bit) << i;
457        }
458
459        Ok(Self::new_truncated(flags))
460    }
461}
462
463#[cfg(feature = "flagset")]
464#[allow(clippy::integer_arithmetic)]
465#[inline(always)]
466fn encode_flagset<T>(set: &flagset::FlagSet<T>) -> (usize, [u8; 16])
467where
468    T: flagset::Flags,
469    u128: From<T::Type>,
470{
471    let bits: u128 = set.bits().into();
472    let mut swap = 0u128;
473
474    for i in 0..128 {
475        let on = bits & (1 << i);
476        swap |= on >> i << (128 - i - 1);
477    }
478
479    (bits.leading_zeros() as usize, swap.to_be_bytes())
480}
481
482#[cfg(feature = "flagset")]
483#[allow(clippy::cast_possible_truncation, clippy::integer_arithmetic)]
484impl<T: flagset::Flags> EncodeValue for flagset::FlagSet<T>
485where
486    T::Type: From<bool>,
487    T::Type: core::ops::Shl<usize, Output = T::Type>,
488    u128: From<T::Type>,
489{
490    fn value_len(&self) -> Result<Length> {
491        let (lead, buff) = encode_flagset(self);
492        let buff = &buff[..buff.len() - lead / 8];
493        BitStringRef::new((lead % 8) as u8, buff)?.value_len()
494    }
495
496    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
497        let (lead, buff) = encode_flagset(self);
498        let buff = &buff[..buff.len() - lead / 8];
499        BitStringRef::new((lead % 8) as u8, buff)?.encode_value(writer)
500    }
501}
502
503#[cfg(test)]
504mod tests {
505    use super::{BitStringRef, Result, Tag};
506    use crate::asn1::AnyRef;
507    use hex_literal::hex;
508
509    /// Parse a `BitString` from an ASN.1 `Any` value to test decoding behaviors.
510    fn parse_bitstring(bytes: &[u8]) -> Result<BitStringRef<'_>> {
511        AnyRef::new(Tag::BitString, bytes)?.try_into()
512    }
513
514    #[test]
515    fn decode_empty_bitstring() {
516        let bs = parse_bitstring(&hex!("00")).unwrap();
517        assert_eq!(bs.as_bytes().unwrap(), &[]);
518    }
519
520    #[test]
521    fn decode_non_empty_bitstring() {
522        let bs = parse_bitstring(&hex!("00010203")).unwrap();
523        assert_eq!(bs.as_bytes().unwrap(), &[0x01, 0x02, 0x03]);
524    }
525
526    #[test]
527    fn decode_bitstring_with_unused_bits() {
528        let bs = parse_bitstring(&hex!("066e5dc0")).unwrap();
529        assert_eq!(bs.unused_bits(), 6);
530        assert_eq!(bs.raw_bytes(), &hex!("6e5dc0"));
531
532        // Expected: 011011100101110111
533        let mut bits = bs.bits();
534        assert_eq!(bits.len(), 18);
535
536        for bit in [0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1] {
537            assert_eq!(u8::from(bits.next().unwrap()), bit)
538        }
539
540        // Ensure `None` is returned on successive calls
541        assert_eq!(bits.next(), None);
542        assert_eq!(bits.next(), None);
543    }
544
545    #[test]
546    fn reject_unused_bits_in_empty_string() {
547        assert_eq!(
548            parse_bitstring(&[0x03]).err().unwrap().kind(),
549            Tag::BitString.value_error().kind()
550        )
551    }
552}