diff options
Diffstat (limited to 'rust/vendor/der-parser/tests')
-rw-r--r-- | rust/vendor/der-parser/tests/ber_parser.rs | 556 | ||||
-rw-r--r-- | rust/vendor/der-parser/tests/constructed.rs | 441 | ||||
-rw-r--r-- | rust/vendor/der-parser/tests/custom_error.rs | 53 | ||||
-rw-r--r-- | rust/vendor/der-parser/tests/der_constructed.rs | 177 | ||||
-rw-r--r-- | rust/vendor/der-parser/tests/der_parser.rs | 628 | ||||
-rw-r--r-- | rust/vendor/der-parser/tests/fuzz01.rs | 5 | ||||
-rw-r--r-- | rust/vendor/der-parser/tests/fuzz02.rs | 22 | ||||
-rw-r--r-- | rust/vendor/der-parser/tests/oid.rs | 25 | ||||
-rw-r--r-- | rust/vendor/der-parser/tests/primitive.rs | 236 |
9 files changed, 2143 insertions, 0 deletions
diff --git a/rust/vendor/der-parser/tests/ber_parser.rs b/rust/vendor/der-parser/tests/ber_parser.rs new file mode 100644 index 0000000..3d61574 --- /dev/null +++ b/rust/vendor/der-parser/tests/ber_parser.rs @@ -0,0 +1,556 @@ +// test_case seem to generate this warning - ignore it +#![allow(clippy::unused_unit)] + +use der_parser::ber::*; +use der_parser::error::*; +use der_parser::oid::*; +use hex_literal::hex; +use nom::Err; +// use pretty_assertions::assert_eq; +use test_case::test_case; + +#[cfg(feature = "bigint")] +use num_bigint::{BigInt, BigUint, Sign}; + +#[test_case(&hex!("01 01 00"), Some(false) ; "val false")] +#[test_case(&hex!("01 01 ff"), Some(true) ; "val true")] +#[test_case(&hex!("01 01 7f"), Some(true) ; "true not ff")] +#[test_case(&hex!("01 02 00 00"), None ; "invalid length")] +#[test_case(&hex!("01 01"), None ; "incomplete")] +fn tc_ber_bool(i: &[u8], out: Option<bool>) { + let res = parse_ber_bool(i); + if let Some(b) = out { + let expected = BerObject::from_obj(BerObjectContent::Boolean(b)); + pretty_assertions::assert_eq!(res, Ok((&b""[..], expected))); + } else { + assert!(res.is_err()); + } +} + +#[test] +fn test_ber_bool() { + let empty = &b""[..]; + let b_true = BerObject::from_obj(BerObjectContent::Boolean(true)); + let b_false = BerObject::from_obj(BerObjectContent::Boolean(false)); + assert_eq!(parse_ber_bool(&[0x01, 0x01, 0x00]), Ok((empty, b_false))); + assert_eq!( + parse_ber_bool(&[0x01, 0x01, 0xff]), + Ok((empty, b_true.clone())) + ); + assert_eq!(parse_ber_bool(&[0x01, 0x01, 0x7f]), Ok((empty, b_true))); + assert_eq!( + parse_ber_bool(&[0x01, 0x02, 0x12, 0x34]), + Err(Err::Error(BerError::InvalidLength)) + ); +} + +#[test] +fn test_seq_indefinite_length() { + let data = hex!("30 80 04 03 56 78 90 00 00 02 01 01"); + let res = parse_ber(&data); + assert_eq!( + res, + Ok(( + &data[9..], + BerObject::from_seq(vec![BerObject::from_obj(BerObjectContent::OctetString( + &data[4..=6] + )),]) + )) + ); + let res = parse_ber_sequence(&data); + assert_eq!( + res, + Ok(( + &data[9..], + BerObject::from_seq(vec![BerObject::from_obj(BerObjectContent::OctetString( + &data[4..=6] + )),]) + )) + ); +} + +#[test] +fn test_ber_set_of() { + let empty = &b""[..]; + let bytes = [ + 0x31, 0x0a, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x00, + ]; + let expected = BerObject::from_set(vec![ + BerObject::from_int_slice(b"\x01\x00\x01"), + BerObject::from_int_slice(b"\x01\x00\x00"), + ]); + fn parser(i: &[u8]) -> BerResult { + parse_ber_set_of(parse_ber_integer)(i) + } + assert_eq!(parser(&bytes), Ok((empty, expected))); + // empty input should raise error (could not read set header) + assert!(parser(&[]).is_err()); + // empty set is ok (returns empty vec) + assert!(parser(&[0x31, 0x00]).is_ok()); +} + +#[test] +fn test_ber_set_of_v() { + let empty = &b""[..]; + let bytes = [ + 0x31, 0x0a, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x00, + ]; + let expected = vec![ + BerObject::from_int_slice(b"\x01\x00\x01"), + BerObject::from_int_slice(b"\x01\x00\x00"), + ]; + fn parser(i: &[u8]) -> BerResult<Vec<BerObject>> { + parse_ber_set_of_v(parse_ber_integer)(i) + } + assert_eq!(parser(&bytes), Ok((empty, expected))); + // empty input should raise error (could not read set header) + assert!(parser(&[]).is_err()); + // empty set is ok (returns empty vec) + assert_eq!(parser(&[0x31, 0x00]), Ok((empty, vec![]))); +} + +#[test] +fn test_set_indefinite_length() { + let data = hex!("31 80 04 03 56 78 90 00 00"); + let res = parse_ber(&data); + assert_eq!( + res, + Ok(( + &data[9..], + BerObject::from_set(vec![BerObject::from_obj(BerObjectContent::OctetString( + &data[4..=6] + )),]) + )) + ); + let res = parse_ber_set(&data); + assert_eq!( + res, + Ok(( + &data[9..], + BerObject::from_set(vec![BerObject::from_obj(BerObjectContent::OctetString( + &data[4..=6] + )),]) + )) + ); +} + +#[test] +fn test_ber_int() { + let empty = &b""[..]; + let bytes = [0x02, 0x03, 0x01, 0x00, 0x01]; + let expected = BerObject::from_obj(BerObjectContent::Integer(b"\x01\x00\x01")); + assert_eq!(parse_ber_integer(&bytes), Ok((empty, expected))); +} + +#[test_case(&hex!("02 01 01"), Ok(1) ; "u32-1")] +#[test_case(&hex!("02 02 00 ff"), Ok(255) ; "u32-255")] +#[test_case(&hex!("02 02 01 23"), Ok(0x123) ; "u32-0x123")] +#[test_case(&hex!("02 04 01 23 45 67"), Ok(0x0123_4567) ; "u32-long-ok")] +#[test_case(&hex!("02 05 00 ff ff ff ff"), Ok(0xffff_ffff) ; "u32-long2-ok")] +#[test_case(&hex!("02 04 ff ff ff ff"), Err(BerError::IntegerNegative) ; "u32-long2-neg")] +#[test_case(&hex!("02 06 ff ff ff ff ff ff"), Err(BerError::IntegerNegative) ; "u32-long3-neg")] +#[test_case(&hex!("02 06 00 00 01 23 45 67"), Ok(0x0123_4567) ; "u32-long-leading-zeros-ok")] +#[test_case(&hex!("02 05 01 23 45 67 01"), Err(BerError::IntegerTooLarge) ; "u32 too large")] +#[test_case(&hex!("02 09 01 23 45 67 01 23 45 67 ab"), Err(BerError::IntegerTooLarge) ; "u32 too large 2")] +#[test_case(&hex!("03 03 01 00 01"), Err(BerError::unexpected_tag(Some(Tag(2)), Tag(3))) ; "invalid tag")] +fn tc_ber_u32(i: &[u8], out: Result<u32, BerError>) { + let res = parse_ber_u32(i); + match out { + Ok(expected) => { + pretty_assertions::assert_eq!(res, Ok((&b""[..], expected))); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(Err::Error(e))); + } + } +} + +#[test_case(&hex!("02 01 01"), Ok(1) ; "u64-1")] +#[test_case(&hex!("02 02 00 ff"), Ok(255) ; "u64-255")] +#[test_case(&hex!("02 02 01 23"), Ok(0x123) ; "u64-0x123")] +#[test_case(&hex!("02 08 01 23 45 67 01 23 45 67"), Ok(0x0123_4567_0123_4567) ; "u64-long-ok")] +#[test_case(&hex!("02 09 00 ff ff ff ff ff ff ff ff"), Ok(0xffff_ffff_ffff_ffff) ; "u64-long2-ok")] +#[test_case(&hex!("02 09 01 23 45 67 01 23 45 67 ab"), Err(BerError::IntegerTooLarge) ; "u64 too large")] +#[test_case(&hex!("03 03 01 00 01"), Err(BerError::unexpected_tag(Some(Tag(2)), Tag(3))) ; "invalid tag")] +fn tc_ber_u64(i: &[u8], out: Result<u64, BerError>) { + let res = parse_ber_u64(i); + match out { + Ok(expected) => { + pretty_assertions::assert_eq!(res, Ok((&b""[..], expected))); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(Err::Error(e))); + } + } +} + +#[test_case(&hex!("02 01 01"), Ok(1) ; "i64-1")] +#[test_case(&hex!("02 01 ff"), Ok(-1) ; "i64-neg1")] +#[test_case(&hex!("02 01 80"), Ok(-128) ; "i64-neg128")] +#[test_case(&hex!("02 02 ff 7f"), Ok(-129) ; "i64-neg129")] +#[test_case(&hex!("02 04 ff ff ff ff"), Ok(-1) ; "i64-long-neg")] +#[test_case(&hex!("03 03 01 00 01"), Err(BerError::unexpected_tag(Some(Tag(2)), Tag(3))) ; "invalid tag")] +fn tc_ber_i64(i: &[u8], out: Result<i64, BerError>) { + let res = parse_ber_i64(i); + match out { + Ok(expected) => { + pretty_assertions::assert_eq!(res, Ok((&b""[..], expected))); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(Err::Error(e))); + } + } +} + +#[cfg(feature = "bigint")] +#[test_case(&hex!("02 01 01"), Ok(BigInt::from(1)) ; "bigint-1")] +#[test_case(&hex!("02 02 00 ff"), Ok(BigInt::from(255)) ; "bigint-255")] +#[test_case(&hex!("02 01 ff"), Ok(BigInt::from(-1)) ; "bigint-neg1")] +#[test_case(&hex!("02 01 80"), Ok(BigInt::from(-128)) ; "bigint-neg128")] +#[test_case(&hex!("02 02 ff 7f"), Ok(BigInt::from(-129)) ; "bigint-neg129")] +#[test_case(&hex!("02 09 00 ff ff ff ff ff ff ff ff"), Ok(BigInt::from(0xffff_ffff_ffff_ffff_u64)) ; "bigint-long2-ok")] +#[test_case(&hex!("02 09 01 23 45 67 01 23 45 67 ab"), Ok(BigInt::from_bytes_be(Sign::Plus, &hex!("01 23 45 67 01 23 45 67 ab"))) ; "bigint-longer1")] +fn tc_ber_bigint(i: &[u8], out: Result<BigInt, BerError>) { + let res = parse_ber_integer(i); + match out { + Ok(expected) => { + let (rem, ber) = res.expect("parsing failed"); + assert!(rem.is_empty()); + let int = ber.as_bigint().expect("failed to convert to bigint"); + pretty_assertions::assert_eq!(int, expected); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(Err::Error(e))); + } + } +} + +#[cfg(feature = "bigint")] +#[test_case(&hex!("02 01 01"), Ok(BigUint::from(1_u8)) ; "biguint-1")] +#[test_case(&hex!("02 02 00 ff"), Ok(BigUint::from(255_u8)) ; "biguint-255")] +#[test_case(&hex!("02 01 ff"), Err(BerError::IntegerNegative) ; "biguint-neg1")] +#[test_case(&hex!("02 01 80"), Err(BerError::IntegerNegative) ; "biguint-neg128")] +#[test_case(&hex!("02 02 ff 7f"), Err(BerError::IntegerNegative) ; "biguint-neg129")] +#[test_case(&hex!("02 09 00 ff ff ff ff ff ff ff ff"), Ok(BigUint::from(0xffff_ffff_ffff_ffff_u64)) ; "biguint-long2-ok")] +#[test_case(&hex!("02 09 01 23 45 67 01 23 45 67 ab"), Ok(BigUint::from_bytes_be(&hex!("01 23 45 67 01 23 45 67 ab"))) ; "biguint-longer1")] +#[test_case(&hex!("03 03 01 00 01"), Err(BerError::unexpected_tag(Some(Tag(2)), Tag(3))) ; "invalid tag")] +fn tc_ber_biguint(i: &[u8], out: Result<BigUint, BerError>) { + let res = parse_ber_integer(i).and_then(|(rem, ber)| Ok((rem, ber.as_biguint()?))); + match out { + Ok(expected) => { + pretty_assertions::assert_eq!(res, Ok((&b""[..], expected))); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(Err::Error(e))); + } + } +} + +#[test_case(&hex!("02 01 01"), Ok(&[1]) ; "slice 1")] +#[test_case(&hex!("02 01 ff"), Ok(&[255]) ; "slice 2")] +#[test_case(&hex!("02 09 01 23 45 67 01 23 45 67 ab"), Ok(&hex!("01 23 45 67 01 23 45 67 ab")) ; "slice 3")] +#[test_case(&hex!("22 80 02 01 01 00 00"), Ok(&[2, 1, 1]) ; "constructed slice")] +#[test_case(&hex!("03 03 01 00 01"), Err(BerError::unexpected_tag(Some(Tag(2)), Tag(3))) ; "invalid tag")] +fn tc_ber_slice(i: &[u8], out: Result<&[u8], BerError>) { + let res = parse_ber_slice(i, 2); + match out { + Ok(expected) => { + pretty_assertions::assert_eq!(res, Ok((&b""[..], expected))); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(Err::Error(e))); + } + } +} + +#[test] +fn test_ber_bitstring_primitive() { + let empty = &b""[..]; + let bytes = &[0x03, 0x07, 0x04, 0x0a, 0x3b, 0x5f, 0x29, 0x1c, 0xd0]; + let expected = BerObject::from_obj(BerObjectContent::BitString( + 4, + BitStringObject { data: &bytes[3..] }, + )); + assert_eq!(parse_ber_bitstring(bytes), Ok((empty, expected))); + // + // correct encoding, padding bits not all set to 0 + // + let bytes = &[0x03, 0x04, 0x06, 0x6e, 0x5d, 0xe0]; + let expected = BerObject::from_obj(BerObjectContent::BitString( + 6, + BitStringObject { data: &bytes[3..] }, + )); + assert_eq!(parse_ber_bitstring(bytes), Ok((empty, expected))); + // + // long form of length + // + let bytes = &[0x03, 0x81, 0x04, 0x06, 0x6e, 0x5d, 0xc0]; + let expected = BerObject::from_obj(BerObjectContent::BitString( + 6, + BitStringObject { data: &bytes[4..] }, + )); + assert_eq!(parse_ber_bitstring(bytes), Ok((empty, expected))); +} + +#[test] +fn test_ber_bitstring_constructed() { + let bytes = &[ + 0x23, 0x80, 0x03, 0x03, 0x00, 0x0a, 0x3b, 0x03, 0x05, 0x04, 0x5f, 0x29, 0x1c, 0xd0, 0x00, + 0x00, + ]; + assert_eq!( + parse_ber_bitstring(bytes), + Err(Err::Error(BerError::Unsupported)) + ); // XXX valid encoding +} + +#[test] +fn test_ber_octetstring_primitive() { + let empty = &b""[..]; + let bytes = [0x04, 0x05, 0x41, 0x41, 0x41, 0x41, 0x41]; + let expected = BerObject::from_obj(BerObjectContent::OctetString(b"AAAAA")); + assert_eq!(parse_ber_octetstring(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_ber_null() { + let empty = &b""[..]; + let expected = BerObject::from_obj(BerObjectContent::Null); + assert_eq!(parse_ber_null(&[0x05, 0x00]), Ok((empty, expected))); +} + +#[test] +fn test_ber_oid() { + let empty = &b""[..]; + let bytes = [ + 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, + ]; + let expected = BerObject::from_obj(BerObjectContent::OID( + Oid::from(&[1, 2, 840, 113_549, 1, 1, 5]).unwrap(), + )); + assert_eq!(parse_ber_oid(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_ber_enum() { + let empty = &b""[..]; + let expected = BerObject::from_obj(BerObjectContent::Enum(2)); + assert_eq!(parse_ber_enum(&[0x0a, 0x01, 0x02]), Ok((empty, expected))); +} + +#[test_case(&hex!("0c 04 31 32 33 34"), Ok("1234") ; "utf8: numeric")] +#[test_case(&hex!("0c 05 68 65 6c 6c 6f"), Ok("hello") ; "utf8: string")] +#[test_case(&hex!("0c 0b 68 65 6c 6c 6f 20 77 6f 72 6c 64"), Ok("hello world") ; "utf8: string with spaces")] +#[test_case(&hex!("0c 0b 68 65 6c 6c 6f 5c 77 6f 72 6c 64"), Ok("hello\\world") ; "utf8: string with backspace")] +#[test_case(&hex!("0c 0b 68 65 6c 6c 6f 2b 77 6f 72 6c 64"), Ok("hello+world") ; "utf8: string with plus")] +#[test_case(&hex!("0c 05 01 02 03 04 05"), Ok("\x01\x02\x03\x04\x05") ; "invalid chars")] +#[test_case(&hex!("0c 0e d0 bf d1 80 d0 b8 d0 b2 d0 b5 cc 81 d1 82"), Ok("приве́т") ; "utf8")] +#[test_case(&hex!("0c 04 00 9f 92 96"), Err(Err::Error(BerError::StringInvalidCharset)) ; "invalid utf8")] +fn tc_ber_utf8_string(i: &[u8], out: Result<&str, Err<BerError>>) { + let res = parse_ber_utf8string(i); + match out { + Ok(b) => { + let (rem, res) = res.expect("could not parse utf8string"); + assert!(rem.is_empty()); + let r = res.as_str().expect("could not convert to string"); + // let expected = BerObject::from_obj(BerObjectContent::Boolean(b)); + pretty_assertions::assert_eq!(r, b); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(e)); + } + } +} + +#[test_case(&hex!("12 04 31 32 33 34"), Ok("1234") ; "numeric string")] +#[test_case(&hex!("12 05 68 65 6c 6c 6f"), Err(Err::Error(BerError::StringInvalidCharset)) ; "invalid chars")] +#[test_case(&hex!("12 05 01 02 03 04 05"), Err(Err::Error(BerError::StringInvalidCharset)) ; "invalid chars2")] +fn tc_ber_numeric_string(i: &[u8], out: Result<&str, Err<BerError>>) { + let res = parse_ber_numericstring(i); + match out { + Ok(b) => { + let (rem, res) = res.expect("could not parse numericstring"); + assert!(rem.is_empty()); + let r = res.as_str().expect("could not convert to string"); + // let expected = BerObject::from_obj(BerObjectContent::Boolean(b)); + pretty_assertions::assert_eq!(r, b); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(e)); + } + } +} + +#[test_case(&hex!("13 04 31 32 33 34"), Ok("1234") ; "printable: numeric")] +#[test_case(&hex!("13 05 68 65 6c 6c 6f"), Ok("hello") ; "printable: string")] +#[test_case(&hex!("13 0b 68 65 6c 6c 6f 20 77 6f 72 6c 64"), Ok("hello world") ; "printable: string with spaces")] +#[test_case(&hex!("13 0b 68 65 6c 6c 6f 5c 77 6f 72 6c 64"), Err(Err::Error(BerError::StringInvalidCharset)) ; "printable: string with backspace")] +#[test_case(&hex!("13 0b 68 65 6c 6c 6f 2b 77 6f 72 6c 64"), Ok("hello+world") ; "printable: string with plus")] +#[test_case(&hex!("13 05 01 02 03 04 05"), Err(Err::Error(BerError::StringInvalidCharset)) ; "invalid chars")] +fn tc_ber_printable_string(i: &[u8], out: Result<&str, Err<BerError>>) { + let res = parse_ber_printablestring(i); + match out { + Ok(b) => { + let (rem, res) = res.expect("could not parse printablestring"); + assert!(rem.is_empty()); + let r = res.as_str().expect("could not convert to string"); + // let expected = BerObject::from_obj(BerObjectContent::Boolean(b)); + pretty_assertions::assert_eq!(r, b); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(e)); + } + } +} + +#[test_case(&hex!("16 04 31 32 33 34"), Ok("1234") ; "ia5: numeric")] +#[test_case(&hex!("16 05 68 65 6c 6c 6f"), Ok("hello") ; "ia5: string")] +#[test_case(&hex!("16 0b 68 65 6c 6c 6f 20 77 6f 72 6c 64"), Ok("hello world") ; "ia5: string with spaces")] +#[test_case(&hex!("16 0b 68 65 6c 6c 6f 5c 77 6f 72 6c 64"), Ok("hello\\world") ; "ia5: string with backspace")] +#[test_case(&hex!("16 0b 68 65 6c 6c 6f 2b 77 6f 72 6c 64"), Ok("hello+world") ; "ia5: string with plus")] +#[test_case(&hex!("16 05 01 02 03 04 05"), Ok("\x01\x02\x03\x04\x05") ; "invalid chars")] +#[test_case(&hex!("16 0d d0 bf d1 80 d0 b8 d0 b2 d0 b5 cc 81 d1 82"), Err(Err::Error(BerError::StringInvalidCharset)) ; "utf8")] +fn tc_ber_ia5_string(i: &[u8], out: Result<&str, Err<BerError>>) { + let res = parse_ber_ia5string(i); + match out { + Ok(b) => { + let (rem, res) = res.expect("could not parse ia5string"); + assert!(rem.is_empty()); + let r = res.as_str().expect("could not convert to string"); + // let expected = BerObject::from_obj(BerObjectContent::Boolean(b)); + pretty_assertions::assert_eq!(r, b); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(e)); + } + } +} + +#[test_case(&hex!("1a 04 31 32 33 34"), Ok("1234") ; "visible: numeric")] +#[test_case(&hex!("1a 05 68 65 6c 6c 6f"), Ok("hello") ; "visible: string")] +#[test_case(&hex!("1a 0b 68 65 6c 6c 6f 20 77 6f 72 6c 64"), Ok("hello world") ; "visible: string with spaces")] +#[test_case(&hex!("1a 0b 68 65 6c 6c 6f 5c 77 6f 72 6c 64"), Ok("hello\\world") ; "printable: string with backspace")] +#[test_case(&hex!("1a 0b 68 65 6c 6c 6f 2b 77 6f 72 6c 64"), Ok("hello+world") ; "printable: string with plus")] +#[test_case(&hex!("1a 05 01 02 03 04 05"), Err(Err::Error(BerError::StringInvalidCharset)) ; "invalid chars")] +fn tc_ber_visible_string(i: &[u8], out: Result<&str, Err<BerError>>) { + let res = parse_ber_visiblestring(i); + match out { + Ok(b) => { + let (rem, res) = res.expect("could not parse visiblestring"); + assert!(rem.is_empty()); + let r = res.as_str().expect("could not convert to string"); + // let expected = BerObject::from_obj(BerObjectContent::Boolean(b)); + pretty_assertions::assert_eq!(r, b); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(e)); + } + } +} + +#[test] +fn test_ber_utf8string() { + let empty = &b""[..]; + let bytes = [ + 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, + ]; + let expected = BerObject::from_obj(BerObjectContent::UTF8String("Some-State")); + assert_eq!(parse_ber_utf8string(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_ber_relativeoid() { + let empty = &b""[..]; + let bytes = hex!("0d 04 c2 7b 03 02"); + let expected = BerObject::from_obj(BerObjectContent::RelativeOID( + Oid::from_relative(&[8571, 3, 2]).unwrap(), + )); + assert_eq!(parse_ber_relative_oid(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_ber_bmpstring() { + let empty = &b""[..]; + let bytes = hex!("1e 08 00 55 00 73 00 65 00 72"); + let expected = BerObject::from_obj(BerObjectContent::BmpString("\x00U\x00s\x00e\x00r")); + assert_eq!(parse_ber_bmpstring(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_ber_customtags() { + let bytes = hex!("8f 02 12 34"); + let hdr = ber_read_element_header(&bytes) + .expect("ber_read_element_header") + .1; + // println!("{:?}", hdr); + let expected: &[u8] = &[0x8f]; + assert_eq!(hdr.raw_tag(), Some(expected)); + let bytes = hex!("9f 0f 02 12 34"); + let hdr = ber_read_element_header(&bytes) + .expect("ber_read_element_header") + .1; + // println!("{:?}", hdr); + let expected: &[u8] = &[0x9f, 0x0f]; + assert_eq!(hdr.raw_tag(), Some(expected)); +} + +#[test] +fn test_ber_indefinite() { + let bytes = hex!("30 80 02 03 01 00 01 00 00"); + let (rem, val) = parse_ber_container::<_, _, BerError>(|i, _| { + assert!(!i.is_empty()); + let (_, val) = parse_ber_u32(i)?; + Ok((i, val)) + })(&bytes) + .unwrap(); + assert!(rem.is_empty()); + assert_eq!(val, 0x10001); +} + +#[test] +fn test_ber_indefinite_recursion() { + let data = &hex!( + " + 24 80 24 80 24 80 24 80 24 80 24 80 24 80 24 80 + 24 80 24 80 24 80 24 80 24 80 24 80 24 80 24 80 + 24 80 24 80 24 80 24 80 24 80 24 80 24 80 24 80 + 24 80 24 80 24 80 24 80 24 80 24 80 24 80 24 80 + 24 80 24 80 24 80 24 80 24 80 24 80 24 80 24 80 + 24 80 24 80 24 80 24 80 24 80 24 80 24 80 24 80 + 24 80 24 80 24 80 24 80 24 80 24 80 24 80 24 80 + 24 80 24 80 24 80 24 80 24 80 24 80 24 80 24 80 + 24 80 24 80 24 80 24 80 24 80 24 80 24 80 24 80 00 00" + ); + let _ = parse_ber_container::<_, _, BerError>(|i, _| Ok((i, ())))(data) + .expect_err("max parsing depth overflow"); +} + +#[test] +fn test_parse_ber_content() { + let bytes = &hex!("02 03 01 00 01"); + let (i, header) = ber_read_element_header(bytes).expect("parsing failed"); + let (rem, content) = + parse_ber_content(header.tag())(i, &header, MAX_RECURSION).expect("parsing failed"); + assert!(rem.is_empty()); + assert_eq!(header.tag(), Tag::Integer); + assert_eq!(content.as_u32(), Ok(0x10001)); +} + +#[test] +fn test_parse_ber_content2() { + let bytes = &hex!("02 03 01 00 01"); + let (i, header) = ber_read_element_header(bytes).expect("parsing failed"); + let tag = header.tag(); + let (rem, content) = parse_ber_content2(tag)(i, header, MAX_RECURSION).expect("parsing failed"); + assert!(rem.is_empty()); + assert_eq!(tag, Tag::Integer); + assert_eq!(content.as_u32(), Ok(0x10001)); +} + +#[test] +fn parse_ber_private() { + let bytes = &hex!("c0 03 01 00 01"); + let (rem, res) = parse_ber(bytes).expect("parsing failed"); + assert!(rem.is_empty()); + assert!(matches!(res.content, BerObjectContent::Unknown(_))); +} diff --git a/rust/vendor/der-parser/tests/constructed.rs b/rust/vendor/der-parser/tests/constructed.rs new file mode 100644 index 0000000..7ba6644 --- /dev/null +++ b/rust/vendor/der-parser/tests/constructed.rs @@ -0,0 +1,441 @@ +// test_case seem to generate this warning - ignore it +#![allow(clippy::unused_unit)] + +use der_parser::ber::*; +use der_parser::der::*; +use der_parser::error::*; +use der_parser::*; +use hex_literal::hex; +use nom::branch::alt; +use nom::combinator::{complete, eof, map, map_res}; +use nom::error::ErrorKind; +use nom::multi::many0; +use nom::sequence::tuple; +use nom::*; +use oid::Oid; +use pretty_assertions::assert_eq; +use test_case::test_case; + +#[derive(Debug, PartialEq)] +struct MyStruct<'a> { + a: BerObject<'a>, + b: BerObject<'a>, +} + +fn parse_struct01(i: &[u8]) -> BerResult<MyStruct> { + parse_der_sequence_defined_g(|i: &[u8], _| { + let (i, a) = parse_ber_integer(i)?; + let (i, b) = parse_ber_integer(i)?; + Ok((i, MyStruct { a, b })) + })(i) +} + +fn parse_struct01_complete(i: &[u8]) -> BerResult<MyStruct> { + parse_der_sequence_defined_g(|i: &[u8], _| { + let (i, a) = parse_ber_integer(i)?; + let (i, b) = parse_ber_integer(i)?; + eof(i)?; + Ok((i, MyStruct { a, b })) + })(i) +} + +// verifying tag +fn parse_struct04(i: &[u8], tag: Tag) -> BerResult<MyStruct> { + parse_der_container(|i: &[u8], hdr| { + if hdr.tag() != tag { + return Err(Err::Error(BerError::InvalidTag)); + } + let (i, a) = parse_ber_integer(i)?; + let (i, b) = parse_ber_integer(i)?; + eof(i)?; + Ok((i, MyStruct { a, b })) + })(i) +} + +#[test_case(&hex!("30 00"), Ok(&[]) ; "empty seq")] +#[test_case(&hex!("30 0a 02 03 01 00 01 02 03 01 00 00"), Ok(&[0x10001, 0x10000]) ; "seq ok")] +#[test_case(&hex!("30 07 02 03 01 00 01 02 03 01"), Err(Err::Error(BerError::NomError(ErrorKind::Eof))) ; "incomplete")] +#[test_case(&hex!("31 0a 02 03 01 00 01 02 03 01 00 00"), Err(Err::Error(BerError::unexpected_tag(Some(Tag::Sequence), Tag::Set))) ; "invalid tag")] +#[test_case(&hex!("30 80 02 03 01 00 01 00 00"), Ok(&[0x10001]) ; "indefinite seq ok")] +#[test_case(&hex!("30 80"), Err(Err::Incomplete(Needed::new(1))) ; "indefinite incomplete")] +fn tc_ber_seq_of(i: &[u8], out: Result<&[u32], Err<BerError>>) { + fn parser(i: &[u8]) -> BerResult { + parse_ber_sequence_of(parse_ber_integer)(i) + } + let res = parser(i); + match out { + Ok(l) => { + let (rem, res) = res.expect("could not parse sequence of"); + assert!(rem.is_empty()); + if let BerObjectContent::Sequence(res) = res.content { + pretty_assertions::assert_eq!(res.len(), l.len()); + for (a, b) in res.iter().zip(l.iter()) { + pretty_assertions::assert_eq!(a.as_u32().unwrap(), *b); + } + } else { + panic!("wrong type for parsed object"); + } + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(e)); + } + } +} + +#[test_case(&hex!("30 0a 02 03 01 00 01 02 03 01 00 00"), Ok(&[0x10001, 0x10000]) ; "seq ok")] +#[test_case(&hex!("30 07 02 03 01 00 01 02 01"), Err(Err::Incomplete(Needed::new(1))) ; "incomplete")] +#[test_case(&hex!("31 0a 02 03 01 00 01 02 03 01 00 00"), Err(Err::Error(BerError::unexpected_tag(Some(Tag::Sequence), Tag::Set))) ; "invalid tag")] +#[test_case(&hex!("30 80 02 03 01 00 01 02 03 01 00 00 00 00"), Ok(&[0x10001, 0x10000]) ; "indefinite seq")] +fn tc_ber_seq_defined(i: &[u8], out: Result<&[u32], Err<BerError>>) { + fn parser(i: &[u8]) -> BerResult<BerObject> { + parse_ber_sequence_defined(map( + tuple((parse_ber_integer, parse_ber_integer)), + |(a, b)| vec![a, b], + ))(i) + } + let res = parser(i); + match out { + Ok(l) => { + let (rem, res) = res.expect("could not parse sequence"); + assert!(rem.is_empty()); + if let BerObjectContent::Sequence(res) = res.content { + pretty_assertions::assert_eq!(res.len(), l.len()); + for (a, b) in res.iter().zip(l.iter()) { + pretty_assertions::assert_eq!(a.as_u32().unwrap(), *b); + } + } else { + panic!("wrong type for parsed object"); + } + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(e)); + } + } +} + +#[test_case(&hex!("31 00"), Ok(&[]) ; "empty set")] +#[test_case(&hex!("31 0a 02 03 01 00 01 02 03 01 00 00"), Ok(&[0x10001, 0x10000]) ; "set ok")] +#[test_case(&hex!("31 07 02 03 01 00 01 02 03 01"), Err(Err::Error(BerError::NomError(ErrorKind::Eof))) ; "incomplete")] +#[test_case(&hex!("30 0a 02 03 01 00 01 02 03 01 00 00"), Err(Err::Error(BerError::unexpected_tag(Some(Tag::Set), Tag::Sequence))) ; "invalid tag")] +#[test_case(&hex!("31 80 02 03 01 00 01 00 00"), Ok(&[0x10001]) ; "indefinite set ok")] +#[test_case(&hex!("31 80"), Err(Err::Incomplete(Needed::new(1))) ; "indefinite incomplete")] +fn tc_ber_set_of(i: &[u8], out: Result<&[u32], Err<BerError>>) { + fn parser(i: &[u8]) -> BerResult { + parse_ber_set_of(parse_ber_integer)(i) + } + let res = parser(i); + match out { + Ok(l) => { + let (rem, res) = res.expect("could not parse set of"); + assert!(rem.is_empty()); + if let BerObjectContent::Set(res) = res.content { + pretty_assertions::assert_eq!(res.len(), l.len()); + for (a, b) in res.iter().zip(l.iter()) { + pretty_assertions::assert_eq!(a.as_u32().unwrap(), *b); + } + } else { + panic!("wrong type for parsed object"); + } + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(e)); + } + } +} + +#[test_case(&hex!("31 0a 02 03 01 00 01 02 03 01 00 00"), Ok(&[0x10001, 0x10000]) ; "set ok")] +#[test_case(&hex!("31 07 02 03 01 00 01 02 01"), Err(Err::Incomplete(Needed::new(1))) ; "incomplete")] +#[test_case(&hex!("30 0a 02 03 01 00 01 02 03 01 00 00"), Err(Err::Error(BerError::unexpected_tag(Some(Tag::Set), Tag::Sequence))) ; "invalid tag")] +#[test_case(&hex!("31 80 02 03 01 00 01 02 03 01 00 00 00 00"), Ok(&[0x10001, 0x10000]) ; "indefinite set")] +fn tc_ber_set_defined(i: &[u8], out: Result<&[u32], Err<BerError>>) { + fn parser(i: &[u8]) -> BerResult<BerObject> { + parse_ber_set_defined(map( + tuple((parse_ber_integer, parse_ber_integer)), + |(a, b)| vec![a, b], + ))(i) + } + let res = parser(i); + match out { + Ok(l) => { + let (rem, res) = res.expect("could not parse set"); + assert!(rem.is_empty()); + if let BerObjectContent::Set(res) = res.content { + pretty_assertions::assert_eq!(res.len(), l.len()); + for (a, b) in res.iter().zip(l.iter()) { + pretty_assertions::assert_eq!(a.as_u32().unwrap(), *b); + } + } else { + panic!("wrong type for parsed object"); + } + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(e)); + } + } +} +#[test] +fn empty_seq() { + let data = &hex!("30 00"); + let (_, res) = parse_ber_sequence(data).expect("parsing empty sequence failed"); + assert!(res.as_sequence().unwrap().is_empty()); +} + +#[test] +fn struct01() { + let bytes = [ + 0x30, 0x0a, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x00, + ]; + let empty = &b""[..]; + let expected = MyStruct { + a: BerObject::from_int_slice(b"\x01\x00\x01"), + b: BerObject::from_int_slice(b"\x01\x00\x00"), + }; + let res = parse_struct01(&bytes); + assert_eq!(res, Ok((empty, expected))); +} + +#[test] +fn struct02() { + let empty = &b""[..]; + let bytes = [ + 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x46, 0x52, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, + 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x16, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, + 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, + ]; + #[derive(Debug, PartialEq)] + struct Attr<'a> { + oid: Oid<'a>, + val: BerObject<'a>, + } + #[derive(Debug, PartialEq)] + struct Rdn<'a> { + a: Attr<'a>, + } + #[derive(Debug, PartialEq)] + struct Name<'a> { + l: Vec<Rdn<'a>>, + } + let expected = Name { + l: vec![ + Rdn { + a: Attr { + oid: Oid::from(&[2, 5, 4, 6]).unwrap(), // countryName + val: BerObject::from_obj(BerObjectContent::PrintableString("FR")), + }, + }, + Rdn { + a: Attr { + oid: Oid::from(&[2, 5, 4, 8]).unwrap(), // stateOrProvinceName + val: BerObject::from_obj(BerObjectContent::UTF8String("Some-State")), + }, + }, + Rdn { + a: Attr { + oid: Oid::from(&[2, 5, 4, 10]).unwrap(), // organizationName + val: BerObject::from_obj(BerObjectContent::IA5String( + "Internet Widgits Pty Ltd", + )), + }, + }, + ], + }; + fn parse_directory_string(i: &[u8]) -> BerResult { + alt(( + parse_ber_utf8string, + parse_ber_printablestring, + parse_ber_ia5string, + ))(i) + } + fn parse_attr_type_and_value(i: &[u8]) -> BerResult<Attr> { + fn clone_oid(x: BerObject) -> Result<Oid, BerError> { + x.as_oid().map(|o| o.clone()) + } + parse_der_sequence_defined_g(|i: &[u8], _| { + let (i, o) = map_res(parse_ber_oid, clone_oid)(i)?; + let (i, s) = parse_directory_string(i)?; + Ok((i, Attr { oid: o, val: s })) + })(i) + } + fn parse_rdn(i: &[u8]) -> BerResult<Rdn> { + parse_der_set_defined_g(|i: &[u8], _| { + let (i, a) = parse_attr_type_and_value(i)?; + Ok((i, Rdn { a })) + })(i) + } + fn parse_name(i: &[u8]) -> BerResult<Name> { + parse_der_sequence_defined_g(|i: &[u8], _| { + let (i, l) = many0(complete(parse_rdn))(i)?; + Ok((i, Name { l })) + })(i) + } + let parsed = parse_name(&bytes).unwrap(); + assert_eq!(parsed, (empty, expected)); + // + assert_eq!(parsed.1.l[0].a.val.as_str(), Ok("FR")); + assert_eq!(parsed.1.l[1].a.val.as_str(), Ok("Some-State")); + assert_eq!(parsed.1.l[2].a.val.as_str(), Ok("Internet Widgits Pty Ltd")); +} + +#[test] +fn struct_with_garbage() { + let bytes = [ + 0x30, 0x0c, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x00, 0xff, 0xff, + ]; + let empty = &b""[..]; + let expected = MyStruct { + a: BerObject::from_int_slice(b"\x01\x00\x01"), + b: BerObject::from_int_slice(b"\x01\x00\x00"), + }; + assert_eq!(parse_struct01(&bytes), Ok((empty, expected))); + assert_eq!( + parse_struct01_complete(&bytes), + Err(Err::Error(error_position!(&bytes[12..], ErrorKind::Eof))) + ); +} + +#[test] +fn struct_verify_tag() { + let bytes = [ + 0x30, 0x0a, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x00, + ]; + let empty = &b""[..]; + let expected = MyStruct { + a: BerObject::from_int_slice(b"\x01\x00\x01"), + b: BerObject::from_int_slice(b"\x01\x00\x00"), + }; + let res = parse_struct04(&bytes, Tag::Sequence); + assert_eq!(res, Ok((empty, expected))); + let res = parse_struct04(&bytes, Tag::Set); + assert_eq!(res, Err(Err::Error(BerError::InvalidTag))); +} + +#[test_case(&hex!("a2 05 02 03 01 00 01"), Ok(0x10001) ; "tag ok")] +#[test_case(&hex!("a2 80 02 03 01 00 01 00 00"), Ok(0x10001) ; "indefinite tag ok")] +#[test_case(&hex!("a3 05 02 03 01 00 01"), Err(BerError::unexpected_tag(Some(Tag(2)), Tag(3))) ; "invalid tag")] +#[test_case(&hex!("22 05 02 03 01 00 01"), Err(BerError::unexpected_class(None, Class::Universal)) ; "invalid class")] +#[test_case(&hex!("82 05 02 03 01 00 01"), Err(BerError::ConstructExpected) ; "construct expected")] +fn tc_ber_tagged_explicit_g(i: &[u8], out: Result<u32, BerError>) { + fn parse_int_explicit(i: &[u8]) -> BerResult<u32> { + parse_ber_tagged_explicit_g(2, move |content, _hdr| { + let (rem, obj) = parse_ber_integer(content)?; + let value = obj.as_u32()?; + Ok((rem, value)) + })(i) + } + let res = parse_int_explicit(i); + match out { + Ok(expected) => { + pretty_assertions::assert_eq!(res, Ok((&b""[..], expected))); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(Err::Error(e))); + } + } +} + +#[test] +fn tagged_explicit() { + fn parse_int_explicit(i: &[u8]) -> BerResult<u32> { + map_res( + parse_der_tagged_explicit(2, parse_der_integer), + |x: BerObject| x.as_tagged()?.2.as_u32(), + )(i) + } + let bytes = &[0xa2, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01]; + // EXPLICIT tagged value parsing + let (rem, val) = parse_int_explicit(bytes).expect("Could not parse explicit int"); + assert!(rem.is_empty()); + assert_eq!(val, 0x10001); + // wrong tag + assert_eq!( + parse_der_tagged_explicit(3, parse_der_integer)(bytes as &[u8]), + Err(Err::Error(BerError::unexpected_tag(Some(Tag(3)), Tag(2)))) + ); + // wrong type + assert_eq!( + parse_der_tagged_explicit(2, parse_der_bool)(bytes as &[u8]), + Err(Err::Error(BerError::unexpected_tag(Some(Tag(1)), Tag(2)))) + ); +} + +#[test_case(&hex!("82 03 01 00 01"), Ok(0x10001) ; "tag ok")] +#[test_case(&hex!("83 03 01 00 01"), Err(BerError::unexpected_tag(Some(Tag(2)), Tag(3))) ; "invalid tag")] +fn tc_ber_tagged_implicit_g(i: &[u8], out: Result<u32, BerError>) { + fn parse_int_implicit(i: &[u8]) -> BerResult<u32> { + parse_ber_tagged_implicit_g(2, |content, hdr, depth| { + let (rem, obj) = parse_ber_content(Tag::Integer)(content, &hdr, depth)?; + let value = obj.as_u32()?; + Ok((rem, value)) + })(i) + } + let res = parse_int_implicit(i); + match out { + Ok(expected) => { + pretty_assertions::assert_eq!(res, Ok((&b""[..], expected))); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(Err::Error(e))); + } + } +} + +#[test] +fn tagged_implicit() { + fn parse_int_implicit(i: &[u8]) -> BerResult<u32> { + map_res( + parse_der_tagged_implicit(2, parse_der_content(Tag::Integer)), + |x: BerObject| x.as_u32(), + )(i) + } + let bytes = &[0x82, 0x03, 0x01, 0x00, 0x01]; + // IMPLICIT tagged value parsing + let (rem, val) = parse_int_implicit(bytes).expect("could not parse implicit int"); + assert!(rem.is_empty()); + assert_eq!(val, 0x10001); + // wrong tag + assert_eq!( + parse_der_tagged_implicit(3, parse_der_content(Tag::Integer))(bytes as &[u8]), + Err(Err::Error(BerError::unexpected_tag(Some(Tag(3)), Tag(2)))) + ); +} + +#[test] +fn application() { + #[derive(Debug, PartialEq)] + struct SimpleStruct { + a: u32, + } + fn parse_app01(i: &[u8]) -> BerResult<SimpleStruct> { + parse_der_container(|i, hdr| { + if hdr.class() != Class::Application { + return Err(Err::Error(BerError::unexpected_class(None, hdr.class()))); + } + if hdr.tag() != Tag(2) { + return Err(Err::Error(BerError::InvalidTag)); + } + let (i, a) = map_res(parse_ber_integer, |x: BerObject| x.as_u32())(i)?; + Ok((i, SimpleStruct { a })) + })(i) + } + let bytes = &[0x62, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01]; + let (rem, app) = parse_app01(bytes).expect("could not parse application"); + assert!(rem.is_empty()); + assert_eq!(app, SimpleStruct { a: 0x10001 }); +} + +#[test] +#[ignore = "not yet implemented"] +fn ber_constructed_string() { + // this encoding is equivalent to "04 05 01 AB 23 7F CA" + let data = &hex!( + " + 24 80 + 04 02 01 ab + 04 02 23 7f + 04 01 ca + 00 00" + ); + let _ = parse_ber_octetstring(data).expect("parsing failed"); +} diff --git a/rust/vendor/der-parser/tests/custom_error.rs b/rust/vendor/der-parser/tests/custom_error.rs new file mode 100644 index 0000000..2281510 --- /dev/null +++ b/rust/vendor/der-parser/tests/custom_error.rs @@ -0,0 +1,53 @@ +//! This test file ensures the functions to parse containers like sequences and sets +//! work correctly with custom errors. + +use der_parser::ber::{parse_ber_sequence_of_v, parse_ber_u32}; +use der_parser::error::BerError; +use nom::error::{ErrorKind, ParseError}; +use nom::{Err, IResult}; + +#[derive(Debug)] +pub enum MyError<'a> { + Variant1, + Variant2, + BerError(BerError), + NomError(&'a [u8], ErrorKind), +} + +impl<'a> ParseError<&'a [u8]> for MyError<'a> { + fn from_error_kind(input: &'a [u8], kind: ErrorKind) -> Self { + MyError::NomError(input, kind) + } + + fn append(_input: &'a [u8], _kind: ErrorKind, other: Self) -> Self { + other + } +} + +impl<'a> From<BerError> for MyError<'a> { + fn from(e: BerError) -> Self { + MyError::BerError(e) + } +} + +#[test] +fn parse_sequence_of_v_custom_errors() { + fn parse_element(i: &[u8]) -> IResult<&[u8], u32, MyError> { + // incomplete must *NOT* be mapped, or parse_ber_sequence_of_v cannot detect end of + // sequence + match parse_ber_u32(i) { + Ok(x) => Ok(x), + Err(Err::Incomplete(e)) => Err(Err::Incomplete(e)), + _ => Err(Err::Error(MyError::Variant1)), + } + } + + let bytes = [ + 0x30, 0x0a, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x00, + ]; + + let (rem, v) = + parse_ber_sequence_of_v(parse_element)(&bytes).expect("Could not parse SEQUENCE OF"); + assert!(rem.is_empty()); + assert_eq!(&v, &[65537, 65536]); +} diff --git a/rust/vendor/der-parser/tests/der_constructed.rs b/rust/vendor/der-parser/tests/der_constructed.rs new file mode 100644 index 0000000..d10adf0 --- /dev/null +++ b/rust/vendor/der-parser/tests/der_constructed.rs @@ -0,0 +1,177 @@ +// test_case seem to generate this warning - ignore it +#![allow(clippy::unused_unit)] + +use der_parser::ber::Tag; +use der_parser::der::*; +use der_parser::error::*; +use hex_literal::hex; +use nom::combinator::map; +use nom::error::ErrorKind; +use nom::sequence::tuple; +use nom::{Err, Needed}; +use test_case::test_case; + +#[test_case(&hex!("a2 05 02 03 01 00 01"), Ok(0x10001) ; "tag ok")] +#[test_case(&hex!("a2 80 02 03 01 00 01 00 00"), Err(BerError::DerConstraintFailed(DerConstraint::IndefiniteLength)) ; "indefinite tag ok")] +#[test_case(&hex!("a3 05 02 03 01 00 01"), Err(BerError::unexpected_tag(Some(Tag(2)), Tag(3))) ; "invalid tag")] +#[test_case(&hex!("22 05 02 03 01 00 01"), Err(BerError::unexpected_class(None, Class::Universal)) ; "invalid class")] +#[test_case(&hex!("82 05 02 03 01 00 01"), Err(BerError::ConstructExpected) ; "construct expected")] +fn tc_der_tagged_explicit_g(i: &[u8], out: Result<u32, BerError>) { + fn parse_int_explicit(i: &[u8]) -> BerResult<u32> { + parse_der_tagged_explicit_g(2, move |content, _hdr| { + let (rem, obj) = parse_der_integer(content)?; + let value = obj.as_u32()?; + Ok((rem, value)) + })(i) + } + let res = parse_int_explicit(i); + match out { + Ok(expected) => { + pretty_assertions::assert_eq!(res, Ok((&b""[..], expected))); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(Err::Error(e))); + } + } +} + +#[test_case(&hex!("82 03 01 00 01"), Ok(0x10001) ; "tag ok")] +#[test_case(&hex!("83 03 01 00 01"), Err(BerError::unexpected_tag(Some(Tag(2)), Tag(3))) ; "invalid tag")] +fn tc_der_tagged_implicit_g(i: &[u8], out: Result<u32, BerError>) { + fn parse_int_implicit(i: &[u8]) -> BerResult<u32> { + parse_der_tagged_implicit_g(2, |content, hdr, depth| { + let (rem, obj) = parse_der_content(Tag::Integer)(content, &hdr, depth)?; + let value = obj.as_u32()?; + Ok((rem, value)) + })(i) + } + let res = parse_int_implicit(i); + match out { + Ok(expected) => { + pretty_assertions::assert_eq!(res, Ok((&b""[..], expected))); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(Err::Error(e))); + } + } +} + +#[test_case(&hex!("30 00"), Ok(&[]) ; "empty seq")] +#[test_case(&hex!("30 0a 02 03 01 00 01 02 03 01 00 00"), Ok(&[0x10001, 0x10000]) ; "seq ok")] +#[test_case(&hex!("30 07 02 03 01 00 01 02 03 01"), Err(BerError::NomError(ErrorKind::Eof)) ; "incomplete")] +#[test_case(&hex!("31 0a 02 03 01 00 01 02 03 01 00 00"), Err(BerError::unexpected_tag(Some(Tag::Sequence), Tag::Set)) ; "invalid tag")] +#[test_case(&hex!("30 80 02 03 01 00 01 00 00"), Err(BerError::DerConstraintFailed(DerConstraint::IndefiniteLength)) ; "indefinite seq ok")] +fn tc_der_seq_of(i: &[u8], out: Result<&[u32], BerError>) { + fn parser(i: &[u8]) -> BerResult { + parse_der_sequence_of(parse_der_integer)(i) + } + let res = parser(i); + match out { + Ok(l) => { + let (rem, res) = res.expect("could not parse sequence of"); + assert!(rem.is_empty()); + if let DerObjectContent::Sequence(res) = res.content { + pretty_assertions::assert_eq!(res.len(), l.len()); + for (a, b) in res.iter().zip(l.iter()) { + pretty_assertions::assert_eq!(a.as_u32().unwrap(), *b); + } + } else { + panic!("wrong type for parsed object"); + } + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(Err::Error(e))); + } + } +} + +#[test_case(&hex!("30 0a 02 03 01 00 01 02 03 01 00 00"), Ok(&[0x10001, 0x10000]) ; "seq ok")] +#[test_case(&hex!("30 07 02 03 01 00 01 02 01"), Err(Err::Incomplete(Needed::new(1))) ; "incomplete")] +#[test_case(&hex!("31 0a 02 03 01 00 01 02 03 01 00 00"), Err(Err::Error(BerError::unexpected_tag(Some(Tag::Sequence), Tag::Set))) ; "invalid tag")] +#[test_case(&hex!("30 80 02 03 01 00 01 00 00"), Err(Err::Error(BerError::DerConstraintFailed(DerConstraint::IndefiniteLength))) ; "indefinite seq ok")] +fn tc_der_seq_defined(i: &[u8], out: Result<&[u32], Err<BerError>>) { + fn parser(i: &[u8]) -> BerResult<DerObject> { + parse_der_sequence_defined(map( + tuple((parse_der_integer, parse_der_integer)), + |(a, b)| vec![a, b], + ))(i) + } + let res = parser(i); + match out { + Ok(l) => { + let (rem, res) = res.expect("could not parse sequence"); + assert!(rem.is_empty()); + if let DerObjectContent::Sequence(res) = res.content { + pretty_assertions::assert_eq!(res.len(), l.len()); + for (a, b) in res.iter().zip(l.iter()) { + pretty_assertions::assert_eq!(a.as_u32().unwrap(), *b); + } + } else { + panic!("wrong type for parsed object"); + } + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(e)); + } + } +} + +#[test_case(&hex!("31 00"), Ok(&[]) ; "empty set")] +#[test_case(&hex!("31 0a 02 03 01 00 01 02 03 01 00 00"), Ok(&[0x10001, 0x10000]) ; "set ok")] +#[test_case(&hex!("31 07 02 03 01 00 01 02 03 01"), Err(BerError::NomError(ErrorKind::Eof)) ; "incomplete")] +#[test_case(&hex!("30 0a 02 03 01 00 01 02 03 01 00 00"), Err(BerError::unexpected_tag(Some(Tag::Set), Tag::Sequence)) ; "invalid tag")] +#[test_case(&hex!("31 80 02 03 01 00 01 00 00"), Err(BerError::DerConstraintFailed(DerConstraint::IndefiniteLength)) ; "indefinite set ok")] +fn tc_der_set_of(i: &[u8], out: Result<&[u32], BerError>) { + fn parser(i: &[u8]) -> BerResult { + parse_der_set_of(parse_der_integer)(i) + } + let res = parser(i); + match out { + Ok(l) => { + let (rem, res) = res.expect("could not parse set of"); + assert!(rem.is_empty()); + if let DerObjectContent::Set(res) = res.content { + pretty_assertions::assert_eq!(res.len(), l.len()); + for (a, b) in res.iter().zip(l.iter()) { + pretty_assertions::assert_eq!(a.as_u32().unwrap(), *b); + } + } else { + panic!("wrong type for parsed object"); + } + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(Err::Error(e))); + } + } +} + +#[test_case(&hex!("31 0a 02 03 01 00 01 02 03 01 00 00"), Ok(&[0x10001, 0x10000]) ; "set ok")] +#[test_case(&hex!("31 07 02 03 01 00 01 02 01"), Err(Err::Incomplete(Needed::new(1))) ; "incomplete")] +#[test_case(&hex!("30 0a 02 03 01 00 01 02 03 01 00 00"), Err(Err::Error(BerError::unexpected_tag(Some(Tag::Set), Tag::Sequence))) ; "invalid tag")] +#[test_case(&hex!("31 80 02 03 01 00 01 00 00"), Err(Err::Error(BerError::DerConstraintFailed(DerConstraint::IndefiniteLength))) ; "indefinite set ok")] +fn tc_der_set_defined(i: &[u8], out: Result<&[u32], Err<BerError>>) { + fn parser(i: &[u8]) -> BerResult<DerObject> { + parse_der_set_defined(map( + tuple((parse_der_integer, parse_der_integer)), + |(a, b)| vec![a, b], + ))(i) + } + let res = parser(i); + match out { + Ok(l) => { + let (rem, res) = res.expect("could not parse set"); + assert!(rem.is_empty()); + if let DerObjectContent::Set(res) = res.content { + pretty_assertions::assert_eq!(res.len(), l.len()); + for (a, b) in res.iter().zip(l.iter()) { + pretty_assertions::assert_eq!(a.as_u32().unwrap(), *b); + } + } else { + panic!("wrong type for parsed object"); + } + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(e)); + } + } +} diff --git a/rust/vendor/der-parser/tests/der_parser.rs b/rust/vendor/der-parser/tests/der_parser.rs new file mode 100644 index 0000000..ef31c66 --- /dev/null +++ b/rust/vendor/der-parser/tests/der_parser.rs @@ -0,0 +1,628 @@ +// test_case seem to generate this warning - ignore it +#![allow(clippy::unused_unit)] + +use asn1_rs::ASN1DateTime; +use asn1_rs::ASN1TimeZone; +use asn1_rs::Any; +use der_parser::ber::*; +use der_parser::der::*; +use der_parser::error::*; +use der_parser::oid::*; +use der_parser::*; +use hex_literal::hex; +use nom::branch::alt; +use nom::combinator::map; +use nom::error::ErrorKind; +use nom::sequence::tuple; +use nom::Err; +use pretty_assertions::assert_eq; +use std::borrow::Cow; +use test_case::test_case; + +#[test] +fn test_der_bool() { + let empty = &b""[..]; + let b_true = DerObject::from_obj(BerObjectContent::Boolean(true)); + let b_false = DerObject::from_obj(BerObjectContent::Boolean(false)); + assert_eq!(parse_der_bool(&[0x01, 0x01, 0x00]), Ok((empty, b_false))); + assert_eq!(parse_der_bool(&[0x01, 0x01, 0xff]), Ok((empty, b_true))); + assert_eq!( + parse_der_bool(&[0x01, 0x01, 0x7f]), + Err(Err::Error(BerError::DerConstraintFailed( + DerConstraint::InvalidBoolean + ))) + ); +} + +#[test] +fn test_der_int() { + let empty = &b""[..]; + let bytes = hex!("02 03 01 00 01"); + let expected = DerObject::from_obj(BerObjectContent::Integer(b"\x01\x00\x01")); + assert_eq!(parse_der_integer(&bytes), Ok((empty, expected))); + let res = parse_der_u64(&bytes); + assert_eq!(res.expect("integer").1, 0x10001); + // wrong tag + let bytes = hex!("04 03 41 41 41"); + let res = parse_der_integer(&bytes); + assert!(res.is_err()); + let res = parse_der_u64(&bytes); + assert!(res.is_err()); + // very long integer + let bytes = hex!("02 0b 40 41 02 03 04 05 06 07 08 09 0a"); + let res = parse_der_integer(&bytes); + assert!(res.is_ok()); + let res = parse_der_u64(&bytes); + assert!(res.is_err()); +} + +#[test] +fn test_der_bitstring_primitive() { + let empty = &b""[..]; + // + // correct DER encoding + // + let bytes = &[0x03, 0x04, 0x06, 0x6e, 0x5d, 0xc0]; + let expected = DerObject::from_obj(BerObjectContent::BitString( + 6, + BitStringObject { data: &bytes[3..] }, + )); + assert_eq!(parse_der_bitstring(bytes), Ok((empty, expected))); + // + // correct encoding, but wrong padding bits (not all set to 0) + // + let bytes = &[0x03, 0x04, 0x06, 0x6e, 0x5d, 0xe0]; + assert_eq!( + parse_der_bitstring(bytes), + Err(Err::Error(BerError::DerConstraintFailed( + DerConstraint::UnusedBitsNotZero + ))) + ); + // // XXX test disabled: the parser is laxist here, since *many* implementations do + // // XXX not respect this constraint! + // // long form of length (invalid, < 127) + // // + // let bytes = &[0x03, 0x81, 0x04, 0x06, 0x6e, 0x5d, 0xc0]; + // assert_eq!( + // parse_der_bitstring(bytes), + // Err(Err::Error(BerError::DerConstraintFailed)) + // ); +} + +#[test] +fn test_der_bitstring_constructed() { + let bytes = &hex!("23 81 0c 03 03 00 0a 3b 03 05 04 5f 29 1c d0"); + assert_eq!( + parse_der_bitstring(bytes), + Err(Err::Error(BerError::DerConstraintFailed( + DerConstraint::Constructed + ))) + ); +} + +#[test] +fn test_der_indefinite_length() { + let bytes = &hex!("23 80 03 03 00 0a 3b 03 05 04 5f 29 1c d0 00 00"); + assert_eq!( + parse_der_bitstring(bytes), + Err(Err::Error(BerError::DerConstraintFailed( + DerConstraint::IndefiniteLength + ))) + ); +} + +#[test] +fn test_der_octetstring_primitive() { + let empty = &b""[..]; + let bytes = [0x04, 0x05, 0x41, 0x41, 0x41, 0x41, 0x41]; + let expected = DerObject::from_obj(BerObjectContent::OctetString(b"AAAAA")); + assert_eq!(parse_der_octetstring(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_der_null() { + let empty = &b""[..]; + let expected = DerObject::from_obj(BerObjectContent::Null); + assert_eq!(parse_der_null(&[0x05, 0x00]), Ok((empty, expected))); +} + +#[test] +fn test_der_oid() { + let empty = &b""[..]; + let bytes = [ + 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, + ]; + let expected = DerObject::from_obj(BerObjectContent::OID( + Oid::from(&[1, 2, 840, 113_549, 1, 1, 5]).unwrap(), + )); + assert_eq!(parse_der_oid(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_der_enum() { + let empty = &b""[..]; + let expected = DerObject::from_obj(BerObjectContent::Enum(2)); + assert_eq!(parse_der_enum(&[0x0a, 0x01, 0x02]), Ok((empty, expected))); +} + +#[test] +fn test_der_utf8string() { + let empty = &b""[..]; + let bytes = [ + 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, + ]; + let expected = DerObject::from_obj(BerObjectContent::UTF8String("Some-State")); + assert_eq!(parse_der_utf8string(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_der_relativeoid() { + let empty = &b""[..]; + let bytes = [0x0d, 0x04, 0xc2, 0x7b, 0x03, 0x02]; + let expected = DerObject::from_obj(BerObjectContent::RelativeOID( + Oid::from_relative(&[8571, 3, 2]).unwrap(), + )); + assert_eq!(parse_der_relative_oid(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_der_seq() { + let empty = &b""[..]; + let bytes = [0x30, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01]; + let expected = DerObject::from_seq(vec![DerObject::from_int_slice(b"\x01\x00\x01")]); + assert_eq!(parse_der_sequence(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_der_set() { + let empty = &b""[..]; + let bytes = [0x31, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01]; + let expected = DerObject::from_set(vec![DerObject::from_int_slice(b"\x01\x00\x01")]); + assert_eq!(parse_der_set(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_der_seq_defined() { + let empty = &b""[..]; + let bytes = [ + 0x30, 0x0a, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x00, + ]; + let expected = DerObject::from_seq(vec![ + DerObject::from_int_slice(b"\x01\x00\x01"), + DerObject::from_int_slice(b"\x01\x00\x00"), + ]); + fn parser(i: &[u8]) -> DerResult { + parse_der_sequence_defined( + // the nom `tuple` combinator returns a tuple, so we have to map it + // to a list + map(tuple((parse_der_integer, parse_der_integer)), |(a, b)| { + vec![a, b] + }), + )(i) + } + assert_eq!(parser(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_der_set_defined() { + let empty = &b""[..]; + let bytes = [ + 0x31, 0x0a, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x00, + ]; + let expected = DerObject::from_set(vec![ + DerObject::from_int_slice(b"\x01\x00\x01"), + DerObject::from_int_slice(b"\x01\x00\x00"), + ]); + fn parser(i: &[u8]) -> DerResult { + parse_der_set_defined( + // the nom `tuple` combinator returns a tuple, so we have to map it + // to a list + map(tuple((parse_der_integer, parse_der_integer)), |(a, b)| { + vec![a, b] + }), + )(i) + } + assert_eq!(parser(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_der_seq_of() { + let empty = &b""[..]; + let bytes = [ + 0x30, 0x0a, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x00, + ]; + let expected = DerObject::from_seq(vec![ + DerObject::from_int_slice(b"\x01\x00\x01"), + DerObject::from_int_slice(b"\x01\x00\x00"), + ]); + fn parser(i: &[u8]) -> DerResult { + parse_der_sequence_of(parse_der_integer)(i) + } + assert_eq!(parser(&bytes), Ok((empty, expected.clone()))); + // + fn parser2(i: &[u8]) -> BerResult { + parse_ber_sequence_of(parse_der_integer)(i) + } + assert_eq!(parser2(&bytes), Ok((empty, expected))); +} + +// extra bytes are simply ignored +#[test] +fn test_der_seq_of_incomplete() { + let bytes = [0x30, 0x07, 0x02, 0x03, 0x01, 0x00, 0x01, 0x00, 0x00]; + fn parser(i: &[u8]) -> DerResult { + parse_der_sequence_of(parse_der_integer)(i) + } + assert_eq!( + parser(&bytes), + Err(Err::Failure(BerError::unexpected_tag(Some(Tag(2)), Tag(0)))) + ); + // + fn parser2(i: &[u8]) -> BerResult<Vec<BerObject>> { + parse_ber_sequence_of_v(parse_der_integer)(i) + } + // eprintln!("trailing data"); + assert_eq!( + parser2(&bytes), + Err(Err::Failure(BerError::unexpected_tag(Some(Tag(2)), Tag(0)))) + ); + let h = &hex!("30 06 02 03 01 00 01 02"); + // eprintln!("remaining 02 at end (incomplete)"); + assert_eq!( + parser2(h), + Err(Err::Error(BerError::NomError(ErrorKind::Eof))) + ); +} + +#[test] +fn test_der_set_of() { + let empty = &b""[..]; + let bytes = [ + 0x31, 0x0a, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x00, + ]; + let expected = DerObject::from_set(vec![ + DerObject::from_int_slice(b"\x01\x00\x01"), + DerObject::from_int_slice(b"\x01\x00\x00"), + ]); + fn parser(i: &[u8]) -> DerResult { + parse_der_set_of(parse_der_integer)(i) + } + assert_eq!(parser(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_der_utctime() { + let bytes = hex!("17 0b 39 32 30 35 32 31 32 33 34 32 5A FF"); + let expected = DerObject::from_obj(BerObjectContent::UTCTime(ASN1DateTime::new( + 92, + 5, + 21, + 23, + 42, + 0, + None, + ASN1TimeZone::Z, + ))); + assert_eq!(parse_der_utctime(&bytes), Ok((&[0xff][..], expected))); + // missing 'Z' + let bytes = hex!("17 0a 39 32 30 35 32 31 32 33 34 32"); + let e = parse_der_utctime(&bytes).expect_err("expected error"); + assert_eq!( + e, + Err::Error(BerError::DerConstraintFailed( + DerConstraint::MissingTimeZone + )) + ); +} + +#[test] +fn test_der_generalizedtime() { + let empty = &b""[..]; + let bytes = hex!("18 0D 31 39 39 32 30 35 32 31 32 33 34 32 5A"); + let expected = DerObject::from_obj(BerObjectContent::GeneralizedTime(ASN1DateTime::new( + 1992, + 5, + 21, + 23, + 42, + 0, + None, + ASN1TimeZone::Z, + ))); + assert_eq!(parse_der_generalizedtime(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_der_generalstring() { + let empty = &b""[..]; + let bytes = [0x1b, 0x04, 0x63, 0x69, 0x66, 0x73]; + let expected = DerObject::from_obj(BerObjectContent::GeneralString("cifs")); + assert_eq!(parse_der_generalstring(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_der_contextspecific() { + let bytes = [0xa0, 0x03, 0x02, 0x01, 0x02]; + let empty = &b""[..]; + let header = Header::new(Class::ContextSpecific, true, Tag(0), 3.into()) + .with_raw_tag(Some(Cow::Borrowed(&[0xa0]))); + let any = Any::new(header.clone(), &bytes[2..]); + let expected = DerObject { + header, + content: BerObjectContent::Unknown(any), + }; + assert_eq!(parse_der(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_der_explicit_optional() { + let empty = &b""[..]; + let bytes = [0xa0, 0x03, 0x02, 0x01, 0x02]; + let header = Header::new(Class::ContextSpecific, true, Tag(0), 3.into()) + .with_raw_tag(Some(Cow::Borrowed(&[0xa0]))); + let expected = DerObject { + header: header.clone(), + content: BerObjectContent::Optional(Some(Box::new(BerObject::from_header_and_content( + header, + BerObjectContent::Tagged( + Class::ContextSpecific, + Tag(0), + Box::new(DerObject::from_int_slice(b"\x02")), + ), + )))), + }; + assert_eq!( + parse_der_explicit_optional(&bytes, Tag(0), parse_der_integer), + Ok((empty, expected)) + ); + let expected2 = DerObject::from_obj(BerObjectContent::Optional(None)); + assert_eq!( + parse_der_explicit_optional(&bytes, Tag(1), parse_der_integer), + Ok((&bytes[..], expected2)) + ); +} + +#[test] +fn test_der_implicit() { + let empty = &b""[..]; + let bytes = [0x81, 0x04, 0x70, 0x61, 0x73, 0x73]; + let expected = DerObject { + header: Header::new(Class::ContextSpecific, false, Tag(1), 4.into()) + .with_raw_tag(Some(Cow::Borrowed(&[0x81]))), + content: BerObjectContent::IA5String("pass"), + }; + fn der_read_ia5string_content<'a>( + i: &'a [u8], + hdr: &Header, + depth: usize, + ) -> BerResult<'a, BerObjectContent<'a>> { + ber_read_element_content_as(i, Tag::Ia5String, hdr.length(), hdr.is_constructed(), depth) + } + assert_eq!( + parse_der_implicit(&bytes, Tag(1), der_read_ia5string_content), + Ok((empty, expected)) + ); + assert_eq!( + parse_der_implicit(&bytes, Tag(2), der_read_ia5string_content), + Err(Err::Error(BerError::unexpected_tag(Some(Tag(2)), Tag(1)))) + ); +} + +#[test] +fn test_der_implicit_long_tag() { + let empty = &b""[..]; + let bytes = [0x5f, 0x52, 0x04, 0x70, 0x61, 0x73, 0x73]; + let expected = DerObject { + header: Header::new(Class::Application, false, Tag(0x52), 4.into()) + .with_raw_tag(Some(Cow::Borrowed(&[0x5f, 0x52]))), + content: BerObjectContent::IA5String("pass"), + }; + fn der_read_ia5string_content<'a>( + i: &'a [u8], + hdr: &Header, + depth: usize, + ) -> BerResult<'a, BerObjectContent<'a>> { + ber_read_element_content_as(i, Tag::Ia5String, hdr.length(), hdr.is_constructed(), depth) + } + assert_eq!( + parse_der_implicit(&bytes, Tag(0x52), der_read_ia5string_content), + Ok((empty, expected)) + ); + assert_eq!( + parse_der_implicit(&bytes, Tag(2), der_read_ia5string_content), + Err(Err::Error(BerError::unexpected_tag( + Some(Tag(2)), + Tag(0x52) + ))) + ); +} + +#[test] +fn test_der_optional() { + let empty = &b""[..]; + let bytes1 = [ + 0x30, 0x0a, 0x0a, 0x03, 0x00, 0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, + ]; + let bytes2 = [0x30, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01]; + let expected1 = DerObject::from_seq(vec![ + DerObject::from_obj(BerObjectContent::Optional(Some(Box::new( + DerObject::from_obj(BerObjectContent::Enum(1)), + )))), + DerObject::from_int_slice(b"\x01\x00\x01"), + ]); + let expected2 = DerObject::from_seq(vec![ + DerObject::from_obj(BerObjectContent::Optional(None)), + DerObject::from_int_slice(b"\x01\x00\x01"), + ]); + fn parse_optional_enum(i: &[u8]) -> DerResult { + parse_ber_optional(parse_der_enum)(i) + } + fn parser(i: &[u8]) -> DerResult { + parse_der_sequence_defined( + // the nom `tuple` combinator returns a tuple, so we have to map it + // to a list + map(tuple((parse_optional_enum, parse_der_integer)), |(a, b)| { + vec![a, b] + }), + )(i) + } + assert_eq!(parser(&bytes1), Ok((empty, expected1))); + assert_eq!(parser(&bytes2), Ok((empty, expected2))); +} + +#[test] +fn test_der_seq_dn() { + let empty = &b""[..]; + let bytes = [ + 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x46, 0x52, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, + 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, + 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, + ]; + let expected = DerObject::from_seq(vec![ + DerObject::from_set(vec![DerObject::from_seq(vec![ + DerObject::from_obj(BerObjectContent::OID(Oid::from(&[2, 5, 4, 6]).unwrap())), // countryName + DerObject::from_obj(BerObjectContent::PrintableString("FR")), + ])]), + DerObject::from_set(vec![DerObject::from_seq(vec![ + DerObject::from_obj(BerObjectContent::OID(Oid::from(&[2, 5, 4, 8]).unwrap())), // stateOrProvinceName + DerObject::from_obj(BerObjectContent::UTF8String("Some-State")), + ])]), + DerObject::from_set(vec![DerObject::from_seq(vec![ + DerObject::from_obj(BerObjectContent::OID(Oid::from(&[2, 5, 4, 10]).unwrap())), // organizationName + DerObject::from_obj(BerObjectContent::UTF8String("Internet Widgits Pty Ltd")), + ])]), + ]); + assert_eq!(parse_der(&bytes), Ok((empty, expected))); +} + +#[test] +fn test_der_seq_dn_defined() { + let empty = &b""[..]; + let bytes = [ + 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x46, 0x52, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, + 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, + 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, + ]; + let expected = DerObject::from_seq(vec![ + DerObject::from_set(vec![DerObject::from_seq(vec![ + DerObject::from_obj(BerObjectContent::OID(Oid::from(&[2, 5, 4, 6]).unwrap())), // countryName + DerObject::from_obj(BerObjectContent::PrintableString("FR")), + ])]), + DerObject::from_set(vec![DerObject::from_seq(vec![ + DerObject::from_obj(BerObjectContent::OID(Oid::from(&[2, 5, 4, 8]).unwrap())), // stateOrProvinceName + DerObject::from_obj(BerObjectContent::UTF8String("Some-State")), + ])]), + DerObject::from_set(vec![DerObject::from_seq(vec![ + DerObject::from_obj(BerObjectContent::OID(Oid::from(&[2, 5, 4, 10]).unwrap())), // organizationName + DerObject::from_obj(BerObjectContent::UTF8String("Internet Widgits Pty Ltd")), + ])]), + ]); + #[inline] + fn parse_directory_string(i: &[u8]) -> DerResult { + alt(( + parse_der_utf8string, + parse_der_printablestring, + parse_der_ia5string, + ))(i) + } + #[inline] + fn parse_attr_type_and_value(i: &[u8]) -> DerResult { + parse_der_sequence_defined( + // the nom `tuple` combinator returns a tuple, so we have to map it + // to a list + map(tuple((parse_der_oid, parse_directory_string)), |(a, b)| { + vec![a, b] + }), + )(i) + } + #[inline] + fn parse_rdn(i: &[u8]) -> DerResult { + parse_der_set_of(parse_attr_type_and_value)(i) + } + #[inline] + fn parse_name(i: &[u8]) -> DerResult { + parse_der_sequence_of(parse_rdn)(i) + } + assert_eq!(parse_name(&bytes), Ok((empty, expected))); +} + +#[test_case(&hex!("02 01 01"), Ok(1) ; "u32-1")] +#[test_case(&hex!("02 01 ff"), Err(BerError::IntegerNegative) ; "negative integer")] +#[test_case(&hex!("02 02 00 ff"), Ok(255) ; "u32-255")] +#[test_case(&hex!("02 02 01 23"), Ok(0x123) ; "u32-0x123")] +#[test_case(&hex!("02 04 01 23 45 67"), Ok(0x0123_4567) ; "u32-long-ok")] +// XXX DER encoding is invalid (not minimal) in following test: +// #[test_case(&hex!("02 04 ff ff ff ff"), Err(BerError::IntegerNegative) ; "u32-long2-neg")] +#[test_case(&hex!("02 06 00 00 01 23 45 67"), Err(BerError::DerConstraintFailed(DerConstraint::IntegerLeadingZeroes)) ; "u32-long-leading-zeros")] +#[test_case(&hex!("02 05 01 23 45 67 01"), Err(BerError::IntegerTooLarge) ; "u32 too large")] +#[test_case(&hex!("02 09 01 23 45 67 01 23 45 67 ab"), Err(BerError::IntegerTooLarge) ; "u32 too large 2")] +#[test_case(&hex!("03 03 01 00 01"), Err(BerError::unexpected_tag(Some(Tag(2)), Tag(3))) ; "invalid tag")] +fn tc_der_u32(i: &[u8], out: Result<u32, BerError>) { + let res = parse_der_u32(i); + match out { + Ok(expected) => { + pretty_assertions::assert_eq!(res, Ok((&b""[..], expected))); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(Err::Error(e))); + } + } +} + +#[test_case(&hex!("02 01 01"), Ok(1) ; "i32-1")] +#[test_case(&hex!("02 01 ff"), Ok(-1) ; "i32-neg1")] +#[test_case(&hex!("02 01 80"), Ok(-128) ; "i32-neg128")] +#[test_case(&hex!("02 02 ff 7f"), Ok(-129) ; "i32-neg129")] +#[test_case(&hex!("02 02 00 ff"), Ok(255) ; "i32-255")] +#[test_case(&hex!("02 02 ff f0"), Err(BerError::DerConstraintFailed(DerConstraint::IntegerLeadingFF)) ; "i32-neg-leading-ff")] +fn tc_der_i32(i: &[u8], out: Result<i32, BerError>) { + let res = parse_der_i32(i); + match out { + Ok(expected) => { + pretty_assertions::assert_eq!(res, Ok((&b""[..], expected))); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(Err::Error(e))); + } + } +} + +#[test_case(&hex!("02 01 01"), Ok(1) ; "u64-1")] +#[test_case(&hex!("02 02 00 ff"), Ok(255) ; "u64-255")] +#[test_case(&hex!("02 02 01 23"), Ok(0x123) ; "u64-0x123")] +#[test_case(&hex!("02 08 01 23 45 67 01 23 45 67"), Ok(0x0123_4567_0123_4567) ; "u64-long-ok")] +#[test_case(&hex!("02 09 00 ff ff ff ff ff ff ff ff"), Ok(0xffff_ffff_ffff_ffff) ; "u64-long2-ok")] +#[test_case(&hex!("02 09 01 23 45 67 01 23 45 67 ab"), Err(BerError::IntegerTooLarge) ; "u64 too large")] +#[test_case(&hex!("03 03 01 00 01"), Err(BerError::unexpected_tag(Some(Tag(2)), Tag(3))) ; "invalid tag")] +fn tc_der_u64(i: &[u8], out: Result<u64, BerError>) { + let res = parse_der_u64(i); + match out { + Ok(expected) => { + pretty_assertions::assert_eq!(res, Ok((&b""[..], expected))); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(Err::Error(e))); + } + } +} + +#[test_case(&hex!("02 01 01"), Ok(&[1]) ; "slice 1")] +#[test_case(&hex!("02 01 ff"), Ok(&[255]) ; "slice 2")] +#[test_case(&hex!("02 09 01 23 45 67 01 23 45 67 ab"), Ok(&hex!("01 23 45 67 01 23 45 67 ab")) ; "slice 3")] +#[test_case(&hex!("22 80 02 01 01 00 00"), Err(BerError::DerConstraintFailed(DerConstraint::IndefiniteLength)) ; "constructed slice")] +#[test_case(&hex!("03 03 01 00 01"), Err(BerError::unexpected_tag(Some(Tag(2)), Tag(3))) ; "invalid tag")] +fn tc_der_slice(i: &[u8], out: Result<&[u8], BerError>) { + let res = parse_der_slice(i, 2); + match out { + Ok(expected) => { + pretty_assertions::assert_eq!(res, Ok((&b""[..], expected))); + } + Err(e) => { + pretty_assertions::assert_eq!(res, Err(Err::Error(e))); + } + } +} diff --git a/rust/vendor/der-parser/tests/fuzz01.rs b/rust/vendor/der-parser/tests/fuzz01.rs new file mode 100644 index 0000000..c971b56 --- /dev/null +++ b/rust/vendor/der-parser/tests/fuzz01.rs @@ -0,0 +1,5 @@ +#[test] +fn test01() { + let data = b"\x03\x00\x00kk\x00\x00\x00\x00\x00\x00\x00.\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff;\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00\x00\x00\xff\x0a\xff"; + let _ = der_parser::parse_der(data); +} diff --git a/rust/vendor/der-parser/tests/fuzz02.rs b/rust/vendor/der-parser/tests/fuzz02.rs new file mode 100644 index 0000000..bea7c21 --- /dev/null +++ b/rust/vendor/der-parser/tests/fuzz02.rs @@ -0,0 +1,22 @@ +#[test] +fn test02() { + let data = b"\x06\x00\x01\x00\x00\x2a"; + let _ = der_parser::parse_der(data); +} + +#[test] +fn test03() { + let data = b"\x06\x0a*\xf1\x0a*\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe\xbe"; + let _ = der_parser::parse_der(data); +} + +#[test] +fn test04() { + let data = &[ + 0x50, 0x2a, 0xa, 0x8d, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xa, 0x0, 0xb, 0x22, 0x56, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf1, 0xa, 0x2a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + ]; + let _ = der_parser::parse_der(data); +} diff --git a/rust/vendor/der-parser/tests/oid.rs b/rust/vendor/der-parser/tests/oid.rs new file mode 100644 index 0000000..3fa45c7 --- /dev/null +++ b/rust/vendor/der-parser/tests/oid.rs @@ -0,0 +1,25 @@ +//! Test the API provided to compare OIDs + +extern crate alloc; +use der_parser::oid; +use der_parser::oid::Oid; + +const OID_RSA_ENCRYPTION: &[u8] = &oid!(raw 1.2.840.113549.1.1.1); +const OID_EC_PUBLIC_KEY: &[u8] = &oid!(raw 1.2.840.10045.2.1); +#[allow(clippy::match_like_matches_macro)] +fn compare_oid(oid: &Oid) -> bool { + match oid.as_bytes() { + OID_RSA_ENCRYPTION => true, + OID_EC_PUBLIC_KEY => true, + _ => false, + } +} + +#[rustfmt::skip::macros(oid)] +#[test] +fn test_compare_oid() { + let oid = Oid::from(&[1, 2, 840, 113_549, 1, 1, 1]).unwrap(); + assert_eq!(oid, oid!(1.2.840.113549.1.1.1)); + let oid = Oid::from(&[1, 2, 840, 113_549, 1, 1, 1]).unwrap(); + assert!(compare_oid(&oid)); +} diff --git a/rust/vendor/der-parser/tests/primitive.rs b/rust/vendor/der-parser/tests/primitive.rs new file mode 100644 index 0000000..2f3aecb --- /dev/null +++ b/rust/vendor/der-parser/tests/primitive.rs @@ -0,0 +1,236 @@ +extern crate alloc; +use std::borrow::Cow; + +use asn1_rs::Any; +use der_parser::ber::*; +use der_parser::der::*; +use der_parser::error::*; +use der_parser::oid::Oid; +use hex_literal::hex; +use nom::*; + +#[test] +fn test_flat_take() { + let empty = &b""[..]; + assert_eq!( + parse_ber_bool(&[0x01, 0x01, 0xff]), + Ok((empty, BerObject::from_obj(BerObjectContent::Boolean(true)))) + ); + assert_eq!( + parse_ber_bool(&[0x01, 0x01, 0x00]), + Ok((empty, BerObject::from_obj(BerObjectContent::Boolean(false)))) + ); + assert_eq!( + ber_read_element_content_as(&[0xff], Tag::Boolean, 0x01.into(), false, MAX_RECURSION), + Ok((empty, BerObjectContent::Boolean(true))) + ); + assert_eq!( + ber_read_element_content_as(&[0x00], Tag::Boolean, 0x01.into(), false, MAX_RECURSION), + Ok((empty, BerObjectContent::Boolean(false))) + ); +} + +#[test] +fn test_oid() { + let empty = &b""[..]; + assert_eq!( + parse_der(&[0x06, 0x06, 42, 129, 122, 1, 16, 9]), + Ok(( + empty, + BerObject::from_obj(BerObjectContent::OID( + Oid::from(&[1, 2, 250, 1, 16, 9]).unwrap() + )) + )) + ); + // Dubuisson 433 + assert_eq!( + parse_der(&[0x0d, 0x05, 129, 122, 1, 16, 9]), + Ok(( + empty, + BerObject::from_obj(BerObjectContent::RelativeOID( + Oid::from_relative(&[250, 1, 16, 9]).unwrap() + )) + )) + ); +} + +#[test] +fn test_rel_oid() { + let empty = &b""[..]; + assert_eq!( + parse_der(&[0x0d, 0x04, 0xc2, 0x7b, 0x03, 0x02]), + Ok(( + empty, + BerObject::from_obj(BerObjectContent::RelativeOID( + Oid::from_relative(&[8571, 3, 2]).unwrap() + )) + )) + ); +} + +#[rustfmt::skip::macros(oid)] +#[test] +fn test_oid_iter_length_check() { + use der_parser::oid; + use std::borrow::Cow; + // empty + assert!(Oid::new(Cow::Borrowed(&[])).iter().is_some()); + assert!(Oid::new_relative(Cow::Borrowed(&[])).iter().is_some()); + // ok + assert!(oid!(0).iter().is_some()); + assert!(oid!(1.2).iter().is_some()); + assert!(oid!(1.2.3456.23.54).iter().is_some()); + // too long + assert!(oid!(1.2.18445618199572250625).iter().is_none()); + assert!(oid!(rel 18445618199572250625).iter().is_none()); +} + +#[test] +fn test_unknown_tag() { + let bytes = hex!("1d 01 00"); + let res = parse_ber(&bytes).expect("parsing failed"); + assert!(res.0.is_empty()); + assert_eq!( + res.1, + BerObject::from_obj(BerObjectContent::Unknown(Any::from_tag_and_data( + Tag(0x1d), + &bytes[2..] + ))) + ); + let res = parse_der(&bytes).expect("parsing failed"); + assert!(res.0.is_empty()); + assert_eq!( + res.1, + BerObject::from_obj(BerObjectContent::Unknown(Any::from_tag_and_data( + Tag(0x1d), + &bytes[2..] + ))) + ); +} + +#[test] +fn test_unknown_context_specific() { + let bytes = hex!("80 01 00"); + let res = parse_ber(&bytes).expect("parsing failed"); + assert!(res.0.is_empty()); + assert_eq!( + res.1, + BerObject { + header: Header::new(Class::ContextSpecific, false, Tag(0), 1.into()) + .with_raw_tag(Some(Cow::Borrowed(&[0x80]))), + content: BerObjectContent::Unknown( + Any::from_tag_and_data(Tag(0x0), &bytes[2..]).with_class(Class::ContextSpecific) + ), + } + ); +} + +#[test] +fn test_unknown_long_tag() { + let bytes = hex!("9f 22 01 00"); + let res = parse_ber(&bytes).expect("parsing failed"); + assert!(res.0.is_empty()); + assert_eq!( + res.1, + BerObject { + header: Header::new(Class::ContextSpecific, false, Tag(0x22), 1.into()) + .with_raw_tag(Some(Cow::Borrowed(&[0x9f, 0x22]))), + content: BerObjectContent::Unknown( + Any::from_tag_and_data(Tag(0x22), &bytes[3..]).with_class(Class::ContextSpecific) + ), + } + ); +} + +#[test] +fn test_unknown_longer_tag() { + let bytes = hex!("9f a2 22 01 00"); + let res = parse_ber(&bytes).expect("parsing failed"); + assert!(res.0.is_empty()); + assert_eq!( + res.1, + BerObject { + header: Header::new(Class::ContextSpecific, false, Tag(0x1122), 1.into()) + .with_raw_tag(Some(Cow::Borrowed(&[0x9f, 0xa2, 0x22]))), + content: BerObjectContent::Unknown( + Any::from_tag_and_data(Tag(0x1122), &bytes[4..]).with_class(Class::ContextSpecific) + ), + } + ); +} + +#[test] +fn test_incomplete_tag() { + let bytes = hex!("9f a2 a2"); + let res = parse_ber(&bytes); + assert!(res.is_err()); +} + +#[test] +fn test_overflow_tag() { + let bytes = hex!("9f a2 a2 a2 a2 a2 22 01 00"); + let res = parse_ber(&bytes); + assert!(res.is_err()); +} + +#[test] +fn test_incomplete_length() { + let bytes = hex!("30"); + let res = parse_ber(&bytes).err().expect("expected error"); + assert_eq!(res, Err::Incomplete(Needed::new(1))); + let res = parse_der(&bytes).err().expect("expected error"); + assert_eq!(res, Err::Incomplete(Needed::new(1))); + let bytes = hex!("02"); + let res = parse_ber(&bytes).err().expect("expected error"); + assert_eq!(res, Err::Incomplete(Needed::new(1))); + let bytes = hex!("02 05"); + let _ = parse_ber(&bytes).err().expect("expected error"); + let bytes = hex!("02 85"); + let res = parse_ber(&bytes).err().expect("expected error"); + assert_eq!(res, Err::Incomplete(Needed::new(5))); + let bytes = hex!("02 85 ff"); + let res = parse_ber(&bytes).err().expect("expected error"); + assert_eq!(res, Err::Incomplete(Needed::new(4))); +} + +#[test] +fn test_invalid_length() { + let bytes = hex!("02 ff 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10"); + let _ = parse_ber(&bytes).err().expect("expected error"); + let _ = ber_read_element_header(&bytes) + .err() + .expect("expected error"); + // + let bytes = hex!("02 8a ff ff ff ff ff ff ff ff ff ff 00"); + let res = parse_ber(&bytes).expect_err("parsing should have returned error"); + assert_eq!(Err::Error(BerError::InvalidLength), res); + // + let bytes = hex!("02 ff 00"); + let res = parse_ber(&bytes).expect_err("parsing should have returned error"); + assert_eq!(Err::Error(BerError::InvalidLength), res); + // + let bytes = hex!("02 02 00"); + let res = parse_der(&bytes).err().expect("expected error"); + assert_eq!(res, Err::Incomplete(Needed::new(2))); +} + +#[test] +fn test_pretty_print() { + let bytes = hex!("01 01 ff"); + let obj = parse_der(&bytes).map(|(_, b)| b).expect("expected error"); + println!("{:?}", obj.as_pretty(0, 2)); + + // controlling the pretty-printer + let mut pp = obj.as_pretty(0, 4); + pp.set_flag(PrettyPrinterFlag::ShowHeader); + println!("{:?}", pp); +} + +#[test] +fn test_print_unexpected() { + let bytes = hex!("01 01 ff"); + let nom_err = parse_der_integer(&bytes).expect_err("expected error"); + nom_err.map(|e| eprintln!("{}", e)); + + eprintln!("{}", BerError::BerMaxDepth); +} |