662 lines
21 KiB
Rust
662 lines
21 KiB
Rust
|
|
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_numericstring() {
|
||
|
|
//
|
||
|
|
let input = &hex!("12 03 31 32 33");
|
||
|
|
let (rem, result) = NumericString::from_der(input).expect("parsing failed");
|
||
|
|
assert_eq!(result.as_ref(), "123");
|
||
|
|
assert_eq!(rem, &[]);
|
||
|
|
// wrong charset
|
||
|
|
let input = &hex!("12 03 41 42 43");
|
||
|
|
let _ = NumericString::from_der(input).expect_err("parsing should fail");
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn from_der_octetstring() {
|
||
|
|
// coverage
|
||
|
|
use std::borrow::Cow;
|
||
|
|
let s = OctetString::new(b"1234");
|
||
|
|
assert_eq!(s.as_cow().len(), 4);
|
||
|
|
assert_eq!(s.into_cow(), Cow::Borrowed(b"1234"));
|
||
|
|
//
|
||
|
|
let input = &hex!("04 05 41 41 41 41 41");
|
||
|
|
let (rem, result) = OctetString::from_der(input).expect("parsing failed");
|
||
|
|
assert_eq!(result.as_ref(), b"AAAAA");
|
||
|
|
assert_eq!(rem, &[]);
|
||
|
|
//
|
||
|
|
let (rem, result) = <&[u8]>::from_der(input).expect("parsing failed");
|
||
|
|
assert_eq!(result, b"AAAAA");
|
||
|
|
assert_eq!(rem, &[]);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn from_der_octetstring_as_slice() {
|
||
|
|
let input = &hex!("04 05 41 41 41 41 41");
|
||
|
|
let (rem, result) = <&[u8]>::from_der(input).expect("parsing failed");
|
||
|
|
assert_eq!(result, b"AAAAA");
|
||
|
|
assert_eq!(rem, &[]);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn from_der_oid() {
|
||
|
|
let input = &hex!("06 09 2a 86 48 86 f7 0d 01 01 05");
|
||
|
|
let (rem, result) = Oid::from_der(input).expect("parsing failed");
|
||
|
|
let expected = Oid::from(&[1, 2, 840, 113_549, 1, 1, 5]).unwrap();
|
||
|
|
assert_eq!(result, expected);
|
||
|
|
assert_eq!(rem, &[]);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn from_der_optional() {
|
||
|
|
let input = &hex!("30 0a 0a 03 00 00 01 02 03 01 00 01");
|
||
|
|
let (rem, result) = Sequence::from_der_and_then(input, |input| {
|
||
|
|
let (i, obj0) = <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);
|
||
|
|
}
|