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) = ::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_numericstring() { // let input = &hex!("12 03 31 32 33"); let (rem, result) = NumericString::from_der(input).expect("parsing failed"); assert_eq!(result.as_ref(), "123"); assert_eq!(rem, &[]); // wrong charset let input = &hex!("12 03 41 42 43"); let _ = NumericString::from_der(input).expect_err("parsing should fail"); } #[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) = >::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) = ::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) = ::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) = >::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::>>() .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::(); 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) = >::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) = ::from_der(input).expect("parsing failed"); let v = result.der_set_of::().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::>>() .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) = >::from_der(input).expect("parsing failed"); assert_eq!(result, Some(2)); assert_eq!(rem, &[0xff, 0xff]); // non-fatal error let (rem, result) = >::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 = >::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::::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::::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::::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::>::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::>::from_der(input).expect("parsing failed"); assert!(result.is_none()); assert_eq!(rem, input); // using OptTaggedExplicit let (rem, result) = OptTaggedExplicit::::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::::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::>::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::>::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::::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::::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::(); 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); }