1 //! ASN.1 `BIT STRING` support.
2 
3 use crate::{
4     BytesRef, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind, FixedTag, Header, Length, Reader,
5     Result, Tag, ValueOrd, Writer,
6 };
7 use 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)]
16 pub 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 
27 impl<'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.
new(unused_bits: u8, bytes: &'a [u8]) -> Result<Self>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.
from_bytes(bytes: &'a [u8]) -> Result<Self>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.
unused_bits(&self) -> u862     pub fn unused_bits(&self) -> u8 {
63         self.unused_bits
64     }
65 
66     /// Is the number of unused bits a value other than 0?
has_unused_bits(&self) -> bool67     pub fn has_unused_bits(&self) -> bool {
68         self.unused_bits != 0
69     }
70 
71     /// Get the length of this `BIT STRING` in bits.
bit_len(&self) -> usize72     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.
byte_len(&self) -> Length78     pub fn byte_len(&self) -> Length {
79         self.inner.len()
80     }
81 
82     /// Is the inner byte slice empty?
is_empty(&self) -> bool83     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.
as_bytes(&self) -> Option<&'a [u8]>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.
raw_bytes(&self) -> &'a [u8]107     pub fn raw_bytes(&self) -> &'a [u8] {
108         self.inner.as_slice()
109     }
110 
111     /// Iterator over the bits of this `BIT STRING`.
bits(self) -> BitStringIter<'a>112     pub fn bits(self) -> BitStringIter<'a> {
113         BitStringIter {
114             bit_string: self,
115             position: 0,
116         }
117     }
118 }
119 
120 impl_any_conversions!(BitStringRef<'a>, 'a);
121 
122 impl<'a> DecodeValue<'a> for BitStringRef<'a> {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>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 
135 impl EncodeValue for BitStringRef<'_> {
value_len(&self) -> Result<Length>136     fn value_len(&self) -> Result<Length> {
137         self.byte_len() + Length::ONE
138     }
139 
encode_value(&self, writer: &mut impl Writer) -> Result<()>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 
146 impl ValueOrd for BitStringRef<'_> {
value_cmp(&self, other: &Self) -> Result<Ordering>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 
155 impl<'a> From<&BitStringRef<'a>> for BitStringRef<'a> {
from(value: &BitStringRef<'a>) -> BitStringRef<'a>156     fn from(value: &BitStringRef<'a>) -> BitStringRef<'a> {
157         *value
158     }
159 }
160 
161 impl<'a> TryFrom<&'a [u8]> for BitStringRef<'a> {
162     type Error = Error;
163 
try_from(bytes: &'a [u8]) -> Result<BitStringRef<'a>>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.
170 impl<'a> TryFrom<&&'a [u8]> for BitStringRef<'a> {
171     type Error = Error;
172 
try_from(bytes: &&'a [u8]) -> Result<BitStringRef<'a>>173     fn try_from(bytes: &&'a [u8]) -> Result<BitStringRef<'a>> {
174         BitStringRef::from_bytes(bytes)
175     }
176 }
177 
178 impl<'a> TryFrom<BitStringRef<'a>> for &'a [u8] {
179     type Error = Error;
180 
try_from(bit_string: BitStringRef<'a>) -> Result<&'a [u8]>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 
188 impl<'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")]
195 impl<'a> arbitrary::Arbitrary<'a> for BitStringRef<'a> {
arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self>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 
size_hint(depth: usize) -> (usize, Option<usize>)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")]
210 pub use self::allocating::BitString;
211 
212 #[cfg(feature = "alloc")]
213 mod 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.
new(unused_bits: u8, bytes: impl Into<Vec<u8>>) -> Result<Self>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.
from_bytes(bytes: &[u8]) -> Result<Self>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`.
unused_bits(&self) -> u8264         pub fn unused_bits(&self) -> u8 {
265             self.unused_bits
266         }
267 
268         /// Is the number of unused bits a value other than 0?
has_unused_bits(&self) -> bool269         pub fn has_unused_bits(&self) -> bool {
270             self.unused_bits != 0
271         }
272 
273         /// Get the length of this `BIT STRING` in bits.
bit_len(&self) -> usize274         pub fn bit_len(&self) -> usize {
275             self.bit_length
276         }
277 
278         /// Is the inner byte slice empty?
is_empty(&self) -> bool279         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.
as_bytes(&self) -> Option<&[u8]>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`.
raw_bytes(&self) -> &[u8]299         pub fn raw_bytes(&self) -> &[u8] {
300             self.inner.as_slice()
301         }
302 
303         /// Iterator over the bits of this `BIT STRING`.
bits(&self) -> BitStringIter<'_>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 {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>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 {
value_len(&self) -> Result<Length>321         fn value_len(&self) -> Result<Length> {
322             Length::ONE + Length::try_from(self.inner.len())?
323         }
324 
encode_value(&self, writer: &mut impl Writer) -> Result<()>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> {
from(bit_string: &'a BitString) -> 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 {
value_cmp(&self, other: &Self) -> Result<Ordering>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 {
arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self>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 
size_hint(depth: usize) -> (usize, Option<usize>)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;
ref_to_owned(&self) -> Self::Owned371         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>;
owned_to_ref(&self) -> Self::Borrowed<'_>382         fn owned_to_ref(&self) -> Self::Borrowed<'_> {
383             self.into()
384         }
385     }
386 }
387 
388 /// Iterator over the bits of a [`BitString`].
389 pub 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 
397 impl<'a> Iterator for BitStringIter<'a> {
398     type Item = bool;
399 
400     #[allow(clippy::integer_arithmetic)]
next(&mut self) -> Option<bool>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 
413 impl<'a> ExactSizeIterator for BitStringIter<'a> {
len(&self) -> usize414     fn len(&self) -> usize {
415         self.bit_string.bit_len()
416     }
417 }
418 
419 impl<'a> FusedIterator for BitStringIter<'a> {}
420 
421 #[cfg(feature = "flagset")]
422 impl<T: flagset::Flags> FixedTag for flagset::FlagSet<T> {
423     const TAG: Tag = BitStringRef::TAG;
424 }
425 
426 #[cfg(feature = "flagset")]
427 impl<T> ValueOrd for flagset::FlagSet<T>
428 where
429     T: flagset::Flags,
430     T::Type: Ord,
431 {
value_cmp(&self, other: &Self) -> Result<Ordering>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)]
439 impl<'a, T> DecodeValue<'a> for flagset::FlagSet<T>
440 where
441     T: flagset::Flags,
442     T::Type: From<bool>,
443     T::Type: core::ops::Shl<usize, Output = T::Type>,
444 {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>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)]
encode_flagset<T>(set: &flagset::FlagSet<T>) -> (usize, [u8; 16]) where T: flagset::Flags, u128: From<T::Type>,466 fn encode_flagset<T>(set: &flagset::FlagSet<T>) -> (usize, [u8; 16])
467 where
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)]
484 impl<T: flagset::Flags> EncodeValue for flagset::FlagSet<T>
485 where
486     T::Type: From<bool>,
487     T::Type: core::ops::Shl<usize, Output = T::Type>,
488     u128: From<T::Type>,
489 {
value_len(&self) -> Result<Length>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 
encode_value(&self, writer: &mut impl Writer) -> Result<()>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)]
504 mod 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.
parse_bitstring(bytes: &[u8]) -> Result<BitStringRef<'_>>510     fn parse_bitstring(bytes: &[u8]) -> Result<BitStringRef<'_>> {
511         AnyRef::new(Tag::BitString, bytes)?.try_into()
512     }
513 
514     #[test]
decode_empty_bitstring()515     fn decode_empty_bitstring() {
516         let bs = parse_bitstring(&hex!("00")).unwrap();
517         assert_eq!(bs.as_bytes().unwrap(), &[]);
518     }
519 
520     #[test]
decode_non_empty_bitstring()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]
decode_bitstring_with_unused_bits()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]
reject_unused_bits_in_empty_string()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 }
553