1pub mod allowed_len_bit_string;
4
5use crate::{
6 BytesRef, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind, FixedTag, Header, Length, Reader,
7 Result, Tag, ValueOrd, Writer,
8};
9use core::{cmp::Ordering, iter::FusedIterator};
10use unused_bits::UnusedBits;
11
12#[cfg(feature = "flagset")]
13use core::mem::size_of_val;
14
15#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
22pub struct BitStringRef<'a> {
23 unused_bits: UnusedBits,
25
26 inner: &'a BytesRef,
28}
29
30impl<'a> BitStringRef<'a> {
31 pub fn new(unused_bits: u8, bytes: &'a [u8]) -> Result<Self> {
42 let unused_bits = UnusedBits::new(unused_bits, bytes)?;
43 let inner = BytesRef::new(bytes).map_err(|_| Self::TAG.length_error())?;
44 let value = Self::new_unchecked(unused_bits, inner);
45 value
46 .bit_len_checked()
47 .ok_or_else(|| Error::from(ErrorKind::Overflow))?;
48 Ok(value)
49 }
50
51 pub(crate) fn new_unchecked(unused_bits: UnusedBits, inner: &'a BytesRef) -> Self {
55 Self { unused_bits, inner }
56 }
57
58 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self> {
65 Self::new(0, bytes)
66 }
67
68 #[must_use]
70 pub fn unused_bits(&self) -> u8 {
71 *self.unused_bits
72 }
73
74 #[must_use]
76 pub fn has_unused_bits(&self) -> bool {
77 *self.unused_bits != 0
78 }
79
80 fn bit_len_checked(&self) -> Option<usize> {
84 usize::try_from(self.inner.len())
85 .ok()
86 .and_then(|n| n.checked_mul(8))
87 .and_then(|n| n.checked_sub(usize::from(*self.unused_bits)))
88 }
89
90 #[must_use]
92 pub fn bit_len(&self) -> usize {
93 let bit_len = self.bit_len_checked();
94 debug_assert!(bit_len.is_some());
95
96 bit_len.unwrap_or(0)
98 }
99
100 #[must_use]
103 pub fn byte_len(&self) -> Length {
104 self.inner.len()
105 }
106
107 #[must_use]
109 pub fn is_empty(&self) -> bool {
110 self.inner.is_empty()
111 }
112
113 #[must_use]
121 pub fn as_bytes(&self) -> Option<&'a [u8]> {
122 if self.has_unused_bits() {
123 None
124 } else {
125 Some(self.raw_bytes())
126 }
127 }
128
129 #[must_use]
135 pub fn raw_bytes(&self) -> &'a [u8] {
136 self.inner.as_slice()
137 }
138
139 #[must_use]
141 pub fn bits(self) -> BitStringIter<'a> {
142 BitStringIter {
143 bit_string: self,
144 position: 0,
145 }
146 }
147
148 #[must_use]
150 pub fn get(&self, position: usize) -> Option<bool> {
151 if position >= self.bit_len() {
152 return None;
153 }
154
155 let byte = self.raw_bytes().get(position / 8)?;
156 let bitmask = 1u8 << (7 - (position % 8));
157 Some(byte & bitmask != 0)
158 }
159}
160
161impl_any_conversions!(BitStringRef<'a>, 'a);
162
163impl<'a> DecodeValue<'a> for BitStringRef<'a> {
164 type Error = Error;
165
166 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
167 let header = header.with_length((header.length() - Length::ONE)?);
168
169 let unused_bits = reader.read_byte()?;
170 let inner = <&'a BytesRef>::decode_value(reader, header)?;
171 Self::new(unused_bits, inner.as_slice())
172 }
173}
174
175impl EncodeValue for BitStringRef<'_> {
176 fn value_len(&self) -> Result<Length> {
177 self.byte_len() + Length::ONE
178 }
179
180 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
181 writer.write_byte(*self.unused_bits)?;
182 writer.write(self.raw_bytes())
183 }
184}
185
186impl ValueOrd for BitStringRef<'_> {
187 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
188 match self.unused_bits.cmp(&other.unused_bits) {
189 Ordering::Equal => self.inner.der_cmp(other.inner),
190 ordering => Ok(ordering),
191 }
192 }
193}
194
195impl<'a> From<&BitStringRef<'a>> for BitStringRef<'a> {
196 fn from(value: &BitStringRef<'a>) -> BitStringRef<'a> {
197 *value
198 }
199}
200
201impl<'a> TryFrom<&'a [u8]> for BitStringRef<'a> {
202 type Error = Error;
203
204 fn try_from(bytes: &'a [u8]) -> Result<BitStringRef<'a>> {
205 BitStringRef::from_bytes(bytes)
206 }
207}
208
209impl<'a> TryFrom<&&'a [u8]> for BitStringRef<'a> {
211 type Error = Error;
212
213 fn try_from(bytes: &&'a [u8]) -> Result<BitStringRef<'a>> {
214 BitStringRef::from_bytes(bytes)
215 }
216}
217
218impl<'a, const N: usize> TryFrom<&'a [u8; N]> for BitStringRef<'a> {
219 type Error = Error;
220
221 fn try_from(bytes: &'a [u8; N]) -> Result<BitStringRef<'a>> {
222 BitStringRef::from_bytes(bytes)
223 }
224}
225
226impl<'a, const N: usize> TryFrom<BitStringRef<'a>> for [u8; N] {
227 type Error = Error;
228
229 fn try_from(bit_string: BitStringRef<'a>) -> Result<Self> {
230 let bytes: &[u8] = TryFrom::try_from(bit_string)?;
231 bytes
232 .try_into()
233 .map_err(|_| Tag::BitString.length_error().into())
234 }
235}
236
237impl<'a> TryFrom<BitStringRef<'a>> for &'a [u8] {
238 type Error = Error;
239
240 fn try_from(bit_string: BitStringRef<'a>) -> Result<&'a [u8]> {
241 bit_string
242 .as_bytes()
243 .ok_or_else(|| Tag::BitString.value_error().into())
244 }
245}
246
247impl FixedTag for BitStringRef<'_> {
248 const TAG: Tag = Tag::BitString;
249}
250
251pub trait AsBitStringRef {
258 fn as_bit_string_ref(&self) -> BitStringRef<'_>;
260}
261
262impl AsBitStringRef for BitStringRef<'_> {
263 fn as_bit_string_ref(&self) -> BitStringRef<'_> {
264 *self
265 }
266}
267
268mod unused_bits {
270 use core::ops::Deref;
271
272 use crate::{Result, Tag};
273
274 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
278 pub(crate) struct UnusedBits(u8);
279
280 impl UnusedBits {
281 pub const MAX_UNUSED_BITS: u8 = 7;
283
284 pub fn new(unused_bits: u8, bytes: &[u8]) -> Result<Self> {
287 if (unused_bits > Self::MAX_UNUSED_BITS) || (unused_bits != 0 && bytes.is_empty()) {
288 Err(Tag::BitString.value_error().into())
289 } else {
290 Ok(Self(unused_bits))
291 }
292 }
293 }
294 impl Deref for UnusedBits {
295 type Target = u8;
296
297 fn deref(&self) -> &Self::Target {
298 &self.0
299 }
300 }
301}
302
303#[cfg(feature = "arbitrary")]
306impl<'a> arbitrary::Arbitrary<'a> for BitStringRef<'a> {
307 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
308 Self::new(
309 u.int_in_range(0..=UnusedBits::MAX_UNUSED_BITS)?,
310 <&'a BytesRef>::arbitrary(u)?.as_slice(),
311 )
312 .map_err(|_| arbitrary::Error::IncorrectFormat)
313 }
314
315 fn size_hint(depth: usize) -> (usize, Option<usize>) {
316 arbitrary::size_hint::and(u8::size_hint(depth), <&'a BytesRef>::size_hint(depth))
317 }
318}
319
320#[cfg(feature = "alloc")]
321pub use self::allocating::BitString;
322
323#[cfg(feature = "alloc")]
324mod allocating {
325 use super::*;
326 use crate::{asn1::Any, referenced::*};
327 use alloc::vec::Vec;
328
329 #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
334 pub struct BitString {
335 unused_bits: UnusedBits,
337
338 inner: Vec<u8>,
340 }
341
342 impl BitString {
343 pub const MAX_UNUSED_BITS: u8 = 7;
345
346 pub fn new(unused_bits: u8, bytes: impl Into<Vec<u8>>) -> Result<Self> {
357 let inner = bytes.into();
358
359 let ref_value = BitStringRef::new(unused_bits, &inner)?;
361
362 Ok(BitString {
363 unused_bits: ref_value.unused_bits,
364 inner,
365 })
366 }
367
368 pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
375 Self::new(0, bytes)
376 }
377
378 #[must_use]
381 pub fn unused_bits(&self) -> u8 {
382 *self.unused_bits
383 }
384
385 #[must_use]
387 pub fn has_unused_bits(&self) -> bool {
388 *self.unused_bits != 0
389 }
390
391 pub(crate) fn bytes_ref(&self) -> &BytesRef {
393 BytesRef::new_unchecked(&self.inner)
395 }
396
397 fn bit_len_checked(&self) -> Option<usize> {
401 BitStringRef::new_unchecked(self.unused_bits, self.bytes_ref()).bit_len_checked()
402 }
403
404 #[must_use]
406 pub fn bit_len(&self) -> usize {
407 let bit_len = self.bit_len_checked();
408 debug_assert!(bit_len.is_some());
409
410 bit_len.unwrap_or(0)
412 }
413
414 #[must_use]
416 pub fn is_empty(&self) -> bool {
417 self.inner.is_empty()
418 }
419
420 #[must_use]
428 pub fn as_bytes(&self) -> Option<&[u8]> {
429 if self.has_unused_bits() {
430 None
431 } else {
432 Some(self.raw_bytes())
433 }
434 }
435
436 #[must_use]
438 pub fn raw_bytes(&self) -> &[u8] {
439 self.inner.as_slice()
440 }
441
442 #[must_use]
444 pub fn bits(&self) -> BitStringIter<'_> {
445 BitStringRef::from(self).bits()
446 }
447
448 #[must_use]
450 pub fn get(&self, position: usize) -> Option<bool> {
451 BitStringRef::from(self).get(position)
452 }
453 }
454
455 impl_any_conversions!(BitString);
456
457 impl<'a> DecodeValue<'a> for BitString {
458 type Error = Error;
459
460 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
461 let inner_len = (header.length() - Length::ONE)?;
462 let unused_bits = reader.read_byte()?;
463 let inner = reader.read_vec(inner_len)?;
464 Self::new(unused_bits, inner)
465 }
466 }
467
468 impl EncodeValue for BitString {
469 fn value_len(&self) -> Result<Length> {
470 Length::ONE + Length::try_from(self.inner.len())?
471 }
472
473 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
474 writer.write_byte(*self.unused_bits)?;
475 writer.write(&self.inner)
476 }
477 }
478
479 impl FixedTag for BitString {
480 const TAG: Tag = Tag::BitString;
481 }
482
483 impl<'a> From<&'a BitString> for BitStringRef<'a> {
484 fn from(bit_string: &'a BitString) -> BitStringRef<'a> {
485 BitStringRef::new_unchecked(bit_string.unused_bits, bit_string.bytes_ref())
487 }
488 }
489
490 impl From<BitStringRef<'_>> for Any {
491 fn from(bit_string_ref: BitStringRef<'_>) -> Any {
492 Any::from(&bit_string_ref)
493 }
494 }
495
496 impl From<&BitStringRef<'_>> for Any {
497 fn from(bit_string_ref: &BitStringRef<'_>) -> Any {
498 Any::encode_from(bit_string_ref).expect("should encode successfully")
499 }
500 }
501
502 impl From<BitString> for Any {
503 fn from(bit_string: BitString) -> Any {
504 bit_string.owned_to_ref().into()
505 }
506 }
507
508 impl From<&BitString> for Any {
509 fn from(bit_string: &BitString) -> Any {
510 bit_string.owned_to_ref().into()
511 }
512 }
513
514 impl<'a> TryFrom<&'a Vec<u8>> for BitStringRef<'a> {
516 type Error = Error;
517
518 fn try_from(bytes: &'a Vec<u8>) -> Result<BitStringRef<'a>> {
519 BitStringRef::from_bytes(bytes)
520 }
521 }
522
523 impl<'a> TryFrom<BitStringRef<'a>> for Vec<u8> {
525 type Error = Error;
526
527 fn try_from(bit_string: BitStringRef<'a>) -> Result<Vec<u8>> {
528 bit_string
529 .as_bytes()
530 .map(<[u8]>::to_vec)
531 .ok_or_else(|| Tag::BitString.value_error().into())
532 }
533 }
534
535 impl ValueOrd for BitString {
536 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
537 match self.unused_bits.cmp(&other.unused_bits) {
538 Ordering::Equal => self.inner.der_cmp(&other.inner),
539 ordering => Ok(ordering),
540 }
541 }
542 }
543
544 #[cfg(feature = "arbitrary")]
547 impl<'a> arbitrary::Arbitrary<'a> for BitString {
548 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
549 Self::new(
550 u.int_in_range(0..=Self::MAX_UNUSED_BITS)?,
551 <&'a BytesRef>::arbitrary(u)?.as_slice(),
552 )
553 .map_err(|_| arbitrary::Error::IncorrectFormat)
554 }
555
556 fn size_hint(depth: usize) -> (usize, Option<usize>) {
557 arbitrary::size_hint::and(u8::size_hint(depth), <&'a BytesRef>::size_hint(depth))
558 }
559 }
560
561 impl<'a> RefToOwned<'a> for BitStringRef<'a> {
562 type Owned = BitString;
563 fn ref_to_owned(&self) -> Self::Owned {
564 BitString {
565 unused_bits: self.unused_bits,
566 inner: Vec::from(self.inner.as_slice()),
567 }
568 }
569 }
570
571 impl OwnedToRef for BitString {
572 type Borrowed<'a> = BitStringRef<'a>;
573 fn owned_to_ref(&self) -> Self::Borrowed<'_> {
574 self.into()
575 }
576 }
577
578 impl AsBitStringRef for BitString {
579 fn as_bit_string_ref(&self) -> BitStringRef<'_> {
580 BitStringRef::from(self)
581 }
582 }
583}
584
585#[derive(Debug)]
587pub struct BitStringIter<'a> {
588 bit_string: BitStringRef<'a>,
590
591 position: usize,
593}
594
595impl Iterator for BitStringIter<'_> {
596 type Item = bool;
597
598 #[allow(clippy::arithmetic_side_effects)]
599 fn next(&mut self) -> Option<bool> {
600 if self.position >= self.bit_string.bit_len() {
601 return None;
602 }
603
604 let byte = self.bit_string.raw_bytes().get(self.position / 8)?;
605 let bit = 1u8 << (7 - (self.position % 8));
606 self.position = self.position.checked_add(1)?;
607 Some(byte & bit != 0)
608 }
609
610 fn size_hint(&self) -> (usize, Option<usize>) {
611 let len = self.bit_string.bit_len().saturating_sub(self.position);
612 (len, Some(len))
613 }
614}
615
616impl ExactSizeIterator for BitStringIter<'_> {
617 fn len(&self) -> usize {
618 self.bit_string.bit_len()
619 }
620}
621
622impl FusedIterator for BitStringIter<'_> {}
623
624#[cfg(feature = "flagset")]
625impl<T: flagset::Flags> FixedTag for flagset::FlagSet<T> {
626 const TAG: Tag = BitStringRef::TAG;
627}
628
629#[cfg(feature = "flagset")]
634impl<T> ValueOrd for flagset::FlagSet<T>
635where
636 T: flagset::Flags,
637 T::Type: From<bool>,
638 T::Type: core::ops::Shl<usize, Output = T::Type>,
639 u128: From<T::Type>,
640{
641 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
642 let mut buf1 = [0u8; 17];
643 let mut buf2 = [0u8; 17];
644 let a = crate::encode::encode_value_to_slice(&mut buf1, self)?;
645 let b = crate::encode::encode_value_to_slice(&mut buf2, other)?;
646 Ok(a.cmp(b))
647 }
648}
649
650#[cfg(feature = "flagset")]
651#[allow(clippy::arithmetic_side_effects)]
652impl<'a, T> DecodeValue<'a> for flagset::FlagSet<T>
653where
654 T: flagset::Flags,
655 T::Type: From<bool>,
656 T::Type: core::ops::Shl<usize, Output = T::Type>,
657{
658 type Error = Error;
659
660 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
661 let position = reader.position();
662 let bits = BitStringRef::decode_value(reader, header)?;
663
664 let mut flags = T::none().bits();
665
666 if bits.bit_len() > size_of_val(&flags) * 8 {
667 return Err(Error::new(ErrorKind::Overlength, position));
668 }
669
670 for (i, bit) in bits.bits().enumerate() {
671 flags |= T::Type::from(bit) << i;
672 }
673
674 Ok(Self::new_truncated(flags))
675 }
676}
677
678#[cfg(feature = "flagset")]
679#[allow(clippy::arithmetic_side_effects)]
680#[inline(always)]
681fn encode_flagset<T>(set: &flagset::FlagSet<T>) -> (usize, [u8; 16])
682where
683 T: flagset::Flags,
684 u128: From<T::Type>,
685{
686 let bits: u128 = set.bits().into();
687 let mut swap = 0u128;
688
689 for i in 0..128 {
690 let on = bits & (1 << i);
691 swap |= on >> i << (128 - i - 1);
692 }
693
694 (bits.leading_zeros() as usize, swap.to_be_bytes())
695}
696
697#[cfg(feature = "flagset")]
698#[allow(clippy::cast_possible_truncation, clippy::arithmetic_side_effects)]
699impl<T: flagset::Flags> EncodeValue for flagset::FlagSet<T>
700where
701 T::Type: From<bool>,
702 T::Type: core::ops::Shl<usize, Output = T::Type>,
703 u128: From<T::Type>,
704{
705 fn value_len(&self) -> Result<Length> {
706 let (lead, buff) = encode_flagset(self);
707 let buff = &buff[..buff.len() - lead / 8];
708 BitStringRef::new((lead % 8) as u8, buff)?.value_len()
709 }
710
711 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
712 let (lead, buff) = encode_flagset(self);
713 let buff = &buff[..buff.len() - lead / 8];
714 BitStringRef::new((lead % 8) as u8, buff)?.encode_value(writer)
715 }
716}
717
718#[cfg(test)]
719#[allow(clippy::unwrap_used)]
720mod tests {
721 use core::cmp::Ordering;
722
723 use super::{BitStringRef, Result, Tag};
724 use crate::asn1::AnyRef;
725 use hex_literal::hex;
726
727 fn parse_bitstring(bytes: &[u8]) -> Result<BitStringRef<'_>> {
729 AnyRef::new(Tag::BitString, bytes)?.try_into()
730 }
731
732 #[test]
733 fn decode_empty_bitstring() {
734 let bs = parse_bitstring(&hex!("00")).unwrap();
735 assert_eq!(bs.as_bytes().unwrap(), &[]);
736 }
737
738 #[test]
739 fn decode_non_empty_bitstring() {
740 let bs = parse_bitstring(&hex!("00010203")).unwrap();
741 assert_eq!(bs.as_bytes().unwrap(), &[0x01, 0x02, 0x03]);
742 }
743
744 #[test]
745 fn decode_bitstring_with_unused_bits() {
746 let bs = parse_bitstring(&hex!("066e5dc0")).unwrap();
747 assert_eq!(bs.unused_bits(), 6);
748 assert_eq!(bs.raw_bytes(), &hex!("6e5dc0"));
749
750 let mut bits = bs.bits();
752 assert_eq!(bits.len(), 18);
753
754 for bit in [0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1] {
755 assert_eq!(u8::from(bits.next().unwrap()), bit);
756 }
757
758 assert_eq!(bits.next(), None);
760 assert_eq!(bits.next(), None);
761 }
762
763 #[test]
764 fn reject_unused_bits_in_empty_string() {
765 assert_eq!(
766 parse_bitstring(&[0x03]).err().unwrap().kind(),
767 Tag::BitString.value_error()
768 );
769 }
770
771 #[test]
772 fn bitstring_valueord_value_cmp() {
773 use crate::ord::DerOrd;
774
775 let bs1 = parse_bitstring(&hex!("00010204")).unwrap();
776 let bs2 = parse_bitstring(&hex!("00010203")).unwrap();
777 assert_eq!(bs1.der_cmp(&bs2), Ok(Ordering::Greater));
778 }
779
780 #[cfg(feature = "flagset")]
781 #[test]
782 fn flagset_valueord_is_encoding_order() {
783 use crate::{DerOrd, Encode, ValueOrd};
784
785 flagset::flags! {
786 enum Flags: u16 {
787 A, B, C, D, E, F, G, H, I,
788 }
789 }
790
791 let a = flagset::FlagSet::from(Flags::A);
793 let b = flagset::FlagSet::from(Flags::B);
794 assert_eq!(b.value_cmp(&a), Ok(Ordering::Less));
795 assert_eq!(a.der_cmp(&b), Ok(Ordering::Greater));
796
797 let all: [flagset::FlagSet<Flags>; 512] =
799 core::array::from_fn(|i| flagset::FlagSet::new(u16::try_from(i).unwrap()).unwrap());
800 for x in &all {
801 for y in &all {
802 let mut bx = [0u8; 8];
803 let mut by = [0u8; 8];
804 let ex = x.encode_to_slice(&mut bx).unwrap();
805 let ey = y.encode_to_slice(&mut by).unwrap();
806 assert_eq!(x.der_cmp(y), Ok(ex.cmp(ey)), "{x:?} vs {y:?}");
807 }
808 }
809 }
810}