1use super::{Class, Header, Length, Tag};
2use crate::ber::ber_read_element_content_as;
3use crate::ber::bitstring_to_u64;
4use crate::ber::integer::*;
5use crate::ber::MAX_RECURSION;
6use crate::error::BerError;
7use crate::oid::Oid;
8use alloc::borrow::ToOwned;
9use alloc::boxed::Box;
10use alloc::vec::Vec;
11use asn1_rs::ASN1DateTime;
12use asn1_rs::Any;
13#[cfg(feature = "bitvec")]
14use bitvec::{order::Msb0, slice::BitSlice};
15use core::convert::AsRef;
16use core::convert::From;
17use core::convert::TryFrom;
18use core::ops::Index;
19
20#[derive(Debug, Clone, PartialEq)]
28pub struct BerObject<'a> {
29 pub header: Header<'a>,
30 pub content: BerObjectContent<'a>,
31}
32
33#[derive(Debug, Clone, PartialEq)]
35#[allow(clippy::upper_case_acronyms)]
36pub enum BerObjectContent<'a> {
37 EndOfContent,
39 Boolean(bool),
41 Integer(&'a [u8]),
48 BitString(u8, BitStringObject<'a>),
50 OctetString(&'a [u8]),
52 Null,
54 Enum(u64),
56 OID(Oid<'a>),
58 RelativeOID(Oid<'a>),
60 NumericString(&'a str),
62 VisibleString(&'a str),
64 PrintableString(&'a str),
66 IA5String(&'a str),
68 UTF8String(&'a str),
70 T61String(&'a str),
72 VideotexString(&'a str),
74
75 BmpString(&'a str),
77 UniversalString(&'a [u8]),
79
80 Sequence(Vec<BerObject<'a>>),
82 Set(Vec<BerObject<'a>>),
84
85 UTCTime(ASN1DateTime),
87 GeneralizedTime(ASN1DateTime),
89
90 ObjectDescriptor(&'a str),
92 GraphicString(&'a str),
94 GeneralString(&'a str),
96
97 Optional(Option<Box<BerObject<'a>>>),
99 Tagged(Class, Tag, Box<BerObject<'a>>),
101
102 Unknown(Any<'a>),
104}
105
106impl<'a> BerObject<'a> {
107 #[inline]
112 pub const fn from_header_and_content<'o>(
113 header: Header<'o>,
114 content: BerObjectContent<'o>,
115 ) -> BerObject<'o> {
116 BerObject { header, content }
117 }
118
119 pub const fn from_obj(c: BerObjectContent) -> BerObject {
122 let class = Class::Universal;
123 let tag = c.tag();
124 let constructed = matches!(tag, Tag::Sequence | Tag::Set);
125 let header = Header::new(class, constructed, tag, Length::Definite(0));
126 BerObject { header, content: c }
127 }
128
129 pub const fn from_int_slice(i: &'a [u8]) -> BerObject<'a> {
131 let header = Header::new(Class::Universal, false, Tag::Integer, Length::Definite(0));
132 BerObject {
133 header,
134 content: BerObjectContent::Integer(i),
135 }
136 }
137
138 pub fn set_raw_tag(self, raw_tag: Option<&'a [u8]>) -> BerObject {
140 let header = self.header.with_raw_tag(raw_tag.map(|x| x.into()));
141 BerObject { header, ..self }
142 }
143
144 pub const fn from_seq(l: Vec<BerObject>) -> BerObject {
146 BerObject::from_obj(BerObjectContent::Sequence(l))
147 }
148
149 pub const fn from_set(l: Vec<BerObject>) -> BerObject {
151 BerObject::from_obj(BerObjectContent::Set(l))
152 }
153
154 pub fn as_i64(&self) -> Result<i64, BerError> {
169 self.content.as_i64()
170 }
171
172 pub fn as_i32(&self) -> Result<i32, BerError> {
187 self.content.as_i32()
188 }
189
190 pub fn as_u64(&self) -> Result<u64, BerError> {
205 self.content.as_u64()
206 }
207
208 pub fn as_u32(&self) -> Result<u32, BerError> {
224 self.content.as_u32()
225 }
226
227 pub fn as_bool(&self) -> Result<bool, BerError> {
230 self.content.as_bool()
231 }
232
233 pub fn as_oid(&self) -> Result<&Oid<'a>, BerError> {
236 self.content.as_oid()
237 }
238
239 pub fn as_oid_val(&self) -> Result<Oid<'a>, BerError> {
242 self.content.as_oid_val()
243 }
244
245 pub fn as_optional(&self) -> Result<Option<&BerObject<'a>>, BerError> {
248 self.content.as_optional()
249 }
250
251 pub fn as_tagged(&self) -> Result<(Class, Tag, &BerObject<'a>), BerError> {
254 self.content.as_tagged()
255 }
256
257 pub fn as_bitstring_ref(&self) -> Result<&BitStringObject, BerError> {
263 self.content.as_bitstring_ref()
264 }
265
266 pub fn as_bitstring(&self) -> Result<BitStringObject<'a>, BerError> {
269 self.content.as_bitstring()
270 }
271
272 #[cfg(feature = "bitvec")]
274 pub fn as_bitslice(&self) -> Result<&BitSlice<Msb0, u8>, BerError> {
275 self.content.as_bitslice()
276 }
277
278 pub fn as_sequence(&self) -> Result<&Vec<BerObject<'a>>, BerError> {
281 self.content.as_sequence()
282 }
283
284 pub fn as_set(&self) -> Result<&Vec<BerObject<'a>>, BerError> {
287 self.content.as_set()
288 }
289
290 pub fn as_slice(&self) -> Result<&'a [u8], BerError> {
295 self.content.as_slice()
296 }
297
298 pub fn as_str(&self) -> Result<&'a str, BerError> {
304 self.content.as_str()
305 }
306
307 #[inline]
309 pub const fn class(&self) -> Class {
310 self.header.class()
311 }
312
313 #[inline]
315 pub const fn tag(&self) -> Tag {
316 self.header.tag()
317 }
318
319 #[inline]
321 pub const fn length(&self) -> Length {
322 self.header.length()
323 }
324
325 #[inline]
327 pub const fn is_universal(&self) -> bool {
328 self.header.is_universal()
329 }
330 #[inline]
332 pub const fn is_application(&self) -> bool {
333 self.header.is_application()
334 }
335 #[inline]
337 pub const fn is_contextspecific(&self) -> bool {
338 self.header.is_contextspecific()
339 }
340 #[inline]
342 pub fn is_private(&self) -> bool {
343 self.header.is_private()
344 }
345
346 #[inline]
348 pub const fn is_primitive(&self) -> bool {
349 self.header.is_primitive()
350 }
351 #[inline]
353 pub const fn is_constructed(&self) -> bool {
354 self.header.is_constructed()
355 }
356
357 #[inline]
359 pub const fn assert_class(&self, class: Class) -> Result<(), BerError> {
360 self.header.assert_class(class)
361 }
362
363 #[inline]
365 pub const fn assert_tag(&self, tag: Tag) -> Result<(), BerError> {
366 self.header.assert_tag(tag)
367 }
368
369 #[inline]
371 pub const fn assert_constructed(&self) -> Result<(), BerError> {
372 self.header.assert_constructed()
373 }
374
375 #[inline]
377 pub const fn assert_primitive(&self) -> Result<(), BerError> {
378 self.header.assert_primitive()
379 }
380}
381
382impl<'a> From<Oid<'a>> for BerObject<'a> {
384 fn from(oid: Oid<'a>) -> BerObject<'a> {
385 BerObject::from_obj(BerObjectContent::OID(oid))
386 }
387}
388
389impl<'a> From<BerObjectContent<'a>> for BerObject<'a> {
391 fn from(obj: BerObjectContent<'a>) -> BerObject<'a> {
392 BerObject::from_obj(obj)
393 }
394}
395
396impl<'a> BerObjectContent<'a> {
397 pub fn as_i64(&self) -> Result<i64, BerError> {
412 if let BerObjectContent::Integer(bytes) = self {
413 let result = if is_highest_bit_set(bytes) {
414 <i64>::from_be_bytes(decode_array_int8(bytes)?)
415 } else {
416 <u64>::from_be_bytes(decode_array_uint8(bytes)?) as i64
417 };
418 Ok(result)
419 } else {
420 Err(BerError::BerValueError)
421 }
422 }
423
424 pub fn as_i32(&self) -> Result<i32, BerError> {
439 if let BerObjectContent::Integer(bytes) = self {
440 let result = if is_highest_bit_set(bytes) {
441 <i32>::from_be_bytes(decode_array_int4(bytes)?)
442 } else {
443 <u32>::from_be_bytes(decode_array_uint4(bytes)?) as i32
444 };
445 Ok(result)
446 } else {
447 Err(BerError::BerValueError)
448 }
449 }
450
451 pub fn as_u64(&self) -> Result<u64, BerError> {
466 match self {
467 BerObjectContent::Integer(i) => {
468 let result = <u64>::from_be_bytes(decode_array_uint8(i)?);
469 Ok(result)
470 }
471 BerObjectContent::BitString(ignored_bits, data) => {
472 bitstring_to_u64(*ignored_bits as usize, data)
473 }
474 BerObjectContent::Enum(i) => Ok(*i),
475 _ => Err(BerError::BerTypeError),
476 }
477 }
478
479 pub fn as_u32(&self) -> Result<u32, BerError> {
495 match self {
496 BerObjectContent::Integer(i) => {
497 let result = <u32>::from_be_bytes(decode_array_uint4(i)?);
498 Ok(result)
499 }
500 BerObjectContent::BitString(ignored_bits, data) => {
501 bitstring_to_u64(*ignored_bits as usize, data).and_then(|x| {
502 if x > u64::from(core::u32::MAX) {
503 Err(BerError::IntegerTooLarge)
504 } else {
505 Ok(x as u32)
506 }
507 })
508 }
509 BerObjectContent::Enum(i) => {
510 if *i > u64::from(core::u32::MAX) {
511 Err(BerError::IntegerTooLarge)
512 } else {
513 Ok(*i as u32)
514 }
515 }
516 _ => Err(BerError::BerTypeError),
517 }
518 }
519
520 pub fn as_bool(&self) -> Result<bool, BerError> {
521 match *self {
522 BerObjectContent::Boolean(b) => Ok(b),
523 _ => Err(BerError::BerTypeError),
524 }
525 }
526
527 pub fn as_oid(&self) -> Result<&Oid<'a>, BerError> {
528 match *self {
529 BerObjectContent::OID(ref o) => Ok(o),
530 BerObjectContent::RelativeOID(ref o) => Ok(o),
531 _ => Err(BerError::BerTypeError),
532 }
533 }
534
535 pub fn as_oid_val(&self) -> Result<Oid<'a>, BerError> {
536 self.as_oid().map(|o| o.clone())
537 }
538
539 pub fn as_optional(&self) -> Result<Option<&BerObject<'a>>, BerError> {
540 match *self {
541 BerObjectContent::Optional(Some(ref o)) => Ok(Some(o)),
542 BerObjectContent::Optional(None) => Ok(None),
543 _ => Err(BerError::BerTypeError),
544 }
545 }
546
547 pub fn as_tagged(&self) -> Result<(Class, Tag, &BerObject<'a>), BerError> {
548 match *self {
549 BerObjectContent::Tagged(class, tag, ref o) => Ok((class, tag, o.as_ref())),
550 _ => Err(BerError::BerTypeError),
551 }
552 }
553
554 pub fn as_bitstring_ref(&self) -> Result<&BitStringObject, BerError> {
555 match *self {
556 BerObjectContent::BitString(_, ref b) => Ok(b),
557 _ => Err(BerError::BerTypeError),
558 }
559 }
560
561 pub fn as_bitstring(&self) -> Result<BitStringObject<'a>, BerError> {
562 match *self {
563 BerObjectContent::BitString(_, ref b) => Ok(b.to_owned()),
564 _ => Err(BerError::BerTypeError),
565 }
566 }
567
568 #[cfg(feature = "bitvec")]
570 pub fn as_bitslice(&self) -> Result<&BitSlice<Msb0, u8>, BerError> {
571 self.as_slice()
572 .and_then(|s| BitSlice::<Msb0, _>::from_slice(s).map_err(|_| BerError::BerValueError))
573 }
574
575 pub fn as_sequence(&self) -> Result<&Vec<BerObject<'a>>, BerError> {
576 match *self {
577 BerObjectContent::Sequence(ref s) => Ok(s),
578 _ => Err(BerError::BerTypeError),
579 }
580 }
581
582 pub fn as_set(&self) -> Result<&Vec<BerObject<'a>>, BerError> {
583 match *self {
584 BerObjectContent::Set(ref s) => Ok(s),
585 _ => Err(BerError::BerTypeError),
586 }
587 }
588
589 #[rustfmt::skip]
590 pub fn as_slice(&self) -> Result<&'a [u8],BerError> {
591 match *self {
592 BerObjectContent::NumericString(s) |
593 BerObjectContent::BmpString(s) |
594 BerObjectContent::VisibleString(s) |
595 BerObjectContent::PrintableString(s) |
596 BerObjectContent::GeneralString(s) |
597 BerObjectContent::ObjectDescriptor(s) |
598 BerObjectContent::GraphicString(s) |
599 BerObjectContent::T61String(s) |
600 BerObjectContent::VideotexString(s) |
601 BerObjectContent::UTF8String(s) |
602 BerObjectContent::IA5String(s) => Ok(s.as_ref()),
603 BerObjectContent::Integer(s) |
604 BerObjectContent::BitString(_,BitStringObject{data:s}) |
605 BerObjectContent::OctetString(s) |
606 BerObjectContent::UniversalString(s) => Ok(s),
607 BerObjectContent::Unknown(ref any) => Ok(any.data),
608 _ => Err(BerError::BerTypeError),
609 }
610 }
611
612 #[rustfmt::skip]
613 pub fn as_str(&self) -> Result<&'a str,BerError> {
614 match *self {
615 BerObjectContent::NumericString(s) |
616 BerObjectContent::BmpString(s) |
617 BerObjectContent::VisibleString(s) |
618 BerObjectContent::PrintableString(s) |
619 BerObjectContent::GeneralString(s) |
620 BerObjectContent::ObjectDescriptor(s) |
621 BerObjectContent::GraphicString(s) |
622 BerObjectContent::T61String(s) |
623 BerObjectContent::VideotexString(s) |
624 BerObjectContent::UTF8String(s) |
625 BerObjectContent::IA5String(s) => Ok(s),
626 _ => Err(BerError::BerTypeError),
627 }
628 }
629
630 #[rustfmt::skip]
631 const fn tag(&self) -> Tag {
632 match self {
633 BerObjectContent::EndOfContent => Tag::EndOfContent,
634 BerObjectContent::Boolean(_) => Tag::Boolean,
635 BerObjectContent::Integer(_) => Tag::Integer,
636 BerObjectContent::BitString(_,_) => Tag::BitString,
637 BerObjectContent::OctetString(_) => Tag::OctetString,
638 BerObjectContent::Null => Tag::Null,
639 BerObjectContent::Enum(_) => Tag::Enumerated,
640 BerObjectContent::OID(_) => Tag::Oid,
641 BerObjectContent::NumericString(_) => Tag::NumericString,
642 BerObjectContent::VisibleString(_) => Tag::VisibleString,
643 BerObjectContent::PrintableString(_) => Tag::PrintableString,
644 BerObjectContent::IA5String(_) => Tag::Ia5String,
645 BerObjectContent::UTF8String(_) => Tag::Utf8String,
646 BerObjectContent::RelativeOID(_) => Tag::RelativeOid,
647 BerObjectContent::T61String(_) => Tag::T61String,
648 BerObjectContent::VideotexString(_) => Tag::VideotexString,
649 BerObjectContent::BmpString(_) => Tag::BmpString,
650 BerObjectContent::UniversalString(_) => Tag::UniversalString,
651 BerObjectContent::Sequence(_) => Tag::Sequence,
652 BerObjectContent::Set(_) => Tag::Set,
653 BerObjectContent::UTCTime(_) => Tag::UtcTime,
654 BerObjectContent::GeneralizedTime(_) => Tag::GeneralizedTime,
655 BerObjectContent::ObjectDescriptor(_) => Tag::ObjectDescriptor,
656 BerObjectContent::GraphicString(_) => Tag::GraphicString,
657 BerObjectContent::GeneralString(_) => Tag::GeneralString,
658 BerObjectContent::Tagged(_,x,_) => *x,
659 BerObjectContent::Unknown(any) => any.tag(),
660 BerObjectContent::Optional(Some(obj)) => obj.content.tag(),
661 BerObjectContent::Optional(None) => Tag(0x00), }
663 }
664}
665
666#[cfg(feature = "bigint")]
667#[cfg_attr(docsrs, doc(cfg(feature = "bigint")))]
668use num_bigint::{BigInt, BigUint};
669
670#[cfg(feature = "bigint")]
671#[cfg_attr(docsrs, doc(cfg(feature = "bigint")))]
672impl<'a> BerObject<'a> {
673 pub fn as_bigint(&self) -> Result<BigInt, BerError> {
689 match self.content {
690 BerObjectContent::Integer(s) => Ok(BigInt::from_signed_bytes_be(s)),
691 _ => Err(BerError::BerValueError),
692 }
693 }
694
695 pub fn as_biguint(&self) -> Result<BigUint, BerError> {
711 match self.content {
712 BerObjectContent::Integer(s) => {
713 if is_highest_bit_set(s) {
714 return Err(BerError::IntegerNegative);
715 }
716 Ok(BigUint::from_bytes_be(s))
717 }
718 _ => Err(BerError::BerValueError),
719 }
720 }
721}
722
723impl<'a> TryFrom<Any<'a>> for BerObject<'a> {
724 type Error = asn1_rs::Error;
725
726 fn try_from(any: Any<'a>) -> Result<Self, Self::Error> {
727 let (header, data) = (any.header, any.data);
728 let (_, content) = ber_read_element_content_as(
729 data,
730 header.tag(),
731 header.length(),
732 header.constructed(),
733 MAX_RECURSION,
734 )?;
735 let obj = BerObject::from_header_and_content(header, content);
736 Ok(obj)
737 }
738}
739
740impl<'a, 'b> TryFrom<&'b Any<'a>> for BerObject<'a> {
741 type Error = asn1_rs::Error;
742
743 fn try_from(any: &'b Any<'a>) -> Result<Self, Self::Error> {
744 let (header, data) = (any.header.clone(), any.data);
745 let (_, content) = ber_read_element_content_as(
746 data,
747 header.tag(),
748 header.length(),
749 header.constructed(),
750 MAX_RECURSION,
751 )?;
752 let obj = BerObject::from_header_and_content(header, content);
753 Ok(obj)
754 }
755}
756
757impl<'a> IntoIterator for BerObject<'a> {
759 type Item = BerObject<'a>;
760 type IntoIter = BerObjectIntoIterator<'a>;
761
762 fn into_iter(self) -> Self::IntoIter {
763 BerObjectIntoIterator { val: self, idx: 0 }
768 }
769}
770
771#[derive(Debug)]
772pub struct BerObjectIntoIterator<'a> {
773 val: BerObject<'a>,
774 idx: usize,
775}
776
777impl<'a> Iterator for BerObjectIntoIterator<'a> {
778 type Item = BerObject<'a>;
779 fn next(&mut self) -> Option<BerObject<'a>> {
780 let res = match self.val.content {
786 BerObjectContent::Sequence(ref v) if self.idx < v.len() => Some(v[self.idx].clone()),
787 BerObjectContent::Set(ref v) if self.idx < v.len() => Some(v[self.idx].clone()),
788 _ => {
789 if self.idx == 0 {
790 Some(self.val.clone())
791 } else {
792 None
793 }
794 }
795 };
796 self.idx += 1;
797 res
798 }
799}
800
801#[derive(Debug)]
810pub struct BerObjectRefIterator<'a> {
811 obj: &'a BerObject<'a>,
812 idx: usize,
813}
814
815impl<'a> Iterator for BerObjectRefIterator<'a> {
816 type Item = &'a BerObject<'a>;
817 fn next(&mut self) -> Option<&'a BerObject<'a>> {
818 let res = match (self.obj).content {
819 BerObjectContent::Sequence(ref v) if self.idx < v.len() => Some(&v[self.idx]),
820 BerObjectContent::Set(ref v) if self.idx < v.len() => Some(&v[self.idx]),
821 _ => None,
822 };
823 self.idx += 1;
824 res
825 }
826}
827
828impl<'a> BerObject<'a> {
829 pub fn ref_iter(&'a self) -> BerObjectRefIterator<'a> {
830 BerObjectRefIterator { obj: self, idx: 0 }
831 }
832}
833
834impl<'a> Index<usize> for BerObject<'a> {
835 type Output = BerObject<'a>;
836
837 fn index(&self, idx: usize) -> &BerObject<'a> {
838 match (self).content {
839 BerObjectContent::Sequence(ref v) if idx < v.len() => &v[idx],
840 BerObjectContent::Set(ref v) if idx < v.len() => &v[idx],
841 _ => panic!("Try to index BerObjectContent which is not constructed"),
842 }
843 }
849}
850
851#[derive(Clone, Debug, PartialEq)]
853pub struct BitStringObject<'a> {
854 pub data: &'a [u8],
855}
856
857impl<'a> BitStringObject<'a> {
858 pub fn is_set(&self, bitnum: usize) -> bool {
860 let byte_pos = bitnum / 8;
861 if byte_pos >= self.data.len() {
862 return false;
863 }
864 let b = 7 - (bitnum % 8);
865 (self.data[byte_pos] & (1 << b)) != 0
866 }
867
868 #[cfg(feature = "bitvec")]
870 pub fn as_bitslice(&self) -> Option<&BitSlice<Msb0, u8>> {
871 BitSlice::<Msb0, _>::from_slice(self.data).ok()
872 }
873}
874
875impl<'a> AsRef<[u8]> for BitStringObject<'a> {
876 fn as_ref(&self) -> &[u8] {
877 self.data
878 }
879}
880
881#[cfg(test)]
882mod tests {
883 use asn1_rs::{Any, FromDer};
884 use core::convert::TryFrom;
885
886 use crate::ber::*;
887 use crate::oid::*;
888
889 #[test]
890 fn ber_from_any() {
891 let bytes = &[0x02, 0x03, 0x01, 0x00, 0x01];
892
893 let (rem, any) = Any::from_der(bytes).expect("parsing failed");
894 assert!(rem.is_empty());
895 let obj = BerObject::try_from(any).expect("try_from(any) failed");
896 assert_eq!(obj.as_u32(), Ok(0x10001_u32));
897 }
898
899 #[test]
900 fn test_der_as_u64() {
901 let der_obj = BerObject::from_int_slice(b"\x01\x00\x02");
902 assert_eq!(der_obj.as_u64(), Ok(0x10002));
903 }
904
905 #[test]
906 fn test_ber_as_u64_bitstring() {
907 let (_, ber_obj) = parse_ber_bitstring(b"\x03\x04\x06\x6e\x5d\xc0").unwrap();
908 assert_eq!(ber_obj.as_u64(), Ok(0b011011100101110111));
909
910 let (_, ber_obj_with_nonzero_padding) =
911 parse_ber_bitstring(b"\x03\x04\x06\x6e\x5d\xe0").unwrap();
912 assert_eq!(
913 ber_obj_with_nonzero_padding.as_u64(),
914 Ok(0b011011100101110111)
915 );
916 }
917
918 #[test]
919 fn test_der_seq_iter() {
920 let der_obj = BerObject::from_obj(BerObjectContent::Sequence(vec![
921 BerObject::from_int_slice(b"\x01\x00\x01"),
922 BerObject::from_int_slice(b"\x01\x00\x00"),
923 ]));
924 let expected_values = vec![
925 BerObject::from_int_slice(b"\x01\x00\x01"),
926 BerObject::from_int_slice(b"\x01\x00\x00"),
927 ];
928
929 for (idx, v) in der_obj.ref_iter().enumerate() {
930 assert_eq!((*v), expected_values[idx]);
932 }
933 }
934
935 #[test]
936 fn test_der_from_oid() {
937 let obj: BerObject = Oid::from(&[1, 2]).unwrap().into();
938 let expected = BerObject::from_obj(BerObjectContent::OID(Oid::from(&[1, 2]).unwrap()));
939
940 assert_eq!(obj, expected);
941 }
942
943 #[test]
944 fn test_der_bitstringobject() {
945 let obj = BitStringObject {
946 data: &[0x0f, 0x00, 0x40],
947 };
948 assert!(!obj.is_set(0));
949 assert!(obj.is_set(7));
950 assert!(!obj.is_set(9));
951 assert!(obj.is_set(17));
952 }
953
954 #[cfg(feature = "bitvec")]
955 #[test]
956 fn test_der_bitslice() {
957 use std::string::String;
958 let obj = BitStringObject {
959 data: &[0x0f, 0x00, 0x40],
960 };
961 let slice = obj.as_bitslice().expect("as_bitslice");
962 assert_eq!(slice.get(0).as_deref(), Some(&false));
963 assert_eq!(slice.get(7).as_deref(), Some(&true));
964 assert_eq!(slice.get(9).as_deref(), Some(&false));
965 assert_eq!(slice.get(17).as_deref(), Some(&true));
966 let s = slice.iter().fold(String::with_capacity(24), |mut acc, b| {
967 acc += if *b { "1" } else { "0" };
968 acc
969 });
970 assert_eq!(&s, "000011110000000001000000");
971 }
972
973 #[test]
974 fn test_der_bistringobject_asref() {
975 fn assert_equal<T: AsRef<[u8]>>(s: T, b: &[u8]) {
976 assert_eq!(s.as_ref(), b);
977 }
978 let b: &[u8] = &[0x0f, 0x00, 0x40];
979 let obj = BitStringObject { data: b };
980 assert_equal(obj, b);
981 }
982
983 #[cfg(feature = "bigint")]
984 #[test]
985 fn test_der_to_bigint() {
986 let obj = BerObject::from_obj(BerObjectContent::Integer(b"\x01\x00\x01"));
987 let expected = ::num_bigint::BigInt::from(0x10001);
988
989 assert_eq!(obj.as_bigint(), Ok(expected));
990 }
991
992 #[cfg(feature = "bigint")]
993 #[test]
994 fn test_der_to_biguint() {
995 let obj = BerObject::from_obj(BerObjectContent::Integer(b"\x01\x00\x01"));
996 let expected = ::num_bigint::BigUint::from(0x10001_u32);
997
998 assert_eq!(obj.as_biguint(), Ok(expected));
999 }
1000}