| use asn1_rs::*; |
| use hex_literal::hex; |
| use nom::sequence::pair; |
| use nom::Needed; |
| use std::collections::BTreeSet; |
| use std::convert::TryInto; |
| |
| #[test] |
| fn from_der_any() { |
| let input = &hex!("02 01 02 ff ff"); |
| let (rem, result) = Any::from_der(input).expect("parsing failed"); |
| // dbg!(&result); |
| assert_eq!(rem, &[0xff, 0xff]); |
| assert_eq!(result.header.tag(), Tag::Integer); |
| } |
| |
| #[test] |
| fn from_der_any_into() { |
| let input = &hex!("02 01 02 ff ff"); |
| let (rem, result) = Any::from_der(input).expect("parsing failed"); |
| assert_eq!(rem, &[0xff, 0xff]); |
| assert_eq!(result.header.tag(), Tag::Integer); |
| let i: u32 = result.try_into().unwrap(); |
| assert_eq!(i, 2); |
| // |
| let (_, result) = Any::from_der(input).expect("parsing failed"); |
| let i = result.u32().unwrap(); |
| assert_eq!(i, 2); |
| } |
| |
| #[test] |
| fn from_der_bitstring() { |
| // |
| // correct DER encoding |
| // |
| let input = &hex!("03 04 06 6e 5d c0"); |
| let (rem, result) = BitString::from_der(input).expect("parsing failed"); |
| assert!(rem.is_empty()); |
| assert_eq!(result.unused_bits, 6); |
| assert_eq!(&result.data[..], &input[3..]); |
| // |
| // correct encoding, but wrong padding bits (not all set to 0) |
| // |
| let input = &hex!("03 04 06 6e 5d e0"); |
| let res = BitString::from_der(input); |
| assert_eq!( |
| res, |
| Err(Err::Error(Error::DerConstraintFailed( |
| DerConstraint::UnusedBitsNotZero |
| ))) |
| ); |
| // |
| // long form of length (invalid, < 127) |
| // |
| // let input = &hex!("03 81 04 06 6e 5d c0"); |
| // let res = BitString::from_der(input); |
| // assert_eq!(res, Err(Err::Error(Error::DerConstraintFailed))); |
| } |
| |
| #[test] |
| fn from_der_bitstring_constructed() { |
| let bytes: &[u8] = &hex!("23 81 0c 03 03 00 0a 3b 03 05 04 5f 29 1c d0"); |
| assert_eq!( |
| BitString::from_der(bytes), |
| Err(Err::Error(Error::ConstructUnexpected)) |
| ); |
| } |
| |
| #[test] |
| fn from_der_bmpstring() { |
| // taken from https://docs.microsoft.com/en-us/windows/win32/seccertenroll/about-bmpstring |
| let input = &hex!("1e 08 00 55 00 73 00 65 00 72"); |
| let (rem, result) = BmpString::from_der(input).expect("parsing failed"); |
| assert_eq!(result.as_ref(), "User"); |
| assert_eq!(rem, &[]); |
| } |
| |
| #[test] |
| fn from_der_bool() { |
| let input = &hex!("01 01 00"); |
| let (rem, result) = Boolean::from_der(input).expect("parsing failed"); |
| assert!(rem.is_empty()); |
| assert_eq!(result, Boolean::FALSE); |
| // |
| let input = &hex!("01 01 ff"); |
| let (rem, result) = Boolean::from_der(input).expect("parsing failed"); |
| assert!(rem.is_empty()); |
| assert_eq!(result, Boolean::TRUE); |
| assert!(result.bool()); |
| // |
| let input = &hex!("01 01 7f"); |
| let res = Boolean::from_der(input); |
| assert_eq!( |
| res, |
| Err(Err::Error(Error::DerConstraintFailed( |
| DerConstraint::InvalidBoolean |
| ))) |
| ); |
| // bool type |
| let input = &hex!("01 01 00"); |
| let (rem, result) = <bool>::from_der(input).expect("parsing failed"); |
| assert!(rem.is_empty()); |
| assert!(!result); |
| } |
| |
| #[test] |
| fn from_der_embedded_pdv() { |
| let input = &hex!("2b 0d a0 07 81 05 2a 03 04 05 06 82 02 aa a0"); |
| let (rem, result) = EmbeddedPdv::from_der(input).expect("parsing failed"); |
| assert_eq!(rem, &[]); |
| assert_eq!( |
| result.identification, |
| PdvIdentification::Syntax(Oid::from(&[1, 2, 3, 4, 5, 6]).unwrap()) |
| ); |
| assert_eq!(result.data_value, &[0xaa, 0xa0]); |
| } |
| |
| #[test] |
| fn from_der_enumerated() { |
| let input = &hex!("0a 01 02"); |
| let (rem, result) = Enumerated::from_der(input).expect("parsing failed"); |
| assert_eq!(rem, &[]); |
| assert_eq!(result.0, 2); |
| } |
| |
| #[test] |
| fn from_der_generalizedtime() { |
| let input = &hex!("18 0F 32 30 30 32 31 32 31 33 31 34 32 39 32 33 5A FF"); |
| let (rem, result) = GeneralizedTime::from_der(input).expect("parsing failed"); |
| assert_eq!(rem, &[0xff]); |
| #[cfg(feature = "datetime")] |
| { |
| use time::macros::datetime; |
| let datetime = datetime! {2002-12-13 14:29:23 UTC}; |
| assert_eq!(result.utc_datetime(), Ok(datetime)); |
| } |
| let _ = result; |
| // local time with fractional seconds (should fail: no 'Z' at end) |
| let input = b"\x18\x1019851106210627.3"; |
| let result = GeneralizedTime::from_der(input).expect_err("should not parse"); |
| assert_eq!( |
| result, |
| nom::Err::Error(Error::DerConstraintFailed(DerConstraint::MissingTimeZone)) |
| ); |
| // coordinated universal time with fractional seconds |
| let input = b"\x18\x1119851106210627.3Z"; |
| let (rem, result) = GeneralizedTime::from_der(input).expect("parsing failed"); |
| assert!(rem.is_empty()); |
| assert_eq!(result.0.millisecond, Some(300)); |
| assert_eq!(result.0.tz, ASN1TimeZone::Z); |
| #[cfg(feature = "datetime")] |
| { |
| use time::macros::datetime; |
| let datetime = datetime! {1985-11-06 21:06:27.3 UTC}; |
| assert_eq!(result.utc_datetime(), Ok(datetime)); |
| } |
| let _ = result.to_string(); |
| // local time with fractional seconds, and with local time 5 hours retarded in relation to coordinated universal time. |
| // (should fail: no 'Z' at end) |
| let input = b"\x18\x1519851106210627.3-0500"; |
| let result = GeneralizedTime::from_der(input).expect_err("should not parse"); |
| assert_eq!( |
| result, |
| nom::Err::Error(Error::DerConstraintFailed(DerConstraint::MissingTimeZone)) |
| ); |
| } |
| |
| #[test] |
| fn from_der_indefinite_length() { |
| let bytes: &[u8] = &hex!("23 80 03 03 00 0a 3b 03 05 04 5f 29 1c d0 00 00"); |
| assert_eq!( |
| BitString::from_der(bytes), |
| Err(Err::Error(Error::DerConstraintFailed( |
| DerConstraint::IndefiniteLength |
| ))) |
| ); |
| let bytes: &[u8] = &hex!("02 80 01 00 00"); |
| assert!(Integer::from_der(bytes).is_err()); |
| } |
| |
| #[test] |
| fn from_der_int() { |
| let input = &hex!("02 01 02 ff ff"); |
| let (rem, result) = u8::from_der(input).expect("parsing failed"); |
| assert_eq!(result, 2); |
| assert_eq!(rem, &[0xff, 0xff]); |
| // attempt to parse a value too large for container type |
| let input = &hex!("02 03 00 ff ff"); |
| let err = u8::from_der(input).expect_err("parsing should fail"); |
| assert_eq!(err, Err::Error(Error::IntegerTooLarge)); |
| // attempt to parse a value too large (positive large value in signed integer) |
| let input = &hex!("02 03 00 ff ff"); |
| let err = i16::from_der(input).expect_err("parsing should fail"); |
| assert_eq!(err, Err::Error(Error::IntegerTooLarge)); |
| } |
| |
| #[test] |
| fn from_der_null() { |
| let input = &hex!("05 00 ff ff"); |
| let (rem, result) = Null::from_der(input).expect("parsing failed"); |
| assert_eq!(result, Null {}); |
| assert_eq!(rem, &[0xff, 0xff]); |
| // unit |
| let (rem, _unit) = <()>::from_der(input).expect("parsing failed"); |
| assert_eq!(rem, &[0xff, 0xff]); |
| } |
| |
| #[test] |
| fn from_der_octetstring() { |
| // coverage |
| use std::borrow::Cow; |
| let s = OctetString::new(b"1234"); |
| assert_eq!(s.as_cow().len(), 4); |
| assert_eq!(s.into_cow(), Cow::Borrowed(b"1234")); |
| // |
| let input = &hex!("04 05 41 41 41 41 41"); |
| let (rem, result) = OctetString::from_der(input).expect("parsing failed"); |
| assert_eq!(result.as_ref(), b"AAAAA"); |
| assert_eq!(rem, &[]); |
| // |
| let (rem, result) = <&[u8]>::from_der(input).expect("parsing failed"); |
| assert_eq!(result, b"AAAAA"); |
| assert_eq!(rem, &[]); |
| } |
| |
| #[test] |
| fn from_der_octetstring_as_slice() { |
| let input = &hex!("04 05 41 41 41 41 41"); |
| let (rem, result) = <&[u8]>::from_der(input).expect("parsing failed"); |
| assert_eq!(result, b"AAAAA"); |
| assert_eq!(rem, &[]); |
| } |
| |
| #[test] |
| fn from_der_oid() { |
| let input = &hex!("06 09 2a 86 48 86 f7 0d 01 01 05"); |
| let (rem, result) = Oid::from_der(input).expect("parsing failed"); |
| let expected = Oid::from(&[1, 2, 840, 113_549, 1, 1, 5]).unwrap(); |
| assert_eq!(result, expected); |
| assert_eq!(rem, &[]); |
| } |
| |
| #[test] |
| fn from_der_optional() { |
| let input = &hex!("30 0a 0a 03 00 00 01 02 03 01 00 01"); |
| let (rem, result) = Sequence::from_der_and_then(input, |input| { |
| let (i, obj0) = <Option<Enumerated>>::from_der(input)?; |
| let (i, obj1) = u32::from_der(i)?; |
| Ok((i, (obj0, obj1))) |
| }) |
| .expect("parsing failed"); |
| let expected = (Some(Enumerated::new(1)), 65537); |
| assert_eq!(result, expected); |
| assert_eq!(rem, &[]); |
| } |
| |
| #[test] |
| fn from_der_real_f32() { |
| const EPSILON: f32 = 0.00001; |
| // binary, base = 2 |
| let input = &hex!("09 03 80 ff 01 ff ff"); |
| let (rem, result) = <f32>::from_der(input).expect("parsing failed"); |
| assert!((result - 0.5).abs() < EPSILON); |
| assert_eq!(rem, &[0xff, 0xff]); |
| } |
| |
| #[test] |
| fn from_der_real_f64() { |
| const EPSILON: f64 = 0.00001; |
| // binary, base = 2 |
| let input = &hex!("09 03 80 ff 01 ff ff"); |
| let (rem, result) = <f64>::from_der(input).expect("parsing failed"); |
| assert!((result - 0.5).abs() < EPSILON); |
| assert_eq!(rem, &[0xff, 0xff]); |
| } |
| |
| #[test] |
| fn from_der_relative_oid() { |
| let input = &hex!("0d 04 c2 7b 03 02"); |
| let (rem, result) = Oid::from_der_relative(input).expect("parsing failed"); |
| let expected = Oid::from_relative(&[8571, 3, 2]).unwrap(); |
| assert_eq!(result, expected); |
| assert_eq!(rem, &[]); |
| } |
| |
| #[test] |
| fn from_der_sequence() { |
| let input = &hex!("30 05 02 03 01 00 01"); |
| let (rem, result) = Sequence::from_der(input).expect("parsing failed"); |
| assert_eq!(result.as_ref(), &input[2..]); |
| assert_eq!(rem, &[]); |
| } |
| |
| #[test] |
| fn from_der_sequence_vec() { |
| let input = &hex!("30 05 02 03 01 00 01"); |
| let (rem, result) = <Vec<u32>>::from_der(input).expect("parsing failed"); |
| assert_eq!(&result, &[65537]); |
| assert_eq!(rem, &[]); |
| } |
| |
| #[test] |
| fn from_der_iter_sequence_parse() { |
| let input = &hex!("30 0a 02 03 01 00 01 02 03 01 00 01"); |
| let (rem, result) = Sequence::from_der(input).expect("parsing failed"); |
| assert_eq!(result.as_ref(), &input[2..]); |
| assert_eq!(rem, &[]); |
| let (rem, v) = result |
| .parse(pair(u32::from_der, u32::from_der)) |
| .expect("parse sequence data"); |
| assert_eq!(v, (65537, 65537)); |
| assert!(rem.is_empty()); |
| } |
| #[test] |
| fn from_der_iter_sequence() { |
| let input = &hex!("30 0a 02 03 01 00 01 02 03 01 00 01"); |
| let (rem, result) = Sequence::from_der(input).expect("parsing failed"); |
| assert_eq!(result.as_ref(), &input[2..]); |
| assert_eq!(rem, &[]); |
| let v = result |
| .der_iter() |
| .collect::<Result<Vec<u32>>>() |
| .expect("could not iterate sequence"); |
| assert_eq!(&v, &[65537, 65537]); |
| } |
| |
| #[test] |
| fn from_der_iter_sequence_incomplete() { |
| let input = &hex!("30 09 02 03 01 00 01 02 03 01 00"); |
| let (rem, result) = Sequence::from_der(input).expect("parsing failed"); |
| assert_eq!(result.as_ref(), &input[2..]); |
| assert_eq!(rem, &[]); |
| let mut iter = result.der_iter::<u32, Error>(); |
| assert_eq!(iter.next(), Some(Ok(65537))); |
| assert_eq!(iter.next(), Some(Err(Error::Incomplete(Needed::new(1))))); |
| assert_eq!(iter.next(), None); |
| } |
| |
| #[test] |
| fn from_der_set() { |
| let input = &hex!("31 05 02 03 01 00 01"); |
| let (rem, result) = Set::from_der(input).expect("parsing failed"); |
| assert_eq!(result.as_ref(), &input[2..]); |
| assert_eq!(rem, &[]); |
| // |
| let (_, i) = Set::from_der_and_then(input, Integer::from_der).expect("parsing failed"); |
| assert_eq!(i.as_u32(), Ok(0x10001)); |
| } |
| |
| #[test] |
| fn from_der_set_btreeset() { |
| let input = &hex!("31 05 02 03 01 00 01"); |
| let (rem, result) = <BTreeSet<u32>>::from_der(input).expect("parsing failed"); |
| assert!(result.contains(&65537)); |
| assert_eq!(result.len(), 1); |
| assert_eq!(rem, &[]); |
| } |
| |
| #[test] |
| fn from_der_set_of_vec() { |
| let input = &hex!("31 05 02 03 01 00 01"); |
| let (rem, result) = <Set>::from_der(input).expect("parsing failed"); |
| let v = result.der_set_of::<u32, _>().expect("ber_set_of failed"); |
| assert_eq!(rem, &[]); |
| assert_eq!(&v, &[65537]); |
| } |
| |
| #[test] |
| fn from_der_iter_set() { |
| let input = &hex!("31 0a 02 03 01 00 01 02 03 01 00 01"); |
| let (rem, result) = Set::from_der(input).expect("parsing failed"); |
| assert_eq!(result.as_ref(), &input[2..]); |
| assert_eq!(rem, &[]); |
| let v = result |
| .der_iter() |
| .collect::<Result<Vec<u32>>>() |
| .expect("could not iterate set"); |
| assert_eq!(&v, &[65537, 65537]); |
| } |
| |
| #[test] |
| fn from_der_utctime() { |
| let input = &hex!("17 0D 30 32 31 32 31 33 31 34 32 39 32 33 5A FF"); |
| let (rem, result) = UtcTime::from_der(input).expect("parsing failed"); |
| assert_eq!(rem, &[0xff]); |
| #[cfg(feature = "datetime")] |
| { |
| use time::macros::datetime; |
| let datetime = datetime! {2-12-13 14:29:23 UTC}; |
| |
| assert_eq!(result.utc_datetime(), Ok(datetime)); |
| } |
| let _ = result.to_string(); |
| // |
| let input = &hex!("17 11 30 32 31 32 31 33 31 34 32 39 32 33 2b 30 33 30 30 FF"); |
| let (rem, result) = UtcTime::from_der(input).expect("parsing failed"); |
| assert_eq!(rem, &[0xff]); |
| #[cfg(feature = "datetime")] |
| { |
| use time::macros::datetime; |
| let datetime = datetime! {2-12-13 14:29:23 +03:00}; |
| |
| assert_eq!(result.utc_datetime(), Ok(datetime)); |
| } |
| let _ = result.to_string(); |
| // |
| let input = &hex!("17 11 30 32 31 32 31 33 31 34 32 39 32 33 2d 30 33 30 30 FF"); |
| let (rem, result) = UtcTime::from_der(input).expect("parsing failed"); |
| assert_eq!(rem, &[0xff]); |
| #[cfg(feature = "datetime")] |
| { |
| use time::macros::datetime; |
| let datetime = datetime! {2-12-13 14:29:23 -03:00}; |
| |
| assert_eq!(result.utc_datetime(), Ok(datetime)); |
| } |
| let _ = result.to_string(); |
| } |
| |
| #[cfg(feature = "datetime")] |
| #[test] |
| fn utctime_adjusted_datetime() { |
| use time::macros::datetime; |
| |
| let input = &hex!("17 0D 30 32 31 32 31 33 31 34 32 39 32 33 5A FF"); |
| let (_, result) = UtcTime::from_der(input).expect("parsing failed"); |
| |
| assert_eq!( |
| result.utc_adjusted_datetime(), |
| Ok(datetime! {2002-12-13 14:29:23 UTC}) |
| ); |
| |
| let input = &hex!("17 0D 35 30 31 32 31 33 31 34 32 39 32 33 5A FF"); |
| let (_, result) = UtcTime::from_der(input).expect("parsing failed"); |
| |
| assert_eq!( |
| result.utc_adjusted_datetime(), |
| Ok(datetime! {1950-12-13 14:29:23 UTC}) |
| ); |
| let _ = result.to_string(); |
| } |
| |
| #[test] |
| fn from_der_utf8string() { |
| let input = &hex!("0c 0a 53 6f 6d 65 2d 53 74 61 74 65"); |
| let (rem, result) = Utf8String::from_der(input).expect("parsing failed"); |
| assert_eq!(result.as_ref(), "Some-State"); |
| assert_eq!(rem, &[]); |
| } |
| |
| #[test] |
| fn from_der_utf8string_as_str() { |
| let input = &hex!("0c 0a 53 6f 6d 65 2d 53 74 61 74 65"); |
| let (rem, result) = <&str>::from_der(input).expect("parsing failed"); |
| assert_eq!(result, "Some-State"); |
| assert_eq!(rem, &[]); |
| } |
| |
| #[test] |
| fn from_der_utf8string_as_string() { |
| let input = &hex!("0c 0a 53 6f 6d 65 2d 53 74 61 74 65"); |
| let (rem, result) = String::from_der(input).expect("parsing failed"); |
| assert_eq!(&result, "Some-State"); |
| assert_eq!(rem, &[]); |
| } |
| |
| #[test] |
| fn from_der_opt_int() { |
| let input = &hex!("02 01 02 ff ff"); |
| let (rem, result) = <Option<u8>>::from_der(input).expect("parsing failed"); |
| assert_eq!(result, Some(2)); |
| assert_eq!(rem, &[0xff, 0xff]); |
| // non-fatal error |
| let (rem, result) = <Option<Ia5String>>::from_der(input).expect("parsing failed"); |
| assert!(result.is_none()); |
| assert_eq!(rem, input); |
| // fatal error (correct tag, but incomplete) |
| let input = &hex!("02 03 02 01"); |
| let res = <Option<u8>>::from_der(input); |
| assert_eq!(res, Err(nom::Err::Incomplete(Needed::new(1)))); |
| } |
| |
| #[test] |
| fn from_der_tagged_explicit() { |
| let input = &hex!("a0 03 02 01 02"); |
| let (rem, result) = TaggedExplicit::<u32, Error, 0>::from_der(input).expect("parsing failed"); |
| assert!(rem.is_empty()); |
| assert_eq!(result.tag(), Tag(0)); |
| assert_eq!(result.as_ref(), &2); |
| } |
| |
| #[test] |
| fn from_der_tagged_explicit_with_class() { |
| let input = &hex!("a0 03 02 01 02"); |
| // Note: the strange notation (using braces) is required by the compiler to use |
| // a constant instead of the numeric value. |
| let (rem, result) = |
| TaggedValue::<u32, Error, Explicit, { Class::CONTEXT_SPECIFIC }, 0>::from_der(input) |
| .expect("parsing failed"); |
| assert!(rem.is_empty()); |
| assert_eq!(result.tag(), Tag(0)); |
| assert_eq!(result.as_ref(), &2); |
| } |
| |
| #[test] |
| fn from_der_tagged_explicit_any_tag() { |
| let input = &hex!("a0 03 02 01 02"); |
| let (rem, result) = TaggedParser::<Explicit, u32>::from_der(input).expect("parsing failed"); |
| assert!(rem.is_empty()); |
| assert_eq!(result.tag(), Tag(0)); |
| assert_eq!(result.as_ref(), &2); |
| } |
| |
| #[test] |
| fn from_der_tagged_explicit_optional() { |
| let input = &hex!("a0 03 02 01 02"); |
| let (rem, result) = |
| Option::<TaggedExplicit<u32, Error, 0>>::from_der(input).expect("parsing failed"); |
| assert!(rem.is_empty()); |
| assert!(result.is_some()); |
| let tagged = result.unwrap(); |
| assert_eq!(tagged.tag(), Tag(0)); |
| assert_eq!(tagged.as_ref(), &2); |
| let (rem, result) = |
| Option::<TaggedExplicit<u32, Error, 1>>::from_der(input).expect("parsing failed"); |
| assert!(result.is_none()); |
| assert_eq!(rem, input); |
| |
| // using OptTaggedExplicit |
| let (rem, result) = |
| OptTaggedExplicit::<u32, Error, 0>::from_der(input).expect("parsing failed"); |
| assert!(rem.is_empty()); |
| assert!(result.is_some()); |
| let tagged = result.unwrap(); |
| assert_eq!(tagged.tag(), Tag(0)); |
| assert_eq!(tagged.as_ref(), &2); |
| |
| // using OptTaggedParser |
| let (rem, result) = OptTaggedParser::from(0) |
| .parse_der(input, |_, data| Integer::from_der(data)) |
| .expect("parsing failed"); |
| assert!(rem.is_empty()); |
| assert_eq!(result, Some(Integer::from(2))); |
| } |
| |
| #[test] |
| fn from_der_tagged_implicit() { |
| let input = &hex!("81 04 70 61 73 73"); |
| let (rem, result) = TaggedImplicit::<&str, Error, 1>::from_der(input).expect("parsing failed"); |
| assert!(rem.is_empty()); |
| assert_eq!(result.tag(), Tag(1)); |
| assert_eq!(result.as_ref(), &"pass"); |
| } |
| |
| #[test] |
| fn from_der_tagged_implicit_with_class() { |
| let input = &hex!("81 04 70 61 73 73"); |
| // Note: the strange notation (using braces) is required by the compiler to use |
| // a constant instead of the numeric value. |
| let (rem, result) = |
| TaggedValue::<&str, Error, Implicit, { Class::CONTEXT_SPECIFIC }, 1>::from_der(input) |
| .expect("parsing failed"); |
| assert!(rem.is_empty()); |
| assert_eq!(result.tag(), Tag(1)); |
| assert_eq!(result.as_ref(), &"pass"); |
| } |
| |
| #[test] |
| fn from_der_tagged_implicit_any_tag() { |
| let input = &hex!("81 04 70 61 73 73"); |
| let (rem, result) = TaggedParser::<Implicit, &str>::from_der(input).expect("parsing failed"); |
| assert!(rem.is_empty()); |
| assert_eq!(result.tag(), Tag(1)); |
| assert_eq!(result.as_ref(), &"pass"); |
| } |
| |
| #[test] |
| fn from_der_tagged_implicit_optional() { |
| let input = &hex!("81 04 70 61 73 73"); |
| let (rem, result) = |
| Option::<TaggedImplicit<&str, Error, 1>>::from_der(input).expect("parsing failed"); |
| assert!(rem.is_empty()); |
| assert!(result.is_some()); |
| let tagged = result.unwrap(); |
| assert_eq!(tagged.tag(), Tag(1)); |
| assert_eq!(tagged.as_ref(), &"pass"); |
| let (rem, result) = |
| Option::<TaggedImplicit<&str, Error, 0>>::from_der(input).expect("parsing failed"); |
| assert!(result.is_none()); |
| assert_eq!(rem, input); |
| |
| // using OptTaggedExplicit |
| let (rem, result) = |
| OptTaggedImplicit::<&str, Error, 1>::from_der(input).expect("parsing failed"); |
| assert!(rem.is_empty()); |
| assert!(result.is_some()); |
| let tagged = result.unwrap(); |
| assert_eq!(tagged.tag(), Tag(1)); |
| assert_eq!(tagged.as_ref(), &"pass"); |
| } |
| |
| #[test] |
| fn from_der_tagged_implicit_all() { |
| let input = &hex!("81 04 70 61 73 73"); |
| let (rem, result) = |
| TaggedParser::<Implicit, Ia5String>::from_der(input).expect("parsing failed"); |
| assert!(rem.is_empty()); |
| assert_eq!(result.tag(), Tag(1)); |
| assert_eq!(result.as_ref().as_ref(), "pass"); |
| |
| // try the API verifying class and tag |
| let _ = TaggedParser::<Implicit, Ia5String>::parse_der(Class::ContextSpecific, Tag(1), input) |
| .expect("parsing failed"); |
| |
| // test TagParser API |
| let parser = TaggedParserBuilder::implicit() |
| .with_class(Class::ContextSpecific) |
| .with_tag(Tag(1)) |
| .der_parser::<Ia5String>(); |
| let _ = parser(input).expect("parsing failed"); |
| |
| // try specifying the expected tag (correct tag) |
| let _ = parse_der_tagged_implicit::<_, Ia5String, _>(1)(input).expect("parsing failed"); |
| // try specifying the expected tag (incorrect tag) |
| let _ = parse_der_tagged_implicit::<_, Ia5String, _>(2)(input) |
| .expect_err("parsing should have failed"); |
| } |
| |
| /// Generic tests on methods, and coverage tests |
| #[test] |
| fn from_der_tagged_optional_cov() { |
| let p = |
| |input| OptTaggedParser::from(1).parse_der::<_, Error, _>(input, |_, data| Ok((data, ()))); |
| // empty input |
| let input = &[]; |
| let (_, r) = p(input).expect("parsing failed"); |
| assert!(r.is_none()); |
| // wrong tag |
| let input = &hex!("a0 03 02 01 02"); |
| let (_, r) = p(input).expect("parsing failed"); |
| assert!(r.is_none()); |
| // wrong class |
| let input = &hex!("e1 03 02 01 02"); |
| let r = p(input); |
| assert!(r.is_err()); |
| |
| let p = OptTaggedParser::from(Tag(1)); |
| let _ = format!("{:?}", p); |
| } |