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