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
251mod unused_bits {
253 use core::ops::Deref;
254
255 use crate::{Result, Tag};
256
257 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
261 pub(crate) struct UnusedBits(u8);
262
263 impl UnusedBits {
264 pub const MAX_UNUSED_BITS: u8 = 7;
266
267 pub fn new(unused_bits: u8, bytes: &[u8]) -> Result<Self> {
270 if (unused_bits > Self::MAX_UNUSED_BITS) || (unused_bits != 0 && bytes.is_empty()) {
271 Err(Tag::BitString.value_error().into())
272 } else {
273 Ok(Self(unused_bits))
274 }
275 }
276 }
277 impl Deref for UnusedBits {
278 type Target = u8;
279
280 fn deref(&self) -> &Self::Target {
281 &self.0
282 }
283 }
284}
285
286#[cfg(feature = "arbitrary")]
289impl<'a> arbitrary::Arbitrary<'a> for BitStringRef<'a> {
290 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
291 Self::new(
292 u.int_in_range(0..=UnusedBits::MAX_UNUSED_BITS)?,
293 <&'a BytesRef>::arbitrary(u)?.as_slice(),
294 )
295 .map_err(|_| arbitrary::Error::IncorrectFormat)
296 }
297
298 fn size_hint(depth: usize) -> (usize, Option<usize>) {
299 arbitrary::size_hint::and(u8::size_hint(depth), <&'a BytesRef>::size_hint(depth))
300 }
301}
302
303#[cfg(feature = "alloc")]
304pub use self::allocating::BitString;
305
306#[cfg(feature = "alloc")]
307mod allocating {
308 use super::*;
309 use crate::{asn1::Any, referenced::*};
310 use alloc::vec::Vec;
311
312 #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
317 pub struct BitString {
318 unused_bits: UnusedBits,
320
321 inner: Vec<u8>,
323 }
324
325 impl BitString {
326 pub const MAX_UNUSED_BITS: u8 = 7;
328
329 pub fn new(unused_bits: u8, bytes: impl Into<Vec<u8>>) -> Result<Self> {
340 let inner = bytes.into();
341
342 let ref_value = BitStringRef::new(unused_bits, &inner)?;
344
345 Ok(BitString {
346 unused_bits: ref_value.unused_bits,
347 inner,
348 })
349 }
350
351 pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
358 Self::new(0, bytes)
359 }
360
361 #[must_use]
364 pub fn unused_bits(&self) -> u8 {
365 *self.unused_bits
366 }
367
368 #[must_use]
370 pub fn has_unused_bits(&self) -> bool {
371 *self.unused_bits != 0
372 }
373
374 pub(crate) fn bytes_ref(&self) -> &BytesRef {
376 BytesRef::new_unchecked(&self.inner)
378 }
379
380 fn bit_len_checked(&self) -> Option<usize> {
384 BitStringRef::new_unchecked(self.unused_bits, self.bytes_ref()).bit_len_checked()
385 }
386
387 #[must_use]
389 pub fn bit_len(&self) -> usize {
390 let bit_len = self.bit_len_checked();
391 debug_assert!(bit_len.is_some());
392
393 bit_len.unwrap_or(0)
395 }
396
397 #[must_use]
399 pub fn is_empty(&self) -> bool {
400 self.inner.is_empty()
401 }
402
403 #[must_use]
411 pub fn as_bytes(&self) -> Option<&[u8]> {
412 if self.has_unused_bits() {
413 None
414 } else {
415 Some(self.raw_bytes())
416 }
417 }
418
419 #[must_use]
421 pub fn raw_bytes(&self) -> &[u8] {
422 self.inner.as_slice()
423 }
424
425 #[must_use]
427 pub fn bits(&self) -> BitStringIter<'_> {
428 BitStringRef::from(self).bits()
429 }
430
431 #[must_use]
433 pub fn get(&self, position: usize) -> Option<bool> {
434 BitStringRef::from(self).get(position)
435 }
436 }
437
438 impl_any_conversions!(BitString);
439
440 impl<'a> DecodeValue<'a> for BitString {
441 type Error = Error;
442
443 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
444 let inner_len = (header.length() - Length::ONE)?;
445 let unused_bits = reader.read_byte()?;
446 let inner = reader.read_vec(inner_len)?;
447 Self::new(unused_bits, inner)
448 }
449 }
450
451 impl EncodeValue for BitString {
452 fn value_len(&self) -> Result<Length> {
453 Length::ONE + Length::try_from(self.inner.len())?
454 }
455
456 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
457 writer.write_byte(*self.unused_bits)?;
458 writer.write(&self.inner)
459 }
460 }
461
462 impl FixedTag for BitString {
463 const TAG: Tag = Tag::BitString;
464 }
465
466 impl<'a> From<&'a BitString> for BitStringRef<'a> {
467 fn from(bit_string: &'a BitString) -> BitStringRef<'a> {
468 BitStringRef::new_unchecked(bit_string.unused_bits, bit_string.bytes_ref())
470 }
471 }
472
473 impl From<BitStringRef<'_>> for Any {
474 fn from(bit_string_ref: BitStringRef<'_>) -> Any {
475 Any::from(&bit_string_ref)
476 }
477 }
478
479 impl From<&BitStringRef<'_>> for Any {
480 fn from(bit_string_ref: &BitStringRef<'_>) -> Any {
481 Any::encode_from(bit_string_ref).expect("should encode successfully")
482 }
483 }
484
485 impl From<BitString> for Any {
486 fn from(bit_string: BitString) -> Any {
487 bit_string.owned_to_ref().into()
488 }
489 }
490
491 impl From<&BitString> for Any {
492 fn from(bit_string: &BitString) -> Any {
493 bit_string.owned_to_ref().into()
494 }
495 }
496
497 impl<'a> TryFrom<&'a Vec<u8>> for BitStringRef<'a> {
499 type Error = Error;
500
501 fn try_from(bytes: &'a Vec<u8>) -> Result<BitStringRef<'a>> {
502 BitStringRef::from_bytes(bytes)
503 }
504 }
505
506 impl<'a> TryFrom<BitStringRef<'a>> for Vec<u8> {
508 type Error = Error;
509
510 fn try_from(bit_string: BitStringRef<'a>) -> Result<Vec<u8>> {
511 bit_string
512 .as_bytes()
513 .map(<[u8]>::to_vec)
514 .ok_or_else(|| Tag::BitString.value_error().into())
515 }
516 }
517
518 impl ValueOrd for BitString {
519 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
520 match self.unused_bits.cmp(&other.unused_bits) {
521 Ordering::Equal => self.inner.der_cmp(&other.inner),
522 ordering => Ok(ordering),
523 }
524 }
525 }
526
527 #[cfg(feature = "arbitrary")]
530 impl<'a> arbitrary::Arbitrary<'a> for BitString {
531 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
532 Self::new(
533 u.int_in_range(0..=Self::MAX_UNUSED_BITS)?,
534 <&'a BytesRef>::arbitrary(u)?.as_slice(),
535 )
536 .map_err(|_| arbitrary::Error::IncorrectFormat)
537 }
538
539 fn size_hint(depth: usize) -> (usize, Option<usize>) {
540 arbitrary::size_hint::and(u8::size_hint(depth), <&'a BytesRef>::size_hint(depth))
541 }
542 }
543
544 impl<'a> RefToOwned<'a> for BitStringRef<'a> {
545 type Owned = BitString;
546 fn ref_to_owned(&self) -> Self::Owned {
547 BitString {
548 unused_bits: self.unused_bits,
549 inner: Vec::from(self.inner.as_slice()),
550 }
551 }
552 }
553
554 impl OwnedToRef for BitString {
555 type Borrowed<'a> = BitStringRef<'a>;
556 fn owned_to_ref(&self) -> Self::Borrowed<'_> {
557 self.into()
558 }
559 }
560}
561
562#[derive(Debug)]
564pub struct BitStringIter<'a> {
565 bit_string: BitStringRef<'a>,
567
568 position: usize,
570}
571
572impl Iterator for BitStringIter<'_> {
573 type Item = bool;
574
575 #[allow(clippy::arithmetic_side_effects)]
576 fn next(&mut self) -> Option<bool> {
577 if self.position >= self.bit_string.bit_len() {
578 return None;
579 }
580
581 let byte = self.bit_string.raw_bytes().get(self.position / 8)?;
582 let bit = 1u8 << (7 - (self.position % 8));
583 self.position = self.position.checked_add(1)?;
584 Some(byte & bit != 0)
585 }
586
587 fn size_hint(&self) -> (usize, Option<usize>) {
588 let len = self.bit_string.bit_len().saturating_sub(self.position);
589 (len, Some(len))
590 }
591}
592
593impl ExactSizeIterator for BitStringIter<'_> {
594 fn len(&self) -> usize {
595 self.bit_string.bit_len()
596 }
597}
598
599impl FusedIterator for BitStringIter<'_> {}
600
601#[cfg(feature = "flagset")]
602impl<T: flagset::Flags> FixedTag for flagset::FlagSet<T> {
603 const TAG: Tag = BitStringRef::TAG;
604}
605
606#[cfg(feature = "flagset")]
607impl<T> ValueOrd for flagset::FlagSet<T>
608where
609 T: flagset::Flags,
610 T::Type: Ord,
611{
612 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
613 Ok(self.bits().cmp(&other.bits()))
614 }
615}
616
617#[cfg(feature = "flagset")]
618#[allow(clippy::arithmetic_side_effects)]
619impl<'a, T> DecodeValue<'a> for flagset::FlagSet<T>
620where
621 T: flagset::Flags,
622 T::Type: From<bool>,
623 T::Type: core::ops::Shl<usize, Output = T::Type>,
624{
625 type Error = Error;
626
627 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
628 let position = reader.position();
629 let bits = BitStringRef::decode_value(reader, header)?;
630
631 let mut flags = T::none().bits();
632
633 if bits.bit_len() > size_of_val(&flags) * 8 {
634 return Err(Error::new(ErrorKind::Overlength, position));
635 }
636
637 for (i, bit) in bits.bits().enumerate() {
638 flags |= T::Type::from(bit) << i;
639 }
640
641 Ok(Self::new_truncated(flags))
642 }
643}
644
645#[cfg(feature = "flagset")]
646#[allow(clippy::arithmetic_side_effects)]
647#[inline(always)]
648fn encode_flagset<T>(set: &flagset::FlagSet<T>) -> (usize, [u8; 16])
649where
650 T: flagset::Flags,
651 u128: From<T::Type>,
652{
653 let bits: u128 = set.bits().into();
654 let mut swap = 0u128;
655
656 for i in 0..128 {
657 let on = bits & (1 << i);
658 swap |= on >> i << (128 - i - 1);
659 }
660
661 (bits.leading_zeros() as usize, swap.to_be_bytes())
662}
663
664#[cfg(feature = "flagset")]
665#[allow(clippy::cast_possible_truncation, clippy::arithmetic_side_effects)]
666impl<T: flagset::Flags> EncodeValue for flagset::FlagSet<T>
667where
668 T::Type: From<bool>,
669 T::Type: core::ops::Shl<usize, Output = T::Type>,
670 u128: From<T::Type>,
671{
672 fn value_len(&self) -> Result<Length> {
673 let (lead, buff) = encode_flagset(self);
674 let buff = &buff[..buff.len() - lead / 8];
675 BitStringRef::new((lead % 8) as u8, buff)?.value_len()
676 }
677
678 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
679 let (lead, buff) = encode_flagset(self);
680 let buff = &buff[..buff.len() - lead / 8];
681 BitStringRef::new((lead % 8) as u8, buff)?.encode_value(writer)
682 }
683}
684
685#[cfg(test)]
686#[allow(clippy::unwrap_used)]
687mod tests {
688 use core::cmp::Ordering;
689
690 use super::{BitStringRef, Result, Tag};
691 use crate::asn1::AnyRef;
692 use hex_literal::hex;
693
694 fn parse_bitstring(bytes: &[u8]) -> Result<BitStringRef<'_>> {
696 AnyRef::new(Tag::BitString, bytes)?.try_into()
697 }
698
699 #[test]
700 fn decode_empty_bitstring() {
701 let bs = parse_bitstring(&hex!("00")).unwrap();
702 assert_eq!(bs.as_bytes().unwrap(), &[]);
703 }
704
705 #[test]
706 fn decode_non_empty_bitstring() {
707 let bs = parse_bitstring(&hex!("00010203")).unwrap();
708 assert_eq!(bs.as_bytes().unwrap(), &[0x01, 0x02, 0x03]);
709 }
710
711 #[test]
712 fn decode_bitstring_with_unused_bits() {
713 let bs = parse_bitstring(&hex!("066e5dc0")).unwrap();
714 assert_eq!(bs.unused_bits(), 6);
715 assert_eq!(bs.raw_bytes(), &hex!("6e5dc0"));
716
717 let mut bits = bs.bits();
719 assert_eq!(bits.len(), 18);
720
721 for bit in [0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1] {
722 assert_eq!(u8::from(bits.next().unwrap()), bit);
723 }
724
725 assert_eq!(bits.next(), None);
727 assert_eq!(bits.next(), None);
728 }
729
730 #[test]
731 fn reject_unused_bits_in_empty_string() {
732 assert_eq!(
733 parse_bitstring(&[0x03]).err().unwrap().kind(),
734 Tag::BitString.value_error()
735 );
736 }
737
738 #[test]
739 fn bitstring_valueord_value_cmp() {
740 use crate::ord::DerOrd;
741
742 let bs1 = parse_bitstring(&hex!("00010204")).unwrap();
743 let bs2 = parse_bitstring(&hex!("00010203")).unwrap();
744 assert_eq!(bs1.der_cmp(&bs2), Ok(Ordering::Greater));
745 }
746}