diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:39:49 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:39:49 +0000 |
commit | a0aa2307322cd47bbf416810ac0292925e03be87 (patch) | |
tree | 37076262a026c4b48c8a0e84f44ff9187556ca35 /rust/vendor/asn1-rs/tests | |
parent | Initial commit. (diff) | |
download | suricata-a0aa2307322cd47bbf416810ac0292925e03be87.tar.xz suricata-a0aa2307322cd47bbf416810ac0292925e03be87.zip |
Adding upstream version 1:7.0.3.upstream/1%7.0.3
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'rust/vendor/asn1-rs/tests')
-rw-r--r-- | rust/vendor/asn1-rs/tests/ber.rs | 518 | ||||
-rw-r--r-- | rust/vendor/asn1-rs/tests/compile_tests.rs | 6 | ||||
-rw-r--r-- | rust/vendor/asn1-rs/tests/cov.rs | 99 | ||||
-rw-r--r-- | rust/vendor/asn1-rs/tests/der.rs | 649 | ||||
-rw-r--r-- | rust/vendor/asn1-rs/tests/krb5.rs | 108 | ||||
-rw-r--r-- | rust/vendor/asn1-rs/tests/to_der.rs | 515 | ||||
-rw-r--r-- | rust/vendor/asn1-rs/tests/x509.rs | 158 |
7 files changed, 2053 insertions, 0 deletions
diff --git a/rust/vendor/asn1-rs/tests/ber.rs b/rust/vendor/asn1-rs/tests/ber.rs new file mode 100644 index 0000000..d1c6705 --- /dev/null +++ b/rust/vendor/asn1-rs/tests/ber.rs @@ -0,0 +1,518 @@ +use asn1_rs::*; +use hex_literal::hex; +use nom::Needed; +#[cfg(feature = "datetime")] +use time::macros::datetime; + +#[test] +fn from_ber_any() { + let input = &hex!("02 01 02 ff ff"); + let (rem, result) = Any::from_ber(input).expect("parsing failed"); + // dbg!(&result); + assert_eq!(rem, &[0xff, 0xff]); + assert_eq!(result.header.tag(), Tag::Integer); +} + +#[test] +fn from_ber_bitstring() { + // + // correct DER encoding + // + let input = &hex!("03 04 06 6e 5d c0"); + let (rem, result) = BitString::from_ber(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 (rem, result) = BitString::from_ber(input).expect("parsing failed"); + assert!(rem.is_empty()); + assert_eq!(result.unused_bits, 6); + assert_eq!(&result.data[..], &input[3..]); + // + // long form of length (invalid, < 127) + // + let input = &hex!("03 81 04 06 6e 5d c0"); + let (rem, result) = BitString::from_ber(input).expect("parsing failed"); + assert!(rem.is_empty()); + assert_eq!(result.unused_bits, 6); + assert_eq!(&result.data[..], &input[4..]); +} + +#[test] +fn from_ber_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_ber(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 embedded_pdv_variants() { + // identification: syntaxes + let input = &hex!("2b 11 a0 0c a0 0a 80 02 2a 03 81 04 2a 03 04 05 82 01 00"); + let (rem, res) = EmbeddedPdv::from_ber(input).expect("parsing EMBEDDED PDV failed"); + assert!(rem.is_empty()); + assert!(matches!( + res.identification, + PdvIdentification::Syntaxes { .. } + )); + // identification: syntax + let input = &hex!("2b 09 a0 04 81 02 2a 03 82 01 00"); + let (rem, res) = EmbeddedPdv::from_ber(input).expect("parsing EMBEDDED PDV failed"); + assert!(rem.is_empty()); + assert!(matches!(res.identification, PdvIdentification::Syntax(_))); + // identification: presentation-context-id + let input = &hex!("2b 08 a0 03 82 01 02 82 01 00"); + let (rem, res) = EmbeddedPdv::from_ber(input).expect("parsing EMBEDDED PDV failed"); + assert!(rem.is_empty()); + assert!(matches!( + res.identification, + PdvIdentification::PresentationContextId(_) + )); + // identification: context-negotiation + let input = &hex!("2b 10 a0 0b a3 09 80 01 2a 81 04 2a 03 04 05 82 01 00"); + let (rem, res) = EmbeddedPdv::from_ber(input).expect("parsing EMBEDDED PDV failed"); + assert!(rem.is_empty()); + assert!(matches!( + res.identification, + PdvIdentification::ContextNegotiation { .. } + )); + // identification: transfer-syntax + let input = &hex!("2b 0b a0 06 84 04 2a 03 04 05 82 01 00"); + let (rem, res) = EmbeddedPdv::from_ber(input).expect("parsing EMBEDDED PDV failed"); + assert!(rem.is_empty()); + assert!(matches!( + res.identification, + PdvIdentification::TransferSyntax(_) + )); + // identification: fixed + let input = &hex!("2b 07 a0 02 85 00 82 01 00"); + let (rem, res) = EmbeddedPdv::from_ber(input).expect("parsing EMBEDDED PDV failed"); + assert!(rem.is_empty()); + assert!(matches!(res.identification, PdvIdentification::Fixed)); + // identification: invalid + let input = &hex!("2b 07 a0 02 86 00 82 01 00"); + let e = EmbeddedPdv::from_ber(input).expect_err("parsing should fail"); + assert!(matches!(e, Err::Error(Error::InvalidValue { .. }))); +} + +#[test] +fn from_ber_endofcontent() { + let input = &hex!("00 00"); + let (rem, _result) = EndOfContent::from_ber(input).expect("parsing failed"); + assert_eq!(rem, &[]); +} + +#[test] +fn from_ber_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_ber(input).expect("parsing failed"); + assert_eq!(rem, &[0xff]); + #[cfg(feature = "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 + let input = b"\x18\x1019851106210627.3"; + let (rem, result) = GeneralizedTime::from_ber(input).expect("parsing failed"); + assert!(rem.is_empty()); + assert_eq!(result.0.millisecond, Some(300)); + assert_eq!(result.0.tz, ASN1TimeZone::Undefined); + #[cfg(feature = "datetime")] + { + let datetime = datetime! {1985-11-06 21:06:27.300_000_000 UTC}; + assert_eq!(result.utc_datetime(), Ok(datetime)); + } + let _ = result; + // coordinated universal time with fractional seconds + let input = b"\x18\x1119851106210627.3Z"; + let (rem, result) = GeneralizedTime::from_ber(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")] + { + let datetime = datetime! {1985-11-06 21:06:27.300_000_000 UTC}; + assert_eq!(result.utc_datetime(), Ok(datetime)); + } + let _ = result; + // coordinated universal time with fractional seconds + let input = b"\x18\x1219851106210627.03Z"; + let (rem, result) = GeneralizedTime::from_ber(input).expect("parsing failed"); + assert!(rem.is_empty()); + assert_eq!(result.0.millisecond, Some(30)); + assert_eq!(result.0.tz, ASN1TimeZone::Z); + #[cfg(feature = "datetime")] + { + let datetime = datetime! {1985-11-06 21:06:27.03 UTC}; + assert_eq!(result.utc_datetime(), Ok(datetime)); + } + let _ = result; + // local time with fractional seconds, and with local time 5 hours retarded in relation to coordinated universal time. + let input = b"\x18\x1519851106210627.3-0500"; + let (rem, result) = GeneralizedTime::from_ber(input).expect("parsing failed"); + assert!(rem.is_empty()); + assert_eq!(result.0.millisecond, Some(300)); + assert_eq!(result.0.tz, ASN1TimeZone::Offset(-5, 0)); + #[cfg(feature = "datetime")] + { + let datetime = datetime! {1985-11-06 21:06:27.300_000_000 -05:00}; + assert_eq!(result.utc_datetime(), Ok(datetime)); + } + let _ = result; +} + +#[test] +fn from_ber_int() { + let input = &hex!("02 01 02 ff ff"); + let (rem, result) = u8::from_ber(input).expect("parsing failed"); + assert_eq!(result, 2); + assert_eq!(rem, &[0xff, 0xff]); +} + +#[test] +fn from_ber_relative_oid() { + let input = &hex!("0d 04 c2 7b 03 02"); + let (rem, result) = Oid::from_ber_relative(input).expect("parsing failed"); + assert_eq!(result, Oid::from_relative(&[8571, 3, 2]).unwrap()); + assert_eq!(rem, &[]); +} + +#[test] +fn from_ber_length_incomplete() { + let input = &hex!("30"); + let res = u8::from_ber(input).expect_err("parsing should have failed"); + assert_eq!(res, nom::Err::Incomplete(Needed::new(1))); + let input = &hex!("02"); + let res = u8::from_ber(input).expect_err("parsing should have failed"); + assert_eq!(res, nom::Err::Incomplete(Needed::new(1))); + let input = &hex!("02 05"); + let res = u8::from_ber(input).expect_err("parsing should have failed"); + assert_eq!(res, nom::Err::Incomplete(Needed::new(5))); + let input = &hex!("02 85"); + let res = u8::from_ber(input).expect_err("parsing should have failed"); + assert_eq!(res, nom::Err::Incomplete(Needed::new(5))); + let input = &hex!("02 85 ff"); + let res = u8::from_ber(input).expect_err("parsing should have failed"); + assert_eq!(res, nom::Err::Incomplete(Needed::new(4))); +} + +#[test] +fn from_ber_length_invalid() { + let input = &hex!("02 ff 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10"); + let res = u8::from_ber(input).expect_err("parsing should have failed"); + assert_eq!(res, nom::Err::Error(Error::InvalidLength)); + let input = &hex!("02 85 ff ff ff ff ff 00"); + let res = u8::from_ber(input).expect_err("parsing should have failed"); + assert!(res.is_incomplete()); +} + +#[test] +fn from_ber_octetstring() { + let input = &hex!("04 05 41 41 41 41 41"); + let (rem, result) = OctetString::from_ber(input).expect("parsing failed"); + assert_eq!(result.as_ref(), b"AAAAA"); + assert_eq!(rem, &[]); +} + +#[test] +fn from_ber_real_binary() { + const EPSILON: f32 = 0.00001; + // binary, base = 2 + let input = &hex!("09 03 80 ff 01 ff ff"); + let (rem, result) = Real::from_ber(input).expect("parsing failed"); + assert_eq!(result, Real::binary(1.0, 2, -1)); + assert!((result.f32() - 0.5).abs() < EPSILON); + assert_eq!(rem, &[0xff, 0xff]); + // binary, base = 2 and scale factor + let input = &hex!("09 03 94 ff 0d ff ff"); + let (rem, result) = Real::from_ber(input).expect("parsing failed"); + assert_eq!(result, Real::binary(26.0, 2, -3).with_enc_base(8)); + assert!((result.f32() - 3.25).abs() < EPSILON); + assert_eq!(rem, &[0xff, 0xff]); + // binary, base = 16 + let input = &hex!("09 03 a0 fe 01 ff ff"); + let (rem, result) = Real::from_ber(input).expect("parsing failed"); + assert_eq!(result, Real::binary(1.0, 2, -8).with_enc_base(16)); + assert!((result.f32() - 0.00390625).abs() < EPSILON); + assert_eq!(rem, &[0xff, 0xff]); + // binary, exponent = 0 + let input = &hex!("09 03 80 00 01 ff ff"); + let (rem, result) = Real::from_ber(input).expect("parsing failed"); + assert_eq!(result, Real::binary(1.0, 2, 0)); + assert!((result.f32() - 1.0).abs() < EPSILON); + assert_eq!(rem, &[0xff, 0xff]); + // 2 octets for exponent and negative exponent + let input = &hex!("09 04 a1 ff 01 03 ff ff"); + let (rem, result) = Real::from_ber(input).expect("parsing failed"); + assert_eq!(result, Real::binary(3.0, 2, -1020).with_enc_base(16)); + let epsilon = 1e-311_f64; + assert!((result.f64() - 2.67e-307).abs() < epsilon); + assert_eq!(rem, &[0xff, 0xff]); +} + +#[test] +fn from_ber_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_ber(input).expect("parsing failed"); + assert!((result - 0.5).abs() < EPSILON); + assert_eq!(rem, &[0xff, 0xff]); +} + +#[test] +fn from_ber_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_ber(input).expect("parsing failed"); + assert!((result - 0.5).abs() < EPSILON); + assert_eq!(rem, &[0xff, 0xff]); +} + +#[test] +fn from_ber_real_special() { + // 0 + let input = &hex!("09 00 ff ff"); + let (rem, result) = Real::from_ber(input).expect("parsing failed"); + assert_eq!(result, Real::from(0.0)); + assert_eq!(rem, &[0xff, 0xff]); + // infinity + let input = &hex!("09 01 40 ff ff"); + let (rem, result) = Real::from_ber(input).expect("parsing failed"); + assert_eq!(result, Real::Infinity); + assert_eq!(rem, &[0xff, 0xff]); + // negative infinity + let input = &hex!("09 01 41 ff ff"); + let (rem, result) = Real::from_ber(input).expect("parsing failed"); + assert_eq!(result, Real::NegInfinity); + assert_eq!(rem, &[0xff, 0xff]); +} + +#[test] +#[allow(clippy::approx_constant)] +fn from_ber_real_string() { + // text representation, NR3 + let input = &hex!("09 07 03 33 31 34 45 2D 32 ff ff"); + let (rem, result) = Real::from_ber(input).expect("parsing failed"); + assert_eq!(result, Real::from(3.14)); + assert_eq!(rem, &[0xff, 0xff]); +} + +#[test] +#[allow(clippy::approx_constant)] +fn from_ber_real_string_primitive() { + // text representation, NR3 + let input = &hex!("09 07 03 33 31 34 45 2D 32 ff ff"); + let (rem, result) = f32::from_ber(input).expect("parsing failed"); + assert!((result - 3.14).abs() < 0.01); + assert_eq!(rem, &[0xff, 0xff]); +} + +#[test] +fn from_ber_sequence() { + let input = &hex!("30 05 02 03 01 00 01"); + let (rem, result) = Sequence::from_ber(input).expect("parsing failed"); + assert_eq!(result.as_ref(), &input[2..]); + assert_eq!(rem, &[]); + // + let (_, i) = Sequence::from_ber_and_then(input, Integer::from_ber).expect("parsing failed"); + assert_eq!(i.as_u32(), Ok(0x10001)); +} + +#[test] +fn from_ber_sequence_vec() { + let input = &hex!("30 05 02 03 01 00 01"); + let (rem, result) = <Vec<u32>>::from_ber(input).expect("parsing failed"); + assert_eq!(&result, &[65537]); + assert_eq!(rem, &[]); +} + +#[test] +fn from_ber_sequence_of_vec() { + let input = &hex!("30 05 02 03 01 00 01"); + let (rem, result) = <Sequence>::from_ber(input).expect("parsing failed"); + let v = result + .ber_sequence_of::<u32, _>() + .expect("ber_sequence_of failed"); + assert_eq!(rem, &[]); + assert_eq!(&v, &[65537]); +} + +#[test] +fn from_ber_iter_sequence() { + let input = &hex!("30 0a 02 03 01 00 01 02 03 01 00 01"); + let (rem, result) = Sequence::from_ber(input).expect("parsing failed"); + assert_eq!(result.as_ref(), &input[2..]); + assert_eq!(rem, &[]); + let v = result + .ber_iter() + .collect::<Result<Vec<u32>>>() + .expect("could not iterate sequence"); + assert_eq!(&v, &[65537, 65537]); +} + +#[test] +fn from_ber_set() { + let input = &hex!("31 05 02 03 01 00 01"); + let (rem, result) = Set::from_ber(input).expect("parsing failed"); + assert_eq!(result.as_ref(), &input[2..]); + assert_eq!(rem, &[]); + // + let (_, i) = Set::from_ber_and_then(input, Integer::from_ber).expect("parsing failed"); + assert_eq!(i.as_u32(), Ok(0x10001)); +} + +#[test] +fn from_ber_set_of_vec() { + let input = &hex!("31 05 02 03 01 00 01"); + let (rem, result) = <Set>::from_ber(input).expect("parsing failed"); + let v = result.ber_set_of::<u32, _>().expect("ber_set_of failed"); + assert_eq!(rem, &[]); + assert_eq!(&v, &[65537]); +} + +#[test] +fn from_ber_iter_set() { + let input = &hex!("31 0a 02 03 01 00 01 02 03 01 00 01"); + let (rem, result) = Set::from_ber(input).expect("parsing failed"); + assert_eq!(result.as_ref(), &input[2..]); + assert_eq!(rem, &[]); + let v = result + .ber_iter() + .collect::<Result<Vec<u32>>>() + .expect("could not iterate set"); + assert_eq!(&v, &[65537, 65537]); +} + +#[test] +fn from_ber_tag_custom() { + // canonical tag encoding + let input = &hex!("8f 02 12 34"); + let (rem, any) = Any::from_ber(input).expect("parsing failed"); + assert!(rem.is_empty()); + assert_eq!(any.tag(), Tag(15)); + // non-canonical tag encoding + let input = &hex!("9f 0f 02 12 34"); + let (rem, any) = Any::from_ber(input).expect("parsing failed"); + assert!(rem.is_empty()); + assert_eq!(any.tag(), Tag(15)); + assert_eq!(any.header.raw_tag(), Some(&[0x9f, 0x0f][..])); +} + +#[test] +fn from_ber_tag_incomplete() { + let input = &hex!("9f a2 a2"); + let res = Any::from_ber(input).expect_err("parsing should have failed"); + assert_eq!(res, nom::Err::Error(Error::InvalidTag)); +} + +#[test] +fn from_ber_tag_overflow() { + let input = &hex!("9f a2 a2 a2 a2 a2 a2 22 01 00"); + let res = Any::from_ber(input).expect_err("parsing should have failed"); + assert_eq!(res, nom::Err::Error(Error::InvalidTag)); +} + +#[test] +fn from_ber_tag_long() { + let input = &hex!("9f a2 22 01 00"); + let (rem, any) = Any::from_ber(input).expect("parsing failed"); + assert!(rem.is_empty()); + assert_eq!(any.tag(), Tag(0x1122)); + assert_eq!(any.header.raw_tag(), Some(&[0x9f, 0xa2, 0x22][..])); +} + +#[test] +fn from_ber_iter_sequence_incomplete() { + let input = &hex!("30 09 02 03 01 00 01 02 03 01 00"); + let (rem, result) = Sequence::from_ber(input).expect("parsing failed"); + assert_eq!(result.as_ref(), &input[2..]); + assert_eq!(rem, &[]); + let mut iter = result.ber_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_ber_set_of() { + let input = &hex!("31 05 02 03 01 00 01"); + let (rem, result) = SetOf::<u32>::from_ber(input).expect("parsing failed"); + assert_eq!(result.as_ref(), &[0x10001]); + assert_eq!(rem, &[]); + // not constructed + let input = &hex!("11 05 02 03 01 00 01"); + let err = SetOf::<u32>::from_ber(input).expect_err("should have failed"); + assert_eq!(err, Err::Error(Error::ConstructExpected)); +} + +#[test] +fn from_ber_tagged_explicit_optional() { + let input = &hex!("a0 03 02 01 02"); + let (rem, result) = + Option::<TaggedExplicit<u32, Error, 0>>::from_ber(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_ber(input).expect("parsing failed"); + assert!(result.is_none()); + assert_eq!(rem, input); + + // using OptTaggedExplicit + let (rem, result) = + OptTaggedExplicit::<u32, Error, 0>::from_ber(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_ber(input, |_, data| Integer::from_ber(data)) + .expect("parsing failed"); + assert!(rem.is_empty()); + assert_eq!(result, Some(Integer::from(2))); +} + +/// Generic tests on methods, and coverage tests +#[test] +fn from_ber_tagged_optional_cov() { + let p = + |input| OptTaggedParser::from(1).parse_ber::<_, 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()); +} + +#[test] +fn from_ber_universalstring() { + let input = &hex!("1C 10 00000061 00000062 00000063 00000064"); + let (rem, result) = UniversalString::from_ber(input).expect("parsing failed"); + assert_eq!(result.as_ref(), "abcd"); + assert_eq!(rem, &[]); +} diff --git a/rust/vendor/asn1-rs/tests/compile_tests.rs b/rust/vendor/asn1-rs/tests/compile_tests.rs new file mode 100644 index 0000000..1491f57 --- /dev/null +++ b/rust/vendor/asn1-rs/tests/compile_tests.rs @@ -0,0 +1,6 @@ +#[test] +fn compile_fail() { + let t = trybuild::TestCases::new(); + t.pass("tests/run-pass/*.rs"); + t.compile_fail("tests/compile-fail/*.rs"); +} diff --git a/rust/vendor/asn1-rs/tests/cov.rs b/rust/vendor/asn1-rs/tests/cov.rs new file mode 100644 index 0000000..374f950 --- /dev/null +++ b/rust/vendor/asn1-rs/tests/cov.rs @@ -0,0 +1,99 @@ +//! Generic and coverage tests +use asn1_rs::*; +use std::io; + +#[test] +fn new_embedded_pdv() { + fn create_pdv(identification: PdvIdentification) -> EmbeddedPdv { + let pdv = EmbeddedPdv { + identification, + data_value_descriptor: None, + data_value: &[0x00, 0xff], + }; + assert!(pdv.data_value_descriptor.is_none()); + assert_eq!(pdv.data_value.len(), 2); + pdv + } + let identification = PdvIdentification::ContextNegotiation { + presentation_context_id: Integer::from(42_u8), + presentation_syntax: oid! { 1.2.3.4.5 }, + }; + let pdv1 = create_pdv(identification); + let identification = PdvIdentification::Syntaxes { + s_abstract: oid! { 1.2.3 }, + s_transfer: oid! { 1.2.3.4.5 }, + }; + let pdv2 = create_pdv(identification); + assert!(pdv1 != pdv2); + let identification = PdvIdentification::Syntaxes { + s_abstract: oid! { 1.2.3 }, + s_transfer: oid! { 1.2.3.4.5 }, + }; + let pdv3 = create_pdv(identification); + assert!(pdv3 == pdv2); +} + +#[test] +fn methods_error() { + let e = Error::invalid_value(Tag(0), "msg".to_string()); + assert_eq!( + e, + Error::InvalidValue { + tag: Tag(0), + msg: "msg".to_string(), + } + ); + // + let e = Error::unexpected_tag(None, Tag(0)); + assert_eq!( + e, + Error::UnexpectedTag { + expected: None, + actual: Tag(0), + } + ); + // + let e = Error::unexpected_class(None, Class::Application); + assert_eq!( + e, + Error::UnexpectedClass { + expected: None, + actual: Class::Application + } + ); + // + use nom::error::ParseError; + let e = Error::from_error_kind(&[], nom::error::ErrorKind::Fail); + let e = <asn1_rs::Error as ParseError<_>>::append(&[], nom::error::ErrorKind::Eof, e); + let s = format!("{}", e); + assert!(s.starts_with("nom error:")); + // + let e1 = Error::from(nom::Err::Error(Error::BerTypeError)); + let e2 = Error::from(nom::Err::Incomplete(nom::Needed::new(2))); + assert!(e1 != e2); + // + let e = SerializeError::from(Error::BerTypeError); + let s = format!("{}", e); + assert!(s.starts_with("ASN.1 error:")); + // + let e = SerializeError::InvalidClass { class: 4 }; + let s = format!("{}", e); + assert!(s.starts_with("Invalid Class")); + // + let e = SerializeError::from(io::Error::new(io::ErrorKind::Other, "msg")); + let s = format!("{}", e); + assert!(s.starts_with("I/O error:")); +} + +#[test] +fn methods_tag() { + let t = Tag::from(2); + assert_eq!(t, Tag::Integer); + // + let err = t.invalid_value("test"); + if let Error::InvalidValue { tag, .. } = err { + assert_eq!(tag, Tag::Integer); + } else { + unreachable!(); + } +} diff --git a/rust/vendor/asn1-rs/tests/der.rs b/rust/vendor/asn1-rs/tests/der.rs new file mode 100644 index 0000000..5fd87d7 --- /dev/null +++ b/rust/vendor/asn1-rs/tests/der.rs @@ -0,0 +1,649 @@ +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); +} diff --git a/rust/vendor/asn1-rs/tests/krb5.rs b/rust/vendor/asn1-rs/tests/krb5.rs new file mode 100644 index 0000000..d48ed2f --- /dev/null +++ b/rust/vendor/asn1-rs/tests/krb5.rs @@ -0,0 +1,108 @@ +//! Test implementation for Kerberos v5 +//! +//! This is mostly used to verify that required types and functions are implemented, +//! and that provided API is convenient. + +use asn1_rs::*; +use hex_literal::hex; + +const PRINCIPAL_NAME: &[u8] = &hex!("30 81 11 a0 03 02 01 00 a1 0a 30 81 07 1b 05 4a 6f 6e 65 73"); + +/// PrincipalName ::= SEQUENCE { +/// name-type [0] Int32, +/// name-string [1] SEQUENCE OF KerberosString +/// } +#[derive(Debug, PartialEq, Eq)] +pub struct PrincipalName { + pub name_type: NameType, + pub name_string: Vec<String>, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct NameType(pub i32); + +// KerberosString ::= GeneralString (IA5String) +pub type KerberosString<'a> = GeneralString<'a>; + +pub type KerberosStringList<'a> = Vec<KerberosString<'a>>; + +impl Tagged for PrincipalName { + const TAG: Tag = Tag::Sequence; +} + +impl<'a> FromDer<'a> for PrincipalName { + fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self> { + // XXX in the example above, PRINCIPAL_NAME does not respect DER constraints (length is using long form while < 127) + let (rem, seq) = Sequence::from_ber(bytes)?; + seq.and_then(|data| { + let input = &data; + let (i, t) = parse_der_tagged_explicit::<_, u32, _>(0)(input)?; + let name_type = t.inner; + let name_type = NameType(name_type as i32); + let (_, t) = parse_der_tagged_explicit::<_, KerberosStringList, _>(1)(i)?; + let name_string = t.inner.iter().map(|s| s.string()).collect(); + Ok(( + rem, + PrincipalName { + name_type, + name_string, + }, + )) + }) + } +} + +impl ToDer for PrincipalName { + fn to_der_len(&self) -> Result<usize> { + let sz = self.name_type.0.to_der_len()? + 2 /* tagged */; + let sz = sz + self.name_string.to_der_len()? + 2 /* tagged */; + Ok(sz) + } + + fn write_der_header(&self, writer: &mut dyn std::io::Write) -> SerializeResult<usize> { + let len = self.to_der_len()?; + let header = Header::new(Class::Universal, true, Self::TAG, Length::Definite(len)); + header.write_der_header(writer).map_err(Into::into) + } + + fn write_der_content(&self, writer: &mut dyn std::io::Write) -> SerializeResult<usize> { + // build DER sequence content + let sz1 = self + .name_type + .0 + .explicit(Class::ContextSpecific, 0) + .write_der(writer)?; + let sz2 = self + .name_string + .iter() + .map(|s| KerberosString::from(s.as_ref())) + .collect::<Vec<_>>() + .explicit(Class::ContextSpecific, 1) + .write_der(writer)?; + Ok(sz1 + sz2) + } +} + +#[test] +fn krb5_principalname() { + let input = PRINCIPAL_NAME; + let (rem, res) = PrincipalName::from_der(input).expect("parsing failed"); + assert!(rem.is_empty()); + let expected = PrincipalName { + name_type: NameType(0), + name_string: vec!["Jones".to_string()], + }; + assert_eq!(res, expected); +} + +#[test] +fn to_der_krb5_principalname() { + let principal = PrincipalName { + name_type: NameType(0), + name_string: vec!["Jones".to_string()], + }; + let v = PrincipalName::to_der_vec(&principal).expect("serialization failed"); + std::fs::write("/tmp/out.bin", &v).unwrap(); + let (_, principal2) = PrincipalName::from_der(&v).expect("parsing failed"); + assert!(principal.eq(&principal2)); +} diff --git a/rust/vendor/asn1-rs/tests/to_der.rs b/rust/vendor/asn1-rs/tests/to_der.rs new file mode 100644 index 0000000..eea7560 --- /dev/null +++ b/rust/vendor/asn1-rs/tests/to_der.rs @@ -0,0 +1,515 @@ +use asn1_rs::*; +use hex_literal::hex; +// use nom::HexDisplay; +use std::collections::BTreeSet; +use std::convert::{TryFrom, TryInto}; +use std::iter::FromIterator; + +macro_rules! test_simple_string { + ($t:ty, $s:expr) => { + let t = <$t>::from($s); + let v = t.to_der_vec().expect("serialization failed"); + assert_eq!(v[0] as u32, t.tag().0); + assert_eq!(v[1] as usize, t.as_ref().len()); + assert_eq!(&v[2..], $s.as_bytes()); + let (_, t2) = <$t>::from_der(&v).expect("decoding serialized object failed"); + assert!(t.eq(&t2)); + }; +} + +macro_rules! test_string_invalid_charset { + ($t:ty, $s:expr) => { + <$t>::test_valid_charset($s.as_bytes()).expect_err("should reject charset"); + }; +} + +#[test] +fn to_der_length() { + // indefinite length + let length = Length::Indefinite; + let v = length.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &[0x80]); + // definite, short form + let length = Length::Definite(3); + let v = length.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &[0x03]); + // definite, long form + let length = Length::Definite(250); + let v = length.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &[0x81, 0xfa]); +} + +#[test] +fn to_der_length_long() { + let s = core::str::from_utf8(&[0x41; 256]).unwrap(); + let v = s.to_der_vec().expect("serialization failed"); + assert_eq!(&v[..4], &[0x0c, 0x82, 0x01, 0x00]); + assert_eq!(&v[4..], s.as_bytes()); +} + +#[test] +fn to_der_tag() { + // short tag, UNIVERSAL + let v = (Class::Universal, false, Tag(0x1a)) + .to_der_vec() + .expect("serialization failed"); + assert_eq!(&v, &[0x1a]); + // short tag, APPLICATION + let v = (Class::Application, false, Tag(0x1a)) + .to_der_vec() + .expect("serialization failed"); + assert_eq!(&v, &[0x1a | (0b01 << 6)]); + // short tag, constructed + let v = (Class::Universal, true, Tag(0x10)) + .to_der_vec() + .expect("serialization failed"); + assert_eq!(&v, &[0x30]); + // long tag, UNIVERSAL + let v = (Class::Universal, false, Tag(0x1a1a)) + .to_der_vec() + .expect("serialization failed"); + assert_eq!(&v, &[0b1_1111, 0x9a, 0x34]); +} + +#[test] +fn to_der_header() { + // simple header + let header = Header::new_simple(Tag::Integer); + let v = header.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &[0x2, 0x0]); + // indefinite length + let header = Header::new(Class::Universal, false, Tag::Integer, Length::Indefinite); + let v = header.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &[0x2, 0x80]); +} + +#[test] +fn to_der_any() { + let header = Header::new_simple(Tag::Integer); + let any = Any::new(header, &hex!("02")); + assert_eq!(any.to_der_len(), Ok(3)); + let v = any.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &[0x02, 0x01, 0x02]); +} + +#[test] +fn to_der_any_raw() { + let header = Header::new(Class::Universal, false, Tag::Integer, Length::Definite(3)); + let any = Any::new(header, &hex!("02")); + // to_vec should compute the length + let v = any.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &[0x02, 0x01, 0x02]); + // to_vec_raw will use the header as provided + let v = any.to_der_vec_raw().expect("serialization failed"); + assert_eq!(&v, &[0x02, 0x03, 0x02]); +} + +#[test] +fn to_der_bitstring() { + let bitstring = BitString::new(6, &hex!("6e 5d c0")); + let v = bitstring.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &hex!("03 04 06 6e 5d c0")); + let (_, result) = BitString::from_der(&v).expect("parsing failed"); + assert!(bitstring.eq(&result)); +} + +#[test] +fn to_der_bmpstring() { + let bmpstring = BmpString::new("User"); + assert_eq!(bmpstring.to_der_len(), Ok(10)); + let v = bmpstring.to_der_vec().expect("serialization failed"); + let expected = &hex!("1e 08 00 55 00 73 00 65 00 72"); + assert_eq!(&v, expected); + assert!(BmpString::test_valid_charset(&v[2..]).is_ok()); + let (_, result) = BmpString::from_der(&v).expect("parsing failed"); + assert!(bmpstring.eq(&result)); + // for coverage + let b1 = BmpString::from("s"); + let s = b1.string(); + let b2 = BmpString::from(s); + assert_eq!(b1, b2); + // long string + let sz = 256; + let s = str::repeat("a", sz); + let bmpstring = BmpString::new(&s); + assert_eq!(bmpstring.to_der_len(), Ok(4 + 2 * s.len())); + let _v = bmpstring.to_der_vec().expect("serialization failed"); +} + +#[test] +fn to_der_bool() { + let v = Boolean::new(0xff) + .to_der_vec() + .expect("serialization failed"); + assert_eq!(&v, &[0x01, 0x01, 0xff]); + // + let v = false.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &[0x01, 0x01, 0x00]); + // + let v = true.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &[0x01, 0x01, 0xff]); + // raw value (not 0 of 0xff) + let v = Boolean::new(0x8a) + .to_der_vec_raw() + .expect("serialization failed"); + assert_eq!(&v, &[0x01, 0x01, 0x8a]); +} + +#[test] +fn to_der_enumerated() { + let v = Enumerated(2).to_der_vec().expect("serialization failed"); + assert_eq!(Enumerated(2).to_der_len(), Ok(3)); + assert_eq!(&v, &[0x0a, 0x01, 0x02]); + // + let (_, result) = Enumerated::from_der(&v).expect("parsing failed"); + assert_eq!(result, Enumerated(2)); +} + +#[test] +fn to_der_generalizedtime() { + // date without millisecond + let dt = ASN1DateTime::new(1999, 12, 31, 23, 59, 59, None, ASN1TimeZone::Z); + let time = GeneralizedTime::new(dt); + let v = time.to_der_vec().expect("serialization failed"); + assert_eq!(&v[..2], &hex!("18 0f")); + assert_eq!(&v[2..], b"19991231235959Z"); + let (_, time2) = GeneralizedTime::from_der(&v).expect("decoding serialized object failed"); + assert!(time.eq(&time2)); + assert_eq!(time.to_der_len(), Ok(0x11)); + // + // date with millisecond + let dt = ASN1DateTime::new(1999, 12, 31, 23, 59, 59, Some(123), ASN1TimeZone::Z); + let time = GeneralizedTime::new(dt); + let v = time.to_der_vec().expect("serialization failed"); + assert_eq!(&v[..2], &hex!("18 13")); + assert_eq!(&v[2..], b"19991231235959.123Z"); + let (_, time2) = GeneralizedTime::from_der(&v).expect("decoding serialized object failed"); + assert!(time.eq(&time2)); +} + +#[test] +fn to_der_graphicstring() { + test_simple_string!(GraphicString, "123456"); + test_string_invalid_charset!(GraphicString, "é23456"); +} + +fn encode_decode_assert_int<T>(t: T, expected: &[u8]) +where + T: ToDer + std::fmt::Debug + Eq, + for<'a> T: TryFrom<Integer<'a>, Error = Error>, +{ + let v = t.to_der_vec().expect("serialization failed"); + assert_eq!(&v, expected); + let (_, obj) = Integer::from_der(&v).expect("decoding serialized object failed"); + let t2: T = obj.try_into().unwrap(); + assert_eq!(t, t2); +} + +#[test] +fn to_der_integer() { + let int = Integer::new(&hex!("02")); + let v = int.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &[0x02, 0x01, 0x02]); + // from_u32 + let int = Integer::from_u32(2); + let v = int.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &[0x02, 0x01, 0x02]); + // impl ToDer for primitive types + encode_decode_assert_int(2u32, &[0x02, 0x01, 0x02]); + // signed i32 (> 0) + encode_decode_assert_int(4, &[0x02, 0x01, 0x04]); + // signed i32 (< 0) + encode_decode_assert_int(-4, &[0x02, 0x01, 0xfc]); + // negative number + encode_decode_assert_int(-1i8, &[0x02, 0x01, 0xff]); +} + +#[test] +fn to_der_null() { + let bytes: &[u8] = &hex!("05 00"); + let s = Null::new(); + assert_eq!(s.to_der_len(), Ok(2)); + let v = s.to_der_vec().expect("serialization failed"); + assert_eq!(&v, bytes); + // unit + assert_eq!(().to_der_len(), Ok(2)); + let (_, s2) = <()>::from_der(&v).expect("decoding serialized object failed"); + assert!(().eq(&s2)); + let v2 = ().to_der_vec().expect("serialization failed"); + assert_eq!(&v2, bytes); + // invalid null encodings + let bytes: &[u8] = &hex!("05 01 00"); + let _ = Null::from_ber(bytes).expect_err("should fail"); + let _ = <()>::from_ber(bytes).expect_err("should fail"); +} + +#[test] +fn to_der_numericstring() { + test_simple_string!(NumericString, "123456"); + test_string_invalid_charset!(NumericString, "abcdef"); + test_string_invalid_charset!(NumericString, "1a"); +} + +#[test] +fn to_der_objectdescriptor() { + test_simple_string!(ObjectDescriptor, "abcdef"); + test_string_invalid_charset!(ObjectDescriptor, "abcdéf"); +} + +#[test] +fn to_der_octetstring() { + let bytes: &[u8] = &hex!("01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f"); + let s = OctetString::from(bytes); + let v = s.to_der_vec().expect("serialization failed"); + assert_eq!(s.to_der_len(), Ok(bytes.len() + 2)); + assert_eq!(&v[..2], &hex!("04 0f")); + assert_eq!(&v[2..], bytes); + let (_, s2) = OctetString::from_der(&v).expect("decoding serialized object failed"); + assert!(s.eq(&s2)); + // + let v = bytes.to_der_vec().expect("serialization failed"); + assert_eq!(bytes.to_der_len(), Ok(bytes.len() + 2)); + assert_eq!(&v[..2], &hex!("04 0f")); + assert_eq!(&v[2..], bytes); + let (_, s2) = OctetString::from_der(&v).expect("decoding serialized object failed"); + assert!(s.eq(&s2)); +} + +#[test] +fn to_der_real_binary() { + // base = 2, value = 4 + let r = Real::binary(2.0, 2, 1); + let v = r.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &hex!("09 03 80 02 01")); + let (_, result) = Real::from_der(&v).expect("parsing failed"); + assert!((r.f64() - result.f64()).abs() < f64::EPSILON); + // + // base = 2, value = 0.5 + let r = Real::binary(0.5, 2, 0); + let v = r.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &hex!("09 03 80 ff 01")); + let (_, result) = Real::from_der(&v).expect("parsing failed"); + assert!((r.f64() - result.f64()).abs() < f64::EPSILON); + // + // base = 2, value = 3.25, but change encoding base (8) + let r = Real::binary(3.25, 2, 0).with_enc_base(8); + let v = r.to_der_vec().expect("serialization failed"); + // note: this encoding has a scale factor (not DER compliant) + assert_eq!(&v, &hex!("09 03 94 ff 0d")); + let (_, result) = Real::from_der(&v).expect("parsing failed"); + assert!((r.f64() - result.f64()).abs() < f64::EPSILON); + // + // base = 2, value = 0.00390625, but change encoding base (16) + let r = Real::binary(0.00390625, 2, 0).with_enc_base(16); + let v = r.to_der_vec().expect("serialization failed"); + // note: this encoding has a scale factor (not DER compliant) + assert_eq!(&v, &hex!("09 03 a0 fe 01")); + let (_, result) = Real::from_der(&v).expect("parsing failed"); + assert!((r.f64() - result.f64()).abs() < f64::EPSILON); + // + // 2 octets for exponent, negative exponent and abs(exponent) is all 1's and fills the whole octet(s) + let r = Real::binary(3.0, 2, -1020); + let v = r.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &hex!("09 04 81 fc 04 03")); + let (_, result) = Real::from_der(&v).expect("parsing failed"); + assert!((r.f64() - result.f64()).abs() < f64::EPSILON); + // + // 3 octets for exponent, and + // check that first 9 bits for exponent are not all 1's + let r = Real::binary(1.0, 2, 262140); + let v = r.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &hex!("09 05 82 03 ff fc 01")); + let (_, result) = Real::from_der(&v).expect("parsing failed"); + // XXX value cannot be represented as f64 (inf) + assert!(result.f64().is_infinite()); + // + // >3 octets for exponent, and + // mantissa < 0 + let r = Real::binary(-1.0, 2, 76354972); + let v = r.to_der_vec().expect("serialization failed"); + let (_, result) = Real::from_der(&v).expect("parsing failed"); + assert_eq!(&v, &hex!("09 07 c3 04 04 8d 15 9c 01")); + // XXX value cannot be represented as f64 (-inf) + assert!(result.f64().is_infinite()); +} + +#[test] +fn to_der_real_special() { + // ZERO + let r = Real::Zero; + let v = r.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &hex!("09 00")); + let (_, result) = Real::from_der(&v).expect("parsing failed"); + assert!(r.eq(&result)); + // INFINITY + let r = Real::Infinity; + let v = r.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &hex!("09 01 40")); + let (_, result) = Real::from_der(&v).expect("parsing failed"); + assert!(r.eq(&result)); + // MINUS INFINITY + let r = Real::NegInfinity; + let v = r.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &hex!("09 01 41")); + let (_, result) = Real::from_der(&v).expect("parsing failed"); + assert!(r.eq(&result)); +} + +#[test] +fn to_der_real_string() { + // non-zero value, base 10 + let r = Real::new(1.2345); + let v = r.to_der_vec().expect("serialization failed"); + // assert_eq!(&v, &hex!("09 00")); + let (_, result) = Real::from_der(&v).expect("parsing failed"); + assert!(r.eq(&result)); +} + +#[test] +fn to_der_sequence() { + let it = [2, 3, 4].iter(); + let seq = Sequence::from_iter_to_der(it).unwrap(); + let v = seq.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &hex!("30 09 02 01 02 02 01 03 02 01 04")); + let (_, seq2) = Sequence::from_der(&v).expect("decoding serialized object failed"); + assert_eq!(seq, seq2); + // Vec<T>::ToDer + let v = vec![2, 3, 4].to_der_vec().expect("serialization failed"); + assert_eq!(&v, &hex!("30 09 02 01 02 02 01 03 02 01 04")); +} + +#[test] +fn to_der_set() { + let it = [2u8, 3, 4].iter(); + let set = Set::from_iter_to_der(it).unwrap(); + let v = set.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &hex!("31 09 02 01 02 02 01 03 02 01 04")); + // let (_, set2) = Set::from_der(&v).expect("decoding serialized object failed"); + // assert_eq!(set, set2); + // BTreeSet<T>::ToDer + let set2 = BTreeSet::from_iter(vec![2, 3, 4]); + let v = set2.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &hex!("31 09 02 01 02 02 01 03 02 01 04")); +} + +#[test] +fn to_der_str() { + let s = "abcdef"; + assert_eq!(s.to_der_len(), Ok(2 + s.len())); + let v = s.to_der_vec().expect("serialization failed"); + assert_eq!(&v[..2], &hex!("0c 06")); + assert_eq!(&v[2..], b"abcdef"); + let (_, s2) = Utf8String::from_der(&v).expect("decoding serialized object failed"); + assert!(s.eq(s2.as_ref())); + // long string + let sz = 256; + let s = str::repeat("a", sz); + let s = s.as_str(); + assert_eq!(s.to_der_len(), Ok(4 + sz)); + let v = s.to_der_vec().expect("serialization failed"); + assert_eq!(v.len(), 4 + sz); +} + +#[test] +fn to_der_string() { + let s = "abcdef".to_string(); + assert_eq!(s.to_der_len(), Ok(2 + s.len())); + let v = s.to_der_vec().expect("serialization failed"); + assert_eq!(&v[..2], &hex!("0c 06")); + assert_eq!(&v[2..], b"abcdef"); + let (_, s2) = Utf8String::from_der(&v).expect("decoding serialized object failed"); + assert!(s.eq(s2.as_ref())); + // long string + let sz = 256; + let s = str::repeat("a", sz); + assert_eq!(s.to_der_len(), Ok(4 + sz)); + let v = s.to_der_vec().expect("serialization failed"); + assert_eq!(v.len(), 4 + sz); +} + +#[test] +fn to_der_tagged_explicit() { + let tagged = TaggedParser::new_explicit(Class::ContextSpecific, 1, 2u32); + let v = tagged.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &hex!("a1 03 02 01 02")); + let (_, t2) = + TaggedParser::<Explicit, u32>::from_der(&v).expect("decoding serialized object failed"); + assert!(tagged.eq(&t2)); + // TaggedValue API + let tagged = TaggedValue::explicit(2u32); + let v = tagged.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &hex!("a1 03 02 01 02")); + let (_, t2) = + TaggedExplicit::<u32, Error, 1>::from_der(&v).expect("decoding serialized object failed"); + assert!(tagged.eq(&t2)); +} + +#[test] +fn to_der_tagged_implicit() { + let tagged = TaggedParser::new_implicit(Class::ContextSpecific, false, 1, 2u32); + let v = tagged.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &hex!("81 01 02")); + let (_, t2) = + TaggedParser::<Implicit, u32>::from_der(&v).expect("decoding serialized object failed"); + assert!(tagged.eq(&t2)); + // TaggedValue API + let tagged = TaggedValue::implicit(2u32); + let v = tagged.to_der_vec().expect("serialization failed"); + assert_eq!(&v, &hex!("81 01 02")); + let (_, t2) = + TaggedImplicit::<u32, Error, 1>::from_der(&v).expect("decoding serialized object failed"); + assert!(tagged.eq(&t2)); +} + +#[test] +fn to_der_teletexstring() { + test_simple_string!(TeletexString, "abcdef"); +} + +#[test] +fn to_der_utctime() { + let dt = ASN1DateTime::new(99, 12, 31, 23, 59, 59, None, ASN1TimeZone::Z); + let time = UtcTime::new(dt); + let v = time.to_der_vec().expect("serialization failed"); + assert_eq!(&v[..2], &hex!("17 0d")); + assert_eq!(&v[2..], b"991231235959Z"); + let (_, time2) = UtcTime::from_der(&v).expect("decoding serialized object failed"); + assert!(time.eq(&time2)); +} + +#[test] +fn to_der_universalstring() { + const S: &str = "abcdef"; + let s = UniversalString::from(S); + assert_eq!(s.to_der_len(), Ok(2 + 4 * S.len())); + let v = s.to_der_vec().expect("serialization failed"); + assert_eq!( + &v, + &hex!("1c 18 00000061 00000062 00000063 00000064 00000065 00000066") + ); + let (_, s2) = UniversalString::from_der(&v).expect("decoding serialized object failed"); + assert!(s.eq(&s2)); + // long string + let sz = 256; + let s = str::repeat("a", sz); + let s = UniversalString::from(s); + assert_eq!(s.to_der_len(), Ok(4 + 4 * sz)); + let v = s.to_der_vec().expect("serialization failed"); + assert_eq!(v.len(), 4 + 4 * sz); +} + +#[test] +fn to_der_utf8string() { + test_simple_string!(Utf8String, "abcdef"); +} + +#[test] +fn to_der_visiblestring() { + test_simple_string!(VisibleString, "abcdef"); + test_string_invalid_charset!(VisibleString, "abcdéf"); +} + +#[test] +fn to_der_videotexstring() { + test_simple_string!(VideotexString, "abcdef"); +} diff --git a/rust/vendor/asn1-rs/tests/x509.rs b/rust/vendor/asn1-rs/tests/x509.rs new file mode 100644 index 0000000..31fa595 --- /dev/null +++ b/rust/vendor/asn1-rs/tests/x509.rs @@ -0,0 +1,158 @@ +//! Test implementation for X.509 +//! +//! This is mostly used to verify that required types and functions are implemented, +//! and that provided API is convenient. + +use asn1_rs::{ + nom, Any, CheckDerConstraints, Choice, Error, FromBer, FromDer, Oid, ParseResult, Sequence, + SetOf, Tag, Tagged, +}; +use hex_literal::hex; +use nom::sequence::pair; +use std::convert::{TryFrom, TryInto}; + +const DN: &[u8] = &hex!( + " +30 45 31 0b 30 09 06 03 55 04 06 13 02 46 52 +31 13 30 11 06 03 55 04 08 0c 0a 53 6f 6d 65 +2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 0a +0c 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 +69 74 73 20 50 74 79 20 4c 74 64 +" +); + +// Name ::= CHOICE { -- only one possibility for now -- +// rdnSequence RDNSequence } + +// RDNSequence ::= SEQUENCE OF RelativeDistinguishedName +#[derive(Debug)] +pub struct Name<'a> { + pub rdn_sequence: Vec<RelativeDistinguishedName<'a>>, +} + +impl<'a> FromDer<'a> for Name<'a> { + fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self> { + let (rem, rdn_sequence) = <Vec<RelativeDistinguishedName>>::from_der(bytes)?; + let dn = Name { rdn_sequence }; + Ok((rem, dn)) + } +} + +// RelativeDistinguishedName ::= +// SET SIZE (1..MAX) OF AttributeTypeAndValue +#[derive(Debug)] +pub struct RelativeDistinguishedName<'a> { + pub v: Vec<AttributeTypeAndValue<'a>>, +} + +impl<'a> FromDer<'a> for RelativeDistinguishedName<'a> { + fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self> { + let (rem, set) = SetOf::<AttributeTypeAndValue>::from_der(bytes)?; + let v: Vec<_> = set.into(); + if v.is_empty() { + return Err(nom::Err::Failure(Error::InvalidLength)); + } + Ok((rem, RelativeDistinguishedName { v })) + } +} + +// AttributeTypeAndValue ::= SEQUENCE { +// type AttributeType, +// value AttributeValue } +#[derive(Debug)] +pub struct AttributeTypeAndValue<'a> { + pub oid: Oid<'a>, + pub value: AttributeValue<'a>, +} + +impl<'a> FromBer<'a> for AttributeTypeAndValue<'a> { + fn from_ber(bytes: &'a [u8]) -> ParseResult<'a, Self> { + let (rem, seq) = Sequence::from_der(bytes)?; + let (_, (oid, value)) = + seq.parse_into(|i| pair(Oid::from_der, AttributeValue::from_der)(i))?; + let attr = AttributeTypeAndValue { oid, value }; + Ok((rem, attr)) + } +} + +impl<'a> FromDer<'a> for AttributeTypeAndValue<'a> { + fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self> { + let (rem, seq) = Sequence::from_der(bytes)?; + let (_, (oid, value)) = + seq.parse_into(|i| pair(Oid::from_der, AttributeValue::from_der)(i))?; + let attr = AttributeTypeAndValue { oid, value }; + Ok((rem, attr)) + } +} + +impl<'a> CheckDerConstraints for AttributeTypeAndValue<'a> { + fn check_constraints(any: &Any) -> asn1_rs::Result<()> { + any.tag().assert_eq(Sequence::TAG)?; + Ok(()) + } +} + +// AttributeType ::= OBJECT IDENTIFIER + +// AttributeValue ::= ANY -- DEFINED BY AttributeType +#[derive(Debug)] +pub enum AttributeValue<'a> { + DirectoryString(DirectoryString), + Other(Any<'a>), +} + +impl<'a> FromDer<'a> for AttributeValue<'a> { + fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self> { + let (rem, any) = Any::from_der(bytes)?; + let ds = if DirectoryString::can_decode(any.tag()) { + AttributeValue::DirectoryString(any.try_into()?) + } else { + AttributeValue::Other(any) + }; + Ok((rem, ds)) + } +} + +// DirectoryString ::= CHOICE { +// teletexString TeletexString (SIZE (1..MAX)), +// printableString PrintableString (SIZE (1..MAX)), +// universalString UniversalString (SIZE (1..MAX)), +// utf8String UTF8String (SIZE (1..MAX)), +// bmpString BMPString (SIZE (1..MAX)) } +#[derive(Debug)] +pub enum DirectoryString { + Printable(String), + Utf8(String), +} + +impl Choice for DirectoryString { + fn can_decode(tag: Tag) -> bool { + matches!(tag, Tag::PrintableString | Tag::Utf8String) + } +} + +impl<'a> TryFrom<Any<'a>> for DirectoryString { + type Error = Error; + + fn try_from(any: Any<'a>) -> Result<Self, Self::Error> { + match any.tag() { + Tag::PrintableString => { + let s = any.printablestring()?; + Ok(DirectoryString::Printable(s.string())) + } + Tag::Utf8String => { + let s = any.string()?; + Ok(DirectoryString::Utf8(s)) + } + _ => Err(Error::InvalidTag), + } + } +} + +#[test] +fn x509_decode_dn() { + let (rem, dn) = Name::from_der(DN).expect("parsing failed"); + assert!(rem.is_empty()); + // dbg!(&dn); + assert_eq!(dn.rdn_sequence.len(), 3); +} |