chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

View File

@@ -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

64
vendor/der/tests/datetime.rs vendored Normal file
View File

@@ -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
);
})
}

539
vendor/der/tests/derive.rs vendored Normal file
View File

@@ -0,0 +1,539 @@
//! 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: &[u8] = &hex!("17 0d 39 31 30 35 30 36 32 33 34 35 34 30 5a");
const GENERAL_TIMESTAMP_DER: &[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: &[u8] = &hex!("80 04 00 01 02 03");
const TIME_DER: &[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 core::marker::PhantomData;
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, Default)]
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,
/// Test handling of PhantomData.
pub phantom: PhantomData<()>,
}
// 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);
}
#[test]
fn idp_encode_twice() {
let mut vec_buf = Vec::new();
IssuingDistributionPointExample {
only_contains_user_certs: true,
..Default::default()
}
.encode_to_vec(&mut vec_buf)
.unwrap();
// encode to the same vec by appending
IssuingDistributionPointExample {
only_contains_cacerts: true,
..Default::default()
}
.encode_to_vec(&mut vec_buf)
.unwrap();
assert_eq!(vec_buf, hex!("30038101FF 30038201FF"));
}
// 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_der().unwrap()
);
}
}
mod infer_default {
//! When another crate might define a PartialEq for another type, the use of
//! `default="Default::default"` in the der derivation will not provide enough
//! information for `der_derive` crate to figure out.
//!
//! This provides a reproduction for that case. This is intended to fail when we
//! compile tests.
//! ```
//! error[E0282]: type annotations needed
//! --> der/tests/derive.rs:480:26
//! |
//!480 | #[asn1(default = "Default::default")]
//! | ^^^^^^^^^^^^^^^^^^ cannot infer type
//!
//!error[E0283]: type annotations needed
//! --> der/tests/derive.rs:478:14
//! |
//!478 | #[derive(Sequence)]
//! | ^^^^^^^^ cannot infer type
//! |
//!note: multiple `impl`s satisfying `bool: PartialEq<_>` found
//! --> der/tests/derive.rs:472:5
//! |
//!472 | impl PartialEq<BooleanIsh> for bool {
//! | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! = note: and another `impl` found in the `core` crate:
//! - impl<host> PartialEq for bool
//! where the constant `host` has type `bool`;
//! = note: required for `&bool` to implement `PartialEq<&_>`
//! = note: this error originates in the derive macro `Sequence` (in Nightly builds, run with -Z macro-backtrace for more info)
//! ```
use der::Sequence;
struct BooleanIsh;
impl PartialEq<BooleanIsh> for bool {
fn eq(&self, _other: &BooleanIsh) -> bool {
unimplemented!("This is only here to mess up the compiler's type inference")
}
}
#[derive(Sequence)]
struct Foo {
#[asn1(default = "Default::default")]
pub use_default_default: bool,
#[asn1(default = "something_true")]
pub use_custom: bool,
}
fn something_true() -> bool {
todo!()
}
}

BIN
vendor/der/tests/examples/spki.der vendored Normal file

Binary file not shown.

3
vendor/der/tests/examples/spki.pem vendored Normal file
View File

@@ -0,0 +1,3 @@
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEATSkWfz8ZEqb3rfopOgUaFcBexnuPFyZ7HFVQ3OhTvQ0=
-----END PUBLIC KEY-----

67
vendor/der/tests/pem.rs vendored Normal file
View File

@@ -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);
}

65
vendor/der/tests/set_of.rs vendored Normal file
View File

@@ -0,0 +1,65 @@
//! `SetOf` tests.
#![cfg(feature = "alloc")]
use der::{asn1::SetOfVec, DerOrd};
use proptest::{prelude::*, string::*};
use std::collections::BTreeSet;
proptest! {
#[test]
fn sort_equiv(bytes in bytes_regex(".{0,64}").unwrap()) {
let mut uniq = BTreeSet::new();
// Ensure there are no duplicates
if bytes.iter().copied().all(move |x| uniq.insert(x)) {
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);
}
}