summaryrefslogtreecommitdiffstats
path: root/vendor/der/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:35 +0000
commit7e5d7eea9c580ef4b41a765bde624af431942b96 (patch)
tree2c0d9ca12878fc4525650aa4e54d77a81a07cc09 /vendor/der/tests
parentAdding debian version 1.70.0+dfsg1-9. (diff)
downloadrustc-7e5d7eea9c580ef4b41a765bde624af431942b96.tar.xz
rustc-7e5d7eea9c580ef4b41a765bde624af431942b96.zip
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/der/tests')
-rw-r--r--vendor/der/tests/datetime.proptest-regressions8
-rw-r--r--vendor/der/tests/datetime.rs64
-rw-r--r--vendor/der/tests/derive.rs459
-rw-r--r--vendor/der/tests/examples/spki.derbin0 -> 44 bytes
-rw-r--r--vendor/der/tests/examples/spki.pem3
-rw-r--r--vendor/der/tests/pem.rs67
-rw-r--r--vendor/der/tests/set_of.rs59
7 files changed, 660 insertions, 0 deletions
diff --git a/vendor/der/tests/datetime.proptest-regressions b/vendor/der/tests/datetime.proptest-regressions
new file mode 100644
index 000000000..f280ac46a
--- /dev/null
+++ b/vendor/der/tests/datetime.proptest-regressions
@@ -0,0 +1,8 @@
+# Seeds for failure cases proptest has generated in the past. It is
+# automatically read and these particular cases re-run before any
+# novel cases are generated.
+#
+# It is recommended to check this file in to source control so that
+# everyone who runs the test benefits from these saved cases.
+cc 00dbea7e90761c16aa20e2fbf7ffad420da0c84d4ed4e6df123de03c9b4567e5 # shrinks to year = 1970, month = 1, day = 1, hour = 0, min = 60, sec = 0
+cc 3b0bd01ef4cad6bea0a287f9cdcd56bad186125ec388d204f6afcd193ca12c39 # shrinks to year = 1970, month = 1, day = 1, hour = 0, min = 0, sec = 60
diff --git a/vendor/der/tests/datetime.rs b/vendor/der/tests/datetime.rs
new file mode 100644
index 000000000..454c1f0e4
--- /dev/null
+++ b/vendor/der/tests/datetime.rs
@@ -0,0 +1,64 @@
+//! Tests for the [`DateTime`] type.
+
+use der::{asn1::UtcTime, DateTime, Decode, Encode};
+use proptest::prelude::*;
+
+proptest! {
+ #[test]
+ fn roundtrip_datetime(
+ year in 1970u16..=9999,
+ month in 1u8..=12,
+ day in 1u8..=31,
+ hour in 0u8..=23,
+ min in 0u8..=59,
+ sec in 0u8..=59,
+ ) {
+ let datetime1 = make_datetime(year, month, day, hour, min, sec);
+ let datetime2 = DateTime::from_unix_duration(datetime1.unix_duration()).unwrap();
+ prop_assert_eq!(datetime1, datetime2);
+ }
+
+ #[test]
+ fn roundtrip_utctime(
+ year in 1970u16..=2049,
+ month in 1u8..=12,
+ day in 1u8..=31,
+ hour in 0u8..=23,
+ min in 0u8..=59,
+ sec in 0u8..=59,
+ ) {
+ let datetime = make_datetime(year, month, day, hour, min, sec);
+ let utc_time1 = UtcTime::try_from(datetime).unwrap();
+
+ let mut buf = [0u8; 128];
+ let mut encoder = der::SliceWriter::new(&mut buf);
+ utc_time1.encode(&mut encoder).unwrap();
+ let der_bytes = encoder.finish().unwrap();
+
+ let utc_time2 = UtcTime::from_der(der_bytes).unwrap();
+ prop_assert_eq!(utc_time1, utc_time2);
+ }
+}
+
+fn make_datetime(year: u16, month: u8, day: u8, hour: u8, min: u8, sec: u8) -> DateTime {
+ let max_day = if month == 2 {
+ let is_leap_year = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
+
+ if is_leap_year {
+ 29
+ } else {
+ 28
+ }
+ } else {
+ 30
+ };
+
+ let day = if day > max_day { max_day } else { day };
+
+ DateTime::new(year, month, day, hour, min, sec).unwrap_or_else(|e| {
+ panic!(
+ "invalid DateTime: {:02}-{:02}-{:02}T{:02}:{:02}:{:02}: {}",
+ year, month, day, hour, min, sec, e
+ );
+ })
+}
diff --git a/vendor/der/tests/derive.rs b/vendor/der/tests/derive.rs
new file mode 100644
index 000000000..dac14f816
--- /dev/null
+++ b/vendor/der/tests/derive.rs
@@ -0,0 +1,459 @@
+//! Tests for custom derive support.
+//!
+//! # Debugging with `cargo expand`
+//!
+//! To expand the Rust code generated by the proc macro when debugging
+//! issues related to these tests, run:
+//!
+//! $ cargo expand --test derive --all-features
+
+#![cfg(all(feature = "derive", feature = "alloc"))]
+
+/// Custom derive test cases for the `Choice` macro.
+mod choice {
+ /// `Choice` with `EXPLICIT` tagging.
+ mod explicit {
+ use der::{
+ asn1::{GeneralizedTime, UtcTime},
+ Choice, Decode, Encode, SliceWriter,
+ };
+ use hex_literal::hex;
+ use std::time::Duration;
+
+ /// Custom derive test case for the `Choice` macro.
+ ///
+ /// Based on `Time` as defined in RFC 5280:
+ /// <https://tools.ietf.org/html/rfc5280#page-117>
+ ///
+ /// ```text
+ /// Time ::= CHOICE {
+ /// utcTime UTCTime,
+ /// generalTime GeneralizedTime }
+ /// ```
+ #[derive(Choice)]
+ pub enum Time {
+ #[asn1(type = "UTCTime")]
+ UtcTime(UtcTime),
+
+ #[asn1(type = "GeneralizedTime")]
+ GeneralTime(GeneralizedTime),
+ }
+
+ impl Time {
+ fn to_unix_duration(self) -> Duration {
+ match self {
+ Time::UtcTime(t) => t.to_unix_duration(),
+ Time::GeneralTime(t) => t.to_unix_duration(),
+ }
+ }
+ }
+
+ const UTC_TIMESTAMP_DER: &'static [u8] =
+ &hex!("17 0d 39 31 30 35 30 36 32 33 34 35 34 30 5a");
+ const GENERAL_TIMESTAMP_DER: &'static [u8] =
+ &hex!("18 0f 31 39 39 31 30 35 30 36 32 33 34 35 34 30 5a");
+
+ #[test]
+ fn decode() {
+ let utc_time = Time::from_der(UTC_TIMESTAMP_DER).unwrap();
+ assert_eq!(utc_time.to_unix_duration().as_secs(), 673573540);
+
+ let general_time = Time::from_der(GENERAL_TIMESTAMP_DER).unwrap();
+ assert_eq!(general_time.to_unix_duration().as_secs(), 673573540);
+ }
+
+ #[test]
+ fn encode() {
+ let mut buf = [0u8; 128];
+
+ let utc_time = Time::from_der(UTC_TIMESTAMP_DER).unwrap();
+ let mut encoder = SliceWriter::new(&mut buf);
+ utc_time.encode(&mut encoder).unwrap();
+ assert_eq!(UTC_TIMESTAMP_DER, encoder.finish().unwrap());
+
+ let general_time = Time::from_der(GENERAL_TIMESTAMP_DER).unwrap();
+ let mut encoder = SliceWriter::new(&mut buf);
+ general_time.encode(&mut encoder).unwrap();
+ assert_eq!(GENERAL_TIMESTAMP_DER, encoder.finish().unwrap());
+ }
+ }
+
+ /// `Choice` with `IMPLICIT` tagging.
+ mod implicit {
+ use der::{
+ asn1::{BitStringRef, GeneralizedTime},
+ Choice, Decode, Encode, SliceWriter,
+ };
+ use hex_literal::hex;
+
+ /// `Choice` macro test case for `IMPLICIT` tagging.
+ #[derive(Choice, Debug, Eq, PartialEq)]
+ #[asn1(tag_mode = "IMPLICIT")]
+ pub enum ImplicitChoice<'a> {
+ #[asn1(context_specific = "0", type = "BIT STRING")]
+ BitString(BitStringRef<'a>),
+
+ #[asn1(context_specific = "1", type = "GeneralizedTime")]
+ Time(GeneralizedTime),
+
+ #[asn1(context_specific = "2", type = "UTF8String")]
+ Utf8String(String),
+ }
+
+ impl<'a> ImplicitChoice<'a> {
+ pub fn bit_string(&self) -> Option<BitStringRef<'a>> {
+ match self {
+ Self::BitString(bs) => Some(*bs),
+ _ => None,
+ }
+ }
+
+ pub fn time(&self) -> Option<GeneralizedTime> {
+ match self {
+ Self::Time(time) => Some(*time),
+ _ => None,
+ }
+ }
+ }
+
+ const BITSTRING_DER: &'static [u8] = &hex!("80 04 00 01 02 03");
+ const TIME_DER: &'static [u8] = &hex!("81 0f 31 39 39 31 30 35 30 36 32 33 34 35 34 30 5a");
+
+ #[test]
+ fn decode() {
+ let cs_bit_string = ImplicitChoice::from_der(BITSTRING_DER).unwrap();
+ assert_eq!(
+ cs_bit_string.bit_string().unwrap().as_bytes().unwrap(),
+ &[1, 2, 3]
+ );
+
+ let cs_time = ImplicitChoice::from_der(TIME_DER).unwrap();
+ assert_eq!(
+ cs_time.time().unwrap().to_unix_duration().as_secs(),
+ 673573540
+ );
+ }
+
+ #[test]
+ fn encode() {
+ let mut buf = [0u8; 128];
+
+ let cs_bit_string = ImplicitChoice::from_der(BITSTRING_DER).unwrap();
+ let mut encoder = SliceWriter::new(&mut buf);
+ cs_bit_string.encode(&mut encoder).unwrap();
+ assert_eq!(BITSTRING_DER, encoder.finish().unwrap());
+
+ let cs_time = ImplicitChoice::from_der(TIME_DER).unwrap();
+ let mut encoder = SliceWriter::new(&mut buf);
+ cs_time.encode(&mut encoder).unwrap();
+ assert_eq!(TIME_DER, encoder.finish().unwrap());
+ }
+ }
+}
+
+/// Custom derive test cases for the `Enumerated` macro.
+mod enumerated {
+ use der::{Decode, Encode, Enumerated, SliceWriter};
+ use hex_literal::hex;
+
+ /// X.509 `CRLReason`.
+ #[derive(Enumerated, Copy, Clone, Debug, Eq, PartialEq)]
+ #[repr(u32)]
+ pub enum CrlReason {
+ Unspecified = 0,
+ KeyCompromise = 1,
+ CaCompromise = 2,
+ AffiliationChanged = 3,
+ Superseded = 4,
+ CessationOfOperation = 5,
+ CertificateHold = 6,
+ RemoveFromCrl = 8,
+ PrivilegeWithdrawn = 9,
+ AaCompromised = 10,
+ }
+
+ const UNSPECIFIED_DER: &[u8] = &hex!("0a 01 00");
+ const KEY_COMPROMISE_DER: &[u8] = &hex!("0a 01 01");
+
+ #[test]
+ fn decode() {
+ let unspecified = CrlReason::from_der(UNSPECIFIED_DER).unwrap();
+ assert_eq!(CrlReason::Unspecified, unspecified);
+
+ let key_compromise = CrlReason::from_der(KEY_COMPROMISE_DER).unwrap();
+ assert_eq!(CrlReason::KeyCompromise, key_compromise);
+ }
+
+ #[test]
+ fn encode() {
+ let mut buf = [0u8; 128];
+
+ let mut encoder = SliceWriter::new(&mut buf);
+ CrlReason::Unspecified.encode(&mut encoder).unwrap();
+ assert_eq!(UNSPECIFIED_DER, encoder.finish().unwrap());
+
+ let mut encoder = SliceWriter::new(&mut buf);
+ CrlReason::KeyCompromise.encode(&mut encoder).unwrap();
+ assert_eq!(KEY_COMPROMISE_DER, encoder.finish().unwrap());
+ }
+}
+
+/// Custom derive test cases for the `Sequence` macro.
+#[cfg(feature = "oid")]
+mod sequence {
+ use der::{
+ asn1::{AnyRef, ObjectIdentifier, SetOf},
+ Decode, Encode, Sequence, ValueOrd,
+ };
+ use hex_literal::hex;
+
+ pub fn default_false_example() -> bool {
+ false
+ }
+
+ // Issuing distribution point extension as defined in [RFC 5280 Section 5.2.5] and as identified by the [`PKIX_PE_SUBJECTINFOACCESS`](constant.PKIX_PE_SUBJECTINFOACCESS.html) OID.
+ //
+ // ```text
+ // IssuingDistributionPoint ::= SEQUENCE {
+ // distributionPoint [0] DistributionPointName OPTIONAL,
+ // onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
+ // onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
+ // onlySomeReasons [3] ReasonFlags OPTIONAL,
+ // indirectCRL [4] BOOLEAN DEFAULT FALSE,
+ // onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE }
+ // -- at most one of onlyContainsUserCerts, onlyContainsCACerts,
+ // -- and onlyContainsAttributeCerts may be set to TRUE.
+ // ```
+ //
+ // [RFC 5280 Section 5.2.5]: https://datatracker.ietf.org/doc/html/rfc5280#section-5.2.5
+ #[derive(Sequence)]
+ pub struct IssuingDistributionPointExample {
+ // Omit distributionPoint and only_some_reasons because corresponding structs are not
+ // available here and are not germane to the example
+ // distributionPoint [0] DistributionPointName OPTIONAL,
+ //#[asn1(context_specific="0", optional="true", tag_mode="IMPLICIT")]
+ //pub distribution_point: Option<DistributionPointName<'a>>,
+ /// onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
+ #[asn1(
+ context_specific = "1",
+ default = "default_false_example",
+ tag_mode = "IMPLICIT"
+ )]
+ pub only_contains_user_certs: bool,
+
+ /// onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
+ #[asn1(
+ context_specific = "2",
+ default = "default_false_example",
+ tag_mode = "IMPLICIT"
+ )]
+ pub only_contains_cacerts: bool,
+
+ // onlySomeReasons [3] ReasonFlags OPTIONAL,
+ //#[asn1(context_specific="3", optional="true", tag_mode="IMPLICIT")]
+ //pub only_some_reasons: Option<ReasonFlags<'a>>,
+ /// indirectCRL [4] BOOLEAN DEFAULT FALSE,
+ #[asn1(
+ context_specific = "4",
+ default = "default_false_example",
+ tag_mode = "IMPLICIT"
+ )]
+ pub indirect_crl: bool,
+
+ /// onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE
+ #[asn1(
+ context_specific = "5",
+ default = "default_false_example",
+ tag_mode = "IMPLICIT"
+ )]
+ pub only_contains_attribute_certs: bool,
+ }
+
+ // Extension as defined in [RFC 5280 Section 4.1.2.9].
+ //
+ // The ASN.1 definition for Extension objects is below. The extnValue type may be further parsed using a decoder corresponding to the extnID value.
+ //
+ // ```text
+ // Extension ::= SEQUENCE {
+ // extnID OBJECT IDENTIFIER,
+ // critical BOOLEAN DEFAULT FALSE,
+ // extnValue OCTET STRING
+ // -- contains the DER encoding of an ASN.1 value
+ // -- corresponding to the extension type identified
+ // -- by extnID
+ // }
+ // ```
+ //
+ // [RFC 5280 Section 4.1.2.9]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.9
+ #[derive(Clone, Debug, Eq, PartialEq, Sequence)]
+ pub struct ExtensionExample<'a> {
+ /// extnID OBJECT IDENTIFIER,
+ pub extn_id: ObjectIdentifier,
+
+ /// critical BOOLEAN DEFAULT FALSE,
+ #[asn1(default = "default_false_example")]
+ pub critical: bool,
+
+ /// extnValue OCTET STRING
+ #[asn1(type = "OCTET STRING")]
+ pub extn_value: &'a [u8],
+ }
+
+ /// X.509 `AlgorithmIdentifier`
+ #[derive(Copy, Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)]
+ pub struct AlgorithmIdentifier<'a> {
+ pub algorithm: ObjectIdentifier,
+ pub parameters: Option<AnyRef<'a>>,
+ }
+
+ /// X.509 `SubjectPublicKeyInfo` (SPKI)
+ #[derive(Copy, Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)]
+ pub struct SubjectPublicKeyInfo<'a> {
+ pub algorithm: AlgorithmIdentifier<'a>,
+ #[asn1(type = "BIT STRING")]
+ pub subject_public_key: &'a [u8],
+ }
+
+ /// PKCS#8v2 `OneAsymmetricKey`
+ #[derive(Sequence)]
+ pub struct OneAsymmetricKey<'a> {
+ pub version: u8,
+ pub private_key_algorithm: AlgorithmIdentifier<'a>,
+ #[asn1(type = "OCTET STRING")]
+ pub private_key: &'a [u8],
+ #[asn1(context_specific = "0", extensible = "true", optional = "true")]
+ pub attributes: Option<SetOf<AnyRef<'a>, 1>>,
+ #[asn1(
+ context_specific = "1",
+ extensible = "true",
+ optional = "true",
+ type = "BIT STRING"
+ )]
+ pub public_key: Option<&'a [u8]>,
+ }
+
+ /// X.509 extension
+ // TODO(tarcieri): tests for code derived with the `default` attribute
+ #[derive(Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)]
+ pub struct Extension<'a> {
+ extn_id: ObjectIdentifier,
+ #[asn1(default = "critical_default")]
+ critical: bool,
+ #[asn1(type = "OCTET STRING")]
+ extn_value: &'a [u8],
+ }
+
+ /// Default value of the `critical` bit
+ fn critical_default() -> bool {
+ false
+ }
+
+ const ID_EC_PUBLIC_KEY_OID: ObjectIdentifier =
+ ObjectIdentifier::new_unwrap("1.2.840.10045.2.1");
+
+ const PRIME256V1_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.3.1.7");
+
+ const ALGORITHM_IDENTIFIER_DER: &[u8] =
+ &hex!("30 13 06 07 2a 86 48 ce 3d 02 01 06 08 2a 86 48 ce 3d 03 01 07");
+
+ #[derive(Sequence)]
+ #[asn1(tag_mode = "IMPLICIT")]
+ pub struct TypeCheckExpandedSequenceFieldAttributeCombinations<'a> {
+ pub simple: bool,
+ #[asn1(type = "BIT STRING")]
+ pub typed: &'a [u8],
+ #[asn1(context_specific = "0")]
+ pub context_specific: bool,
+ #[asn1(optional = "true")]
+ pub optional: Option<bool>,
+ #[asn1(default = "default_false_example")]
+ pub default: bool,
+ #[asn1(type = "BIT STRING", context_specific = "1")]
+ pub typed_context_specific: &'a [u8],
+ #[asn1(context_specific = "2", optional = "true")]
+ pub context_specific_optional: Option<bool>,
+ #[asn1(context_specific = "3", default = "default_false_example")]
+ pub context_specific_default: bool,
+ #[asn1(type = "BIT STRING", context_specific = "4", optional = "true")]
+ pub typed_context_specific_optional: Option<&'a [u8]>,
+ }
+
+ #[test]
+ fn idp_test() {
+ let idp = IssuingDistributionPointExample::from_der(&hex!("30038101FF")).unwrap();
+ assert_eq!(idp.only_contains_user_certs, true);
+ assert_eq!(idp.only_contains_cacerts, false);
+ assert_eq!(idp.indirect_crl, false);
+ assert_eq!(idp.only_contains_attribute_certs, false);
+
+ let idp = IssuingDistributionPointExample::from_der(&hex!("30038201FF")).unwrap();
+ assert_eq!(idp.only_contains_user_certs, false);
+ assert_eq!(idp.only_contains_cacerts, true);
+ assert_eq!(idp.indirect_crl, false);
+ assert_eq!(idp.only_contains_attribute_certs, false);
+
+ let idp = IssuingDistributionPointExample::from_der(&hex!("30038401FF")).unwrap();
+ assert_eq!(idp.only_contains_user_certs, false);
+ assert_eq!(idp.only_contains_cacerts, false);
+ assert_eq!(idp.indirect_crl, true);
+ assert_eq!(idp.only_contains_attribute_certs, false);
+
+ let idp = IssuingDistributionPointExample::from_der(&hex!("30038501FF")).unwrap();
+ assert_eq!(idp.only_contains_user_certs, false);
+ assert_eq!(idp.only_contains_cacerts, false);
+ assert_eq!(idp.indirect_crl, false);
+ assert_eq!(idp.only_contains_attribute_certs, true);
+ }
+
+ // demonstrates default field that is not context specific
+ #[test]
+ fn extension_test() {
+ let ext1 = ExtensionExample::from_der(&hex!(
+ "300F" // 0 15: SEQUENCE {
+ "0603551D13" // 2 3: OBJECT IDENTIFIER basicConstraints (2 5 29 19)
+ "0101FF" // 7 1: BOOLEAN TRUE
+ "0405" // 10 5: OCTET STRING, encapsulates {
+ "3003" // 12 3: SEQUENCE {
+ "0101FF" // 14 1: BOOLEAN TRUE
+ ))
+ .unwrap();
+ assert_eq!(ext1.critical, true);
+
+ let ext2 = ExtensionExample::from_der(&hex!(
+ "301F" // 0 31: SEQUENCE {
+ "0603551D23" // 2 3: OBJECT IDENTIFIER authorityKeyIdentifier (2 5 29 35)
+ "0418" // 7 24: OCTET STRING, encapsulates {
+ "3016" // 9 22: SEQUENCE {
+ "8014E47D5FD15C9586082C05AEBE75B665A7D95DA866" // 11 20: [0] E4 7D 5F D1 5C 95 86 08 2C 05 AE BE 75 B6 65 A7 D9 5D A8 66
+ ))
+ .unwrap();
+ assert_eq!(ext2.critical, false);
+ }
+
+ #[test]
+ fn decode() {
+ let algorithm_identifier =
+ AlgorithmIdentifier::from_der(&ALGORITHM_IDENTIFIER_DER).unwrap();
+
+ assert_eq!(ID_EC_PUBLIC_KEY_OID, algorithm_identifier.algorithm);
+ assert_eq!(
+ PRIME256V1_OID,
+ ObjectIdentifier::try_from(algorithm_identifier.parameters.unwrap()).unwrap()
+ );
+ }
+
+ #[test]
+ fn encode() {
+ let parameters_oid = PRIME256V1_OID;
+
+ let algorithm_identifier = AlgorithmIdentifier {
+ algorithm: ID_EC_PUBLIC_KEY_OID,
+ parameters: Some(AnyRef::from(&parameters_oid)),
+ };
+
+ assert_eq!(
+ ALGORITHM_IDENTIFIER_DER,
+ algorithm_identifier.to_vec().unwrap()
+ );
+ }
+}
diff --git a/vendor/der/tests/examples/spki.der b/vendor/der/tests/examples/spki.der
new file mode 100644
index 000000000..1b602ee1f
--- /dev/null
+++ b/vendor/der/tests/examples/spki.der
Binary files differ
diff --git a/vendor/der/tests/examples/spki.pem b/vendor/der/tests/examples/spki.pem
new file mode 100644
index 000000000..6891701f7
--- /dev/null
+++ b/vendor/der/tests/examples/spki.pem
@@ -0,0 +1,3 @@
+-----BEGIN PUBLIC KEY-----
+MCowBQYDK2VwAyEATSkWfz8ZEqb3rfopOgUaFcBexnuPFyZ7HFVQ3OhTvQ0=
+-----END PUBLIC KEY-----
diff --git a/vendor/der/tests/pem.rs b/vendor/der/tests/pem.rs
new file mode 100644
index 000000000..d2c865463
--- /dev/null
+++ b/vendor/der/tests/pem.rs
@@ -0,0 +1,67 @@
+//! PEM decoding and encoding tests.
+
+#![cfg(all(feature = "derive", feature = "oid", feature = "pem"))]
+
+use der::{
+ asn1::{BitString, ObjectIdentifier},
+ pem::{LineEnding, PemLabel},
+ Decode, DecodePem, EncodePem, Sequence,
+};
+
+/// Example SPKI document encoded as DER.
+const SPKI_DER: &[u8] = include_bytes!("examples/spki.der");
+
+/// Example SPKI document encoded as PEM.
+const SPKI_PEM: &str = include_str!("examples/spki.pem");
+
+/// X.509 `AlgorithmIdentifier`
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Sequence)]
+pub struct AlgorithmIdentifier {
+ pub algorithm: ObjectIdentifier,
+ // pub parameters: ... (not used in spki.pem)
+}
+
+/// X.509 `SubjectPublicKeyInfo` (SPKI) in borrowed form
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Sequence)]
+pub struct SpkiBorrowed<'a> {
+ pub algorithm: AlgorithmIdentifier,
+ #[asn1(type = "BIT STRING")]
+ pub subject_public_key: &'a [u8],
+}
+
+impl PemLabel for SpkiBorrowed<'_> {
+ const PEM_LABEL: &'static str = "PUBLIC KEY";
+}
+
+/// X.509 `SubjectPublicKeyInfo` (SPKI) in owned form
+#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
+pub struct SpkiOwned {
+ pub algorithm: AlgorithmIdentifier,
+ pub subject_public_key: BitString,
+}
+
+impl PemLabel for SpkiOwned {
+ const PEM_LABEL: &'static str = "PUBLIC KEY";
+}
+
+#[test]
+fn from_pem() {
+ // Decode PEM to owned form.
+ let pem_spki = SpkiOwned::from_pem(SPKI_PEM).unwrap();
+
+ // Decode DER to borrowed form.
+ let der_spki = SpkiBorrowed::from_der(SPKI_DER).unwrap();
+
+ assert_eq!(pem_spki.algorithm, der_spki.algorithm);
+ assert_eq!(
+ pem_spki.subject_public_key.raw_bytes(),
+ der_spki.subject_public_key
+ );
+}
+
+#[test]
+fn to_pem() {
+ let spki = SpkiBorrowed::from_der(SPKI_DER).unwrap();
+ let pem = spki.to_pem(LineEnding::LF).unwrap();
+ assert_eq!(&pem, SPKI_PEM);
+}
diff --git a/vendor/der/tests/set_of.rs b/vendor/der/tests/set_of.rs
new file mode 100644
index 000000000..ba43d80a2
--- /dev/null
+++ b/vendor/der/tests/set_of.rs
@@ -0,0 +1,59 @@
+//! `SetOf` tests.
+
+#![cfg(feature = "alloc")]
+
+use der::{asn1::SetOfVec, DerOrd};
+use proptest::{prelude::*, string::*};
+
+proptest! {
+ #[test]
+ fn sort_equiv(bytes in bytes_regex(".{0,64}").unwrap()) {
+ let mut expected = bytes.clone();
+ expected.sort_by(|a, b| a.der_cmp(b).unwrap());
+
+ let set = SetOfVec::try_from(bytes).unwrap();
+ prop_assert_eq!(expected.as_slice(), set.as_slice());
+ }
+}
+
+/// Set ordering tests.
+#[cfg(all(feature = "derive", feature = "oid"))]
+mod ordering {
+ use der::{
+ asn1::{AnyRef, ObjectIdentifier, SetOf, SetOfVec},
+ Decode, Sequence, ValueOrd,
+ };
+ use hex_literal::hex;
+
+ /// X.501 `AttributeTypeAndValue`
+ #[derive(Copy, Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)]
+ pub struct AttributeTypeAndValue<'a> {
+ pub oid: ObjectIdentifier,
+ pub value: AnyRef<'a>,
+ }
+
+ const OUT_OF_ORDER_RDN_EXAMPLE: &[u8] =
+ &hex!("311F301106035504030C0A4A4F484E20534D495448300A060355040A0C03313233");
+
+ /// For compatibility reasons, we allow non-canonical DER with out-of-order
+ /// sets in order to match the behavior of other implementations.
+ #[test]
+ fn allow_out_of_order_setof() {
+ assert!(SetOf::<AttributeTypeAndValue<'_>, 2>::from_der(OUT_OF_ORDER_RDN_EXAMPLE).is_ok());
+ }
+
+ /// Same as above, with `SetOfVec` instead of `SetOf`.
+ #[test]
+ fn allow_out_of_order_setofvec() {
+ assert!(SetOfVec::<AttributeTypeAndValue<'_>>::from_der(OUT_OF_ORDER_RDN_EXAMPLE).is_ok());
+ }
+
+ /// Test to ensure ordering is handled correctly.
+ #[test]
+ fn ordering_regression() {
+ let der_bytes = hex!("3139301906035504030C12546573742055736572393031353734333830301C060A0992268993F22C640101130E3437303031303030303134373333");
+ let set = SetOf::<AttributeTypeAndValue<'_>, 3>::from_der(&der_bytes).unwrap();
+ let attr1 = set.get(0).unwrap();
+ assert_eq!(ObjectIdentifier::new("2.5.4.3").unwrap(), attr1.oid);
+ }
+}