rasn_pkix/
lib.rs

1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(test), no_std)]
3
4extern crate alloc;
5
6pub mod algorithms;
7pub mod attribute_certificate;
8pub mod est;
9
10use rasn::prelude::*;
11
12pub type InvalidityDate = GeneralizedTime;
13pub type CertificateIssuer = GeneralNames;
14pub type CrlNumber = Integer;
15pub type BaseCrlNumber = CrlNumber;
16pub type SubjectInfoAccessSyntax = SequenceOf<AccessDescription>;
17pub type AuthorityInfoAccessSyntax = SequenceOf<AccessDescription>;
18pub type FreshestCrl = CrlDistributionPoints;
19pub type InhibitAnyPolicy = CrlDistributionPoints;
20pub type KeyPurposeId = ObjectIdentifier;
21pub type ExtKeyUsageSyntax = SequenceOf<KeyPurposeId>;
22pub type ReasonFlags = BitString;
23pub type SkipCerts = Integer;
24pub type BaseDistance = Integer;
25pub type CrlDistributionPoints = SequenceOf<DistributionPoint>;
26pub type GeneralSubtrees = SequenceOf<GeneralSubtree>;
27pub type SubjectDirectoryAttributes = SequenceOf<Attribute>;
28pub type GeneralNames = SequenceOf<GeneralName>;
29pub type SubjectAltName = GeneralNames;
30pub type PolicyMappings = SequenceOf<PolicyMapping>;
31pub type CpsUri = Ia5String;
32pub type CertPolicyId = ObjectIdentifier;
33pub type CertificatePolicies = SequenceOf<PolicyInformation>;
34pub type KeyUsage = BitString;
35pub type AttributeType = ObjectIdentifier;
36pub type AttributeValue = Any;
37pub type RdnSequence = SequenceOf<RelativeDistinguishedName>;
38pub type X520DnQualifier = PrintableString;
39pub type DomainComponent = Ia5String;
40pub type EmailAddress = Ia5String;
41pub type CertificateSerialNumber = Integer;
42pub type UniqueIdentifier = BitString;
43pub type NetworkAddress = X121Address;
44pub type X121Address = NumericString;
45pub type TerminalIdentifier = PrintableString;
46pub type OrganisationName = PrintableString;
47pub type NumericUserIdentifier = NumericString;
48pub type TerminalType = u8;
49pub type KeyIdentifier = OctetString;
50pub type SubjectKeyIdentifier = KeyIdentifier;
51pub type PolicyQualifierId = ObjectIdentifier;
52pub type TrustAnchorTitle = Utf8String;
53pub type TrustAnchorList = SequenceOf<TrustAnchorChoice>;
54pub type CertPolicyFlags = BitString;
55
56macro_rules! derefable {
57    ($ty:ident, $inner:ty) => {
58        impl From<$inner> for $ty {
59            fn from(value: $inner) -> Self {
60                Self(value)
61            }
62        }
63
64        impl core::ops::Deref for $ty {
65            type Target = $inner;
66
67            fn deref(&self) -> &Self::Target {
68                &self.0
69            }
70        }
71
72        impl core::ops::DerefMut for $ty {
73            fn deref_mut(&mut self) -> &mut Self::Target {
74                &mut self.0
75            }
76        }
77    };
78}
79
80/// An X.509 certificate
81#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
82pub struct Certificate {
83    /// Certificate information.
84    pub tbs_certificate: TbsCertificate,
85    /// contains the identifier for the cryptographic algorithm used by the CA
86    /// to sign this certificate.
87    pub signature_algorithm: AlgorithmIdentifier,
88    /// Contains a digital signature computed upon the ASN.1 DER encoded
89    /// `tbs_certificate`.  The ASN.1 DER encoded tbsCertificate is used as the
90    /// input to the signature function. The details of this process are
91    /// specified for each of the algorithms listed in [RFC 3279], [RFC 4055],
92    /// and [RFC 4491].
93    ///
94    pub signature_value: BitString,
95}
96
97/// Information associated with the subject of the certificate and the CA that
98/// issued it.
99#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
100pub struct TbsCertificate {
101    /// The version of the encoded certificate.
102    #[rasn(tag(explicit(0)), default)]
103    pub version: Version,
104    /// The serial number MUST be a positive integer assigned by the CA to each
105    /// certificate.  It MUST be unique for each certificate issued by a given
106    /// CA (i.e., the issuer name and serial number identify a unique
107    /// certificate).  CAs MUST force the serialNumber to be a
108    /// non-negative integer.
109    ///
110    /// Given the uniqueness requirements above, serial numbers can be expected
111    /// to contain long integers.  Certificate users MUST be able to handle
112    /// serialNumber values up to 20 octets.  Conforming CAs MUST NOT use
113    /// serialNumber values longer than 20 octets.
114    ///
115    /// Note: Non-conforming CAs may issue certificates with serial numbers that
116    /// are negative or zero.  Certificate users SHOULD be prepared to
117    /// gracefully handle such certificates.
118    pub serial_number: CertificateSerialNumber,
119    /// The algorithm identifier for the algorithm used by the CA to sign
120    /// the certificate.
121    ///
122    /// This field MUST contain the same algorithm identifier as the
123    /// `Certificate.signature_algorithm`.  The contents of the optional
124    /// parameters field will vary according to the algorithm identified.
125    /// [RFC 3279], [RFC 4055], and [RFC 4491] list supported signature algorithms,
126    /// but other signature algorithms MAY also be supported.
127    pub signature: AlgorithmIdentifier,
128    /// The entity that has signed and issued the certificate. The issuer field
129    /// MUST contain a non-empty distinguished name (DN).
130    pub issuer: Name,
131    /// The time interval during which the CA warrants that it will maintain
132    /// information about the status of the certificate.
133    pub validity: Validity,
134    /// The entity associated with the public key stored in the subject public
135    /// key field.
136    pub subject: Name,
137    /// The public key and identifies the algorithm with which the key is used
138    /// (e.g., RSA, DSA, or Diffie-Hellman).
139    pub subject_public_key_info: SubjectPublicKeyInfo,
140    #[rasn(tag(1))]
141    pub issuer_unique_id: Option<UniqueIdentifier>,
142    #[rasn(tag(2))]
143    pub subject_unique_id: Option<UniqueIdentifier>,
144    /// Extensions to the certificate.
145    #[rasn(tag(explicit(3)))]
146    pub extensions: Option<Extensions>,
147}
148
149/// The version of a encoded certificate.
150///
151/// When extensions are used, as expected in this profile, version MUST be 3
152/// (value is 2).  If no extensions are present, but a UniqueIdentifier is
153/// present, the version SHOULD be 2 (value is 1); however, the version MAY
154/// be 3.  If only basic fields are present, the version SHOULD be 1 (the
155/// value is omitted from the certificate as the default value); however,
156/// the version MAY be 2 or 3.
157#[derive(AsnType, Clone, Copy, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
158#[rasn(delegate)]
159pub struct Version(u64);
160
161impl Version {
162    pub const V1: Self = Self(0);
163    pub const V2: Self = Self(1);
164    pub const V3: Self = Self(2);
165
166    /// Returns the raw value of the version. Note that the version is
167    /// zero-indexed (v1 is 0, v2 is 1, etc).
168    pub fn raw_value(self) -> u64 {
169        self.0
170    }
171}
172
173impl Default for Version {
174    fn default() -> Self {
175        Self::V1
176    }
177}
178
179impl core::fmt::Display for Version {
180    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
181        core::write!(f, "{}", self.0.saturating_add(1))
182    }
183}
184
185/// Trust anchors are widely used to verify digital signatures and
186/// validate certification paths [RFC 5280](https://www.rfc-editor.org/rfc/rfc5280).
187///
188/// They are required when validating certification paths. Though widely used, there is no
189/// standard format for representing trust anchor information.  The RFC-5914
190/// document describes the TrustAnchorInfo structure.
191#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
192pub struct TrustAnchorInfo {
193    /// version identifies the version of TrustAnchorInfo.  Defaults to 1.
194    #[rasn(tag(explicit(1)), default)]
195    pub version: TrustAnchorInfoVersion,
196    /// pubKey identifies the public key and algorithm associated with the
197    /// trust anchor using the SubjectPublicKeyInfo structure [RFC 5280].  The
198    /// SubjectPublicKeyInfo structure contains the algorithm identifier
199    /// followed by the public key itself.
200    pub pub_key: SubjectPublicKeyInfo,
201    /// keyId contains the public key identifier of the trust anchor public key.
202    pub key_id: KeyIdentifier,
203    /// taTitle is OPTIONAL.  When it is present, it provides a human-readable name
204    /// for the trust anchor.
205    pub ta_title: Option<TrustAnchorTitle>,
206    /// certPath is OPTIONAL.  When it is present, it provides the controls
207    /// needed to initialize an X.509 certification path validation algorithm
208    /// implementation (see Section 6 of [RFC 5280]).  When absent, the trust
209    /// anchor cannot be used to validate the signature on an X.509
210    /// certificate.
211    pub cert_path: Option<CertPathControls>,
212    #[rasn(tag(explicit(1)))]
213    /// exts is OPTIONAL.  When it is present, it can be used to associate
214    /// additional information with the trust anchor using the standard
215    /// Extensions structure.  Extensions that are anticipated to be widely
216    /// used have been included in the CertPathControls structure to avoid
217    /// overhead associated with use of the Extensions structure.  To avoid
218    /// duplication with the CertPathControls field, the following types of
219    /// extensions MUST NOT appear in the exts field and are ignored if they
220    /// do appear: id-ce-certificatePolicies, id-ce-policyConstraints, id-ce-
221    /// inhibitAnyPolicy, or id-ce-nameConstraints.
222    pub exts: Option<Extensions>,
223    #[rasn(tag(2))]
224    /// The taTitleLangTag field identifies the language used to express the
225    /// taTitle.  When taTitleLangTag is absent, English ("en" language tag)
226    /// is used.
227    pub ta_title_lang_tag: Option<Utf8String>,
228}
229
230/// CertPathControls provides the controls needed to initialize an X.509
231// certification path validation algorithm implementation
232#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
233pub struct CertPathControls {
234    /// taName provides the X.500 distinguished name associated with the
235    /// trust anchor, and this distinguished name is used to construct and
236    /// validate an X.509 certification path.  The name MUST NOT be an empty
237    /// sequence.
238    pub ta_name: Name,
239    #[rasn(tag(0))]
240    /// certificate provides an OPTIONAL X.509 certificate, which can be used
241    /// in some environments to represent the trust anchor in certification
242    /// path development and validation
243    pub certificate: Option<Certificate>,
244    #[rasn(tag(1))]
245    /// policySet contains a sequence of
246    /// certificate policy identifiers to be provided as inputs to the
247    /// certification path validation algorithm.
248    pub policy_set: Option<CertificatePolicies>,
249    #[rasn(tag(2))]
250    /// policyFlags is OPTIONAL.  When present, three Boolean values for
251    /// input to the certification path validation algorithm are provided in
252    /// a BIT STRING.  When absent, the input to the certification path
253    /// validation algorithm is { FALSE, FALSE, FALSE }, which represents the
254    /// most liberal setting for these flags.
255    pub policy_flags: Option<CertPolicyFlags>,
256    #[rasn(tag(3))]
257    /// nameConstrhas the same syntax and semantics as the
258    /// Name Constraints certificate extension [RFC 5280], which includes a
259    /// list of permitted names and a list of excluded names.
260    pub name_constr: Option<NameConstraints>,
261    #[rasn(tag(4))]
262    /// The pathLenConstraint field gives the maximum number of non-self-
263    /// issued intermediate certificates that may follow this certificate in
264    /// a valid certification path.  (Note: The last certificate in the
265    /// certification path is not an intermediate certificate and is not
266    /// included in this limit.  Usually, the last certificate is an end
267    /// entity certificate, but it can be a CA certificate.
268    pub path_len_constraint: Option<Integer>,
269}
270
271/// TrustAnchorChoice provides three options for representing a trust anchor.
272///
273/// The certificate option allows for the use of a certificate with no additional
274/// associated constraints.
275///
276/// The tbsCert option allows for associating constraints by removing a signature
277/// on a certificate and changing the extensions field.
278///
279/// The taInfo option allows for use of the TrustAnchorInfo structure defined
280/// in RFC-5914.
281#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
282#[rasn(choice)]
283pub enum TrustAnchorChoice {
284    Certificate(Certificate),
285    #[rasn(tag(explicit(1)))]
286    TbsCertificate(TbsCertificate),
287    #[rasn(tag(explicit(2)))]
288    TrustAnchorInfo(alloc::boxed::Box<TrustAnchorInfo>),
289}
290
291/// TrustAnchorInfoVersion identifies the version of TrustAnchorInfo. Future updates
292/// to RFC 5914 may include changes to the TrustAnchorInfo structure,
293/// in which case the version number should be incremented.
294#[derive(AsnType, Clone, Copy, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
295#[rasn(delegate)]
296pub struct TrustAnchorInfoVersion(u64);
297
298impl TrustAnchorInfoVersion {
299    pub const V1: Self = Self(1);
300
301    /// Returns the raw value of the version. Note that the version is
302    /// one-indexed.
303    pub fn raw_value(self) -> u64 {
304        self.0
305    }
306}
307
308impl Default for TrustAnchorInfoVersion {
309    fn default() -> Self {
310        Self::V1
311    }
312}
313
314impl core::fmt::Display for TrustAnchorInfoVersion {
315    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
316        core::write!(f, "{}", self.0)
317    }
318}
319
320/// The validity period of the certificate.
321#[derive(AsnType, Clone, Copy, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
322pub struct Validity {
323    pub not_before: Time,
324    pub not_after: Time,
325}
326
327/// A general time type.
328#[derive(AsnType, Clone, Copy, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
329#[rasn(choice)]
330pub enum Time {
331    Utc(UtcTime),
332    General(GeneralizedTime),
333}
334
335/// The subject's public key, and the algorithm used to encode it.
336#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
337pub struct SubjectPublicKeyInfo {
338    pub algorithm: AlgorithmIdentifier,
339    pub subject_public_key: BitString,
340}
341
342/// Identifying the public key corresponding to the private key used to sign a
343/// certificate.
344///
345/// This extension is used where an issuer has multiple signing keys (either due
346/// to multiple concurrent key pairs or due to changeover).  The identification
347/// MAY be based on either the key identifier (the subject key identifier in the
348/// issuer's certificate) or the issuer name and serial number.
349#[derive(AsnType, Default, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
350pub struct AuthorityKeyIdentifier {
351    #[rasn(tag(0))]
352    pub key_identifier: Option<KeyIdentifier>,
353    #[rasn(tag(1))]
354    pub authority_cert_issuer: Option<GeneralNames>,
355    #[rasn(tag(2))]
356    pub authority_cert_serial_number: Option<CertificateSerialNumber>,
357}
358
359/// Extension to an X.509 certificate.
360#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
361pub struct Extension {
362    pub extn_id: ObjectIdentifier,
363    #[rasn(default)]
364    pub critical: bool,
365    pub extn_value: OctetString,
366}
367
368/// A signed list of revoked certificates.
369#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
370pub struct CertificateList {
371    pub tbs_cert_list: TbsCertList,
372    pub signature_algorithm: AlgorithmIdentifier,
373    pub signature: BitString,
374}
375
376/// The list of revoked certificates along with associated metadata.
377#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
378pub struct TbsCertList {
379    /// The version of the list.
380    pub version: Version,
381    /// The algorithm used in the signature.
382    pub signature: AlgorithmIdentifier,
383    /// The authority that issued the certificate list.
384    pub issuer: Name,
385    /// The issue date of this list.
386    pub this_update: Time,
387    /// When the next update will be available. The update may be available
388    /// sooner than `next_update`, but it will not be issued later.
389    pub next_update: Option<Time>,
390    /// The list of revoked certificates.
391    pub revoked_certificates: SequenceOf<RevokedCertificate>,
392    /// Extensions to the list.
393    #[rasn(tag(explicit(0)))]
394    pub crl_extensions: Option<Extensions>,
395}
396
397/// Identifies a revoked certificate.
398#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
399pub struct RevokedCertificate {
400    /// The ID of the certificate being revoked.
401    pub user_certificate: CertificateSerialNumber,
402    /// When the certificate was revoked.
403    pub revocation_date: Time,
404    /// Extensions to the revoked entry.
405    pub crl_entry_extensions: Option<Extensions>,
406}
407
408/// Identifies what algorithm was used, along with any parameters used as input.
409#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
410pub struct AlgorithmIdentifier {
411    /// The identifier for the algorithm.
412    pub algorithm: ObjectIdentifier,
413    /// Parameters for the algorithm, if any.
414    pub parameters: Option<Any>,
415}
416
417#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
418pub struct OrAddress {
419    pub built_in_standard_attributes: BuiltInStandardAttributes,
420    pub built_in_domain_defined_attributes: Option<BuiltInDomainDefinedAttributes>,
421    pub extension_attributes: Option<ExtensionAttributes>,
422}
423
424#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
425pub struct BuiltInStandardAttributes {
426    pub country_name: Option<CountryName>,
427    pub administraion_domain_name: Option<AdministrationDomainName>,
428    #[rasn(tag(0))]
429    pub network_address: Option<NetworkAddress>,
430    #[rasn(tag(1))]
431    pub terminal_identifier: Option<TerminalIdentifier>,
432    #[rasn(tag(2))]
433    pub private_domain_name: Option<PrivateDomainName>,
434    #[rasn(tag(3))]
435    pub organisation_name: Option<OrganisationName>,
436    #[rasn(tag(4))]
437    pub numeric_user_identifier: Option<NumericUserIdentifier>,
438    #[rasn(tag(5))]
439    pub personal_name: Option<PersonalName>,
440    #[rasn(tag(6))]
441    pub organisational_unit_name: Option<OrganisationalUnitNames>,
442}
443
444#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
445#[rasn(delegate, size("1..=4"))]
446pub struct BuiltInDomainDefinedAttributes(SequenceOf<BuiltInDomainDefinedAttribute>);
447derefable!(
448    BuiltInDomainDefinedAttributes,
449    SequenceOf<BuiltInDomainDefinedAttribute>
450);
451
452#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
453pub struct BuiltInDomainDefinedAttribute {
454    #[rasn(size("1..=8"))]
455    pub r#type: PrintableString,
456    #[rasn(size("1..=128"))]
457    pub value: PrintableString,
458}
459
460#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
461#[rasn(tag(explicit(application, 1)))]
462#[rasn(choice)]
463pub enum CountryName {
464    #[rasn(size(3))]
465    X121DccCode(NumericString),
466    #[rasn(size(2))]
467    Iso3166Alpha2Code(PrintableString),
468}
469
470#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
471#[rasn(choice)]
472pub enum PrivateDomainName {
473    #[rasn(size("1..=16"))]
474    Numeric(NumericString),
475    #[rasn(size("1..=16"))]
476    Printable(PrintableString),
477}
478
479#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
480#[rasn(tag(explicit(application, 2)), choice)]
481pub enum AdministrationDomainName {
482    #[rasn(size("0..=16"))]
483    Numeric(NumericString),
484    #[rasn(size("0..=16"))]
485    Printable(PrintableString),
486}
487
488#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
489#[rasn(set)]
490pub struct PersonalName {
491    #[rasn(tag(0))]
492    pub surname: PrintableString,
493    #[rasn(tag(1))]
494    pub given_name: Option<PrintableString>,
495    #[rasn(tag(2))]
496    pub initials: Option<PrintableString>,
497    #[rasn(tag(3))]
498    pub generation_qualifier: Option<PrintableString>,
499}
500
501#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
502#[rasn(delegate, size("1..=4"))]
503pub struct OrganisationalUnitNames(SequenceOf<OrganisationalUnitName>);
504derefable!(OrganisationalUnitNames, SequenceOf<OrganisationalUnitName>);
505
506#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
507#[rasn(delegate, size("1..=32"))]
508pub struct OrganisationalUnitName(PrintableString);
509derefable!(OrganisationalUnitName, PrintableString);
510
511#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
512#[rasn(delegate, size("1.."))]
513pub struct Extensions(SequenceOf<Extension>);
514derefable!(Extensions, SequenceOf<Extension>);
515
516#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
517#[rasn(delegate, size("1.."))]
518pub struct RelativeDistinguishedName(SetOf<AttributeTypeAndValue>);
519derefable!(RelativeDistinguishedName, SetOf<AttributeTypeAndValue>);
520
521#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
522#[rasn(delegate, size("1..=256"))]
523pub struct ExtensionAttributes(SetOf<ExtensionAttribute>);
524derefable!(ExtensionAttributes, SetOf<ExtensionAttribute>);
525
526#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
527pub struct ExtensionAttribute {
528    #[rasn(tag(0), value("0..=256"))]
529    pub extension_attribute_type: u16,
530    #[rasn(tag(1))]
531    pub extension_attribute_value: Any,
532}
533
534#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
535#[rasn(set)]
536pub struct TeletexPersonalName {
537    #[rasn(tag(0), size("1..=40"))]
538    pub surname: TeletexString,
539    #[rasn(tag(1), size("1..=16"))]
540    pub given_name: Option<TeletexString>,
541    #[rasn(tag(2), size("1..=5"))]
542    pub initials: Option<TeletexString>,
543    #[rasn(tag(3), size("1..=3"))]
544    pub generation_qualifier: Option<TeletexString>,
545}
546
547#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
548#[rasn(choice)]
549pub enum PhysicalDeliveryCountryName {
550    #[rasn(size(3))]
551    X121DccCode(NumericString),
552    #[rasn(size(2))]
553    Iso3166Alpha2Code(PrintableString),
554}
555
556#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
557#[rasn(choice)]
558pub enum PostalCode {
559    #[rasn(size("1..=16"))]
560    Numeric(NumericString),
561    #[rasn(size("1..=16"))]
562    Printable(PrintableString),
563}
564
565#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
566#[rasn(delegate, size("1..=64"))]
567pub struct CommonName(PrintableString);
568derefable!(CommonName, PrintableString);
569
570#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
571#[rasn(delegate, size("1..=64"))]
572pub struct TeletexCommonName(TeletexString);
573derefable!(TeletexCommonName, TeletexString);
574
575#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
576#[rasn(delegate, size("1..=64"))]
577pub struct TeletexOrganizationName(TeletexString);
578derefable!(TeletexOrganizationName, TeletexString);
579
580#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
581#[rasn(delegate, size("1..=4"))]
582pub struct TeletexOrganisationalUnitNames(SequenceOf<TeletexOrganisationalUnitName>);
583derefable!(
584    TeletexOrganisationalUnitNames,
585    SequenceOf<TeletexOrganisationalUnitName>
586);
587
588#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
589#[rasn(delegate, size("1..=32"))]
590pub struct TeletexOrganisationalUnitName(TeletexString);
591derefable!(TeletexOrganisationalUnitName, TeletexString);
592
593#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
594#[rasn(delegate, size("1..=16"))]
595pub struct PdsName(PrintableString);
596derefable!(PdsName, PrintableString);
597
598#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
599#[rasn(delegate, size("1..=30"))]
600pub struct PrintableAddress(PrintableString);
601derefable!(PrintableAddress, PrintableString);
602
603#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
604#[rasn(delegate, size("1..=180"))]
605pub struct TeletexAddress(TeletexString);
606derefable!(TeletexAddress, TeletexString);
607
608#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
609#[rasn(set)]
610pub struct UnformattedPostalAddress {
611    #[rasn(size("1..=6"))]
612    pub printable_address: Option<SequenceOf<PrintableAddress>>,
613    pub teletex_string: Option<TeletexAddress>,
614}
615
616#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
617#[rasn(set)]
618pub struct PdsParameter {
619    #[rasn(size("1..=30"))]
620    pub printable_string: Option<PrintableString>,
621    #[rasn(size("1..=30"))]
622    pub teletex_string: Option<TeletexString>,
623}
624
625#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
626#[rasn(choice)]
627pub enum ExtendedNetworkAddress {
628    E1634Address(E1634Address),
629    #[rasn(tag(0))]
630    PsapAddress(PresentationAddress),
631}
632
633#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
634pub struct E1634Address {
635    #[rasn(tag(0), size("1..=15"))]
636    pub number: NumericString,
637    #[rasn(tag(1), size("1..=40"))]
638    pub sub_address: Option<NumericString>,
639}
640
641#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
642pub struct PresentationAddress {
643    #[rasn(tag(explicit(0)))]
644    pub p_selector: Option<OctetString>,
645    #[rasn(tag(explicit(1)))]
646    pub s_selector: Option<OctetString>,
647    #[rasn(tag(explicit(2)))]
648    pub t_selector: Option<OctetString>,
649    #[rasn(tag(explicit(3)), size("1.."))]
650    pub n_addresses: SetOf<OctetString>,
651}
652
653#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
654#[rasn(delegate, size("1..=4"))]
655pub struct TeletexDomainDefinedAttributes(SequenceOf<TeletexDomainDefinedAttribute>);
656
657#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
658pub struct TeletexDomainDefinedAttribute {
659    #[rasn(size("1..=8"))]
660    pub r#type: TeletexString,
661    #[rasn(size("1..=128"))]
662    pub value: TeletexString,
663}
664
665#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
666#[rasn(choice)]
667pub enum Name {
668    RdnSequence(RdnSequence),
669}
670
671#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
672pub struct Attribute {
673    pub r#type: AttributeType,
674    pub values: SetOf<AttributeValue>,
675}
676
677#[derive(AsnType, Clone, Debug, Decode, Encode, PartialOrd, Ord, PartialEq, Eq, Hash)]
678pub struct AttributeTypeAndValue {
679    pub r#type: AttributeType,
680    pub value: AttributeValue,
681}
682
683#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
684pub struct PolicyInformation {
685    pub policy_identifier: CertPolicyId,
686    pub policy_qualifiers: Option<SequenceOf<PolicyQualifierInfo>>,
687}
688
689#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
690pub struct PolicyQualifierInfo {
691    pub id: PolicyQualifierId,
692    pub qualifier: Any,
693}
694
695#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
696pub struct UserNotice {
697    pub notice_ref: Option<NoticeReference>,
698    pub explicit_text: Option<DisplayText>,
699}
700
701#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
702pub struct NoticeReference {
703    pub organisation: DisplayText,
704    pub notice_numbers: SequenceOf<Integer>,
705}
706
707#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
708#[rasn(choice)]
709pub enum DisplayText {
710    Ia5String(Ia5String),
711    VisibleString(VisibleString),
712    BmpString(BmpString),
713    Utf8String(Utf8String),
714}
715
716#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
717pub struct PolicyMapping {
718    pub issuer_domain_policy: CertPolicyId,
719    pub subject_domain_policy: CertPolicyId,
720}
721
722#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
723#[rasn(choice)]
724pub enum GeneralName {
725    #[rasn(tag(0))]
726    OtherName(InstanceOf<OctetString>),
727    #[rasn(tag(1))]
728    Rfc822Name(Ia5String),
729    #[rasn(tag(2))]
730    DnsName(Ia5String),
731    // Boxed because it's 368 bytes, and the next largest enum variant is 64.
732    #[rasn(tag(3))]
733    X400Address(alloc::boxed::Box<OrAddress>),
734    #[rasn(tag(4))]
735    DirectoryName(Name),
736    #[rasn(tag(5))]
737    EdiPartyName(EdiPartyName),
738    #[rasn(tag(6))]
739    Uri(Ia5String),
740    #[rasn(tag(7))]
741    IpAddress(OctetString),
742    #[rasn(tag(8))]
743    RegisteredId(ObjectIdentifier),
744}
745
746#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
747pub struct EdiPartyName {
748    #[rasn(tag(0))]
749    pub name_assigner: Option<DirectoryString>,
750    #[rasn(tag(1))]
751    pub party_name: DirectoryString,
752}
753
754#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
755#[rasn(delegate, size(2))]
756pub struct X520CountryName(PrintableString);
757derefable!(X520CountryName, PrintableString);
758
759#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
760#[rasn(delegate, size("1..=64"))]
761pub struct X520SerialNumber(PrintableString);
762derefable!(X520SerialNumber, PrintableString);
763
764#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
765#[rasn(choice)]
766pub enum X520StateOrProvinceName {
767    #[rasn(size("1..=128"))]
768    Teletex(TeletexString),
769    #[rasn(size("1..=128"))]
770    Printable(PrintableString),
771    #[rasn(size("1..=128"))]
772    Universal(UniversalString),
773    #[rasn(size("1..=128"))]
774    Utf8(Utf8String),
775    #[rasn(size("1..=128"))]
776    Bmp(BmpString),
777}
778
779#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
780#[rasn(choice)]
781pub enum X520OrganisationName {
782    #[rasn(size("1..=64"))]
783    Teletex(TeletexString),
784    #[rasn(size("1..=64"))]
785    Printable(PrintableString),
786    #[rasn(size("1..=64"))]
787    Universal(UniversalString),
788    #[rasn(size("1..=64"))]
789    Utf8(Utf8String),
790    #[rasn(size("1..=64"))]
791    Bmp(BmpString),
792}
793
794#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
795#[rasn(choice)]
796pub enum X520OrganisationalUnitName {
797    #[rasn(size("1..=64"))]
798    Teletex(TeletexString),
799    #[rasn(size("1..=64"))]
800    Printable(PrintableString),
801    #[rasn(size("1..=64"))]
802    Universal(UniversalString),
803    #[rasn(size("1..=64"))]
804    Utf8(Utf8String),
805    #[rasn(size("1..=64"))]
806    Bmp(BmpString),
807}
808
809#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
810#[rasn(choice)]
811pub enum X520Title {
812    #[rasn(size("1..=64"))]
813    Teletex(TeletexString),
814    #[rasn(size("1..=64"))]
815    Printable(PrintableString),
816    #[rasn(size("1..=64"))]
817    Universal(UniversalString),
818    #[rasn(size("1..=64"))]
819    Utf8(Utf8String),
820    #[rasn(size("1..=64"))]
821    Bmp(BmpString),
822}
823
824#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
825#[rasn(choice)]
826pub enum X520Pseudonym {
827    #[rasn(size("1..=128"))]
828    Teletex(TeletexString),
829    #[rasn(size("1..=128"))]
830    Printable(PrintableString),
831    #[rasn(size("1..=128"))]
832    Universal(UniversalString),
833    #[rasn(size("1..=128"))]
834    Utf8(Utf8String),
835    #[rasn(size("1..=128"))]
836    Bmp(BmpString),
837}
838
839#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
840#[rasn(choice)]
841pub enum X520LocalityName {
842    #[rasn(size("1..=128"))]
843    Teletex(TeletexString),
844    #[rasn(size("1..=128"))]
845    Printable(PrintableString),
846    #[rasn(size("1..=128"))]
847    Universal(UniversalString),
848    #[rasn(size("1..=128"))]
849    Utf8(Utf8String),
850    #[rasn(size("1..=128"))]
851    Bmp(BmpString),
852}
853
854#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
855#[rasn(choice)]
856pub enum X520Name {
857    #[rasn(size("1..=32768"))]
858    Teletex(TeletexString),
859    #[rasn(size("1..=32768"))]
860    Printable(PrintableString),
861    #[rasn(size("1..=32768"))]
862    Universal(UniversalString),
863    #[rasn(size("1..=32768"))]
864    Utf8(Utf8String),
865    #[rasn(size("1..=32768"))]
866    Bmp(BmpString),
867}
868
869#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
870#[rasn(choice)]
871pub enum X520CommonName {
872    #[rasn(size("1..=64"))]
873    Teletex(TeletexString),
874    #[rasn(size("1..=64"))]
875    Printable(PrintableString),
876    #[rasn(size("1..=64"))]
877    Universal(UniversalString),
878    #[rasn(size("1..=64"))]
879    Utf8(Utf8String),
880    #[rasn(size("1..=64"))]
881    Bmp(BmpString),
882}
883
884macro_rules! directory_string_compat {
885    ($($from:ident),+ $(,)?) => {
886        $(
887            impl PartialEq<$from> for DirectoryString {
888                fn eq(&self, rhs: &$from) -> bool {
889                    match (rhs, self) {
890                        ($from::Teletex(lhs), Self::Teletex(rhs)) => lhs == rhs,
891                        ($from::Printable(lhs), Self::Printable(rhs)) => lhs == rhs,
892                        ($from::Universal(lhs), Self::Universal(rhs)) => lhs == rhs,
893                        ($from::Utf8(lhs), Self::Utf8(rhs)) => lhs == rhs,
894                        ($from::Bmp(lhs), Self::Bmp(rhs)) => lhs == rhs,
895                        _ => false,
896                    }
897                }
898            }
899
900            impl From<$from> for DirectoryString {
901                fn from(value: $from) -> Self {
902                    match value {
903                        $from::Teletex(value) => Self::Teletex(value),
904                        $from::Printable(value) => Self::Printable(value),
905                        $from::Universal(value) => Self::Universal(value),
906                        $from::Utf8(value) => Self::Utf8(value),
907                        $from::Bmp(value) => Self::Bmp(value),
908                    }
909                }
910            }
911        )+
912    }
913}
914
915directory_string_compat! {
916    X520Name,
917    X520CommonName,
918    X520LocalityName,
919    X520Pseudonym,
920    X520Title,
921    X520OrganisationalUnitName,
922    X520OrganisationName,
923    X520StateOrProvinceName,
924}
925
926#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
927#[rasn(choice)]
928pub enum DirectoryString {
929    #[rasn(size("1.."))]
930    Teletex(TeletexString),
931    #[rasn(size("1.."))]
932    Printable(PrintableString),
933    #[rasn(size("1.."))]
934    Universal(UniversalString),
935    #[rasn(size("1.."))]
936    Utf8(Utf8String),
937    #[rasn(size("1.."))]
938    Bmp(BmpString),
939}
940
941#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
942pub struct BasicConstraints {
943    #[rasn(default)]
944    pub ca: bool,
945    pub path_len_constraint: Option<Integer>,
946}
947
948#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
949pub struct NameConstraints {
950    #[rasn(tag(0))]
951    pub permitted_subtrees: Option<GeneralSubtrees>,
952    #[rasn(tag(1))]
953    pub excluded_subtrees: Option<GeneralSubtrees>,
954}
955
956#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
957pub struct GeneralSubtree {
958    pub base: GeneralName,
959    #[rasn(tag(0), default)]
960    pub minimum: BaseDistance,
961    #[rasn(tag(1))]
962    pub maximum: Option<BaseDistance>,
963}
964
965#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
966pub struct PolicyConstraints {
967    #[rasn(tag(0))]
968    pub require_explicit_policy: Option<SkipCerts>,
969    #[rasn(tag(1))]
970    pub inhibit_policy_mapping: Option<SkipCerts>,
971}
972
973#[derive(AsnType, Clone, Debug, Default, Decode, Encode, PartialEq, Eq, Hash)]
974pub struct DistributionPoint {
975    #[rasn(tag(0))]
976    pub distribution_point: Option<DistributionPointName>,
977    #[rasn(tag(1))]
978    pub reasons: Option<ReasonFlags>,
979    #[rasn(tag(2))]
980    pub crl_issuer: Option<GeneralNames>,
981}
982
983#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
984#[rasn(choice)]
985pub enum DistributionPointName {
986    #[rasn(tag(0))]
987    FullName(GeneralNames),
988    #[rasn(tag(1))]
989    NameRelativeToCrlIssuer(RelativeDistinguishedName),
990}
991
992#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
993pub struct AccessDescription {
994    pub access_method: ObjectIdentifier,
995    pub access_location: GeneralName,
996}
997
998#[derive(AsnType, Clone, Copy, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
999#[rasn(enumerated)]
1000pub enum CrlReason {
1001    Unspecified = 0,
1002    KeyCompromise = 1,
1003    CaCompromise = 2,
1004    AffiliationChanged = 3,
1005    Superseded = 4,
1006    CessationOfOperation = 5,
1007    CertificateHold = 6,
1008    RemoveFromCRL = 8,
1009    PrivilegeWithdrawn = 9,
1010    AaCompromise = 10,
1011}
1012
1013#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
1014pub struct IssuingDistributionPoint {
1015    #[rasn(tag(0))]
1016    pub distribution_point: Option<DistributionPointName>,
1017    #[rasn(tag(1), default)]
1018    pub only_contains_user_certs: bool,
1019    #[rasn(tag(2), default)]
1020    pub only_contains_ca_certs: bool,
1021    #[rasn(tag(3))]
1022    pub only_some_reasons: Option<ReasonFlags>,
1023    #[rasn(tag(4), default)]
1024    pub indirect_crl: bool,
1025    #[rasn(tag(5), default)]
1026    pub only_contains_attribute_certs: bool,
1027}
1028
1029/** PrivateKeyUsagePeriod
1030
1031This certificate extensions was deprecated in
1032[RFC3280 4.2.1.4](https://www.rfc-editor.org/rfc/rfc3280#section-4.2.1.4) but
1033this was undone by
1034[RFC5280 1](https://www.rfc-editor.org/rfc/rfc5280#section-1).
1035
1036[RFC 5280 A.2](https://www.rfc-editor.org/rfc/rfc5280#appendix-A.2):
1037
1038```text
1039   -- private key usage period extension OID and syntax
1040
1041   id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::=  { id-ce 16 }
1042
1043   PrivateKeyUsagePeriod ::= SEQUENCE {
1044        notBefore       [0]     GeneralizedTime OPTIONAL,
1045        notAfter        [1]     GeneralizedTime OPTIONAL }
1046        -- either notBefore or notAfter MUST be present
1047```
1048*/
1049#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
1050pub struct PrivateKeyUsagePeriod {
1051    #[rasn(tag(0))]
1052    pub not_before: Option<GeneralizedTime>,
1053    #[rasn(tag(1))]
1054    pub not_after: Option<GeneralizedTime>,
1055}
1056
1057#[cfg(test)]
1058mod tests {
1059    extern crate alloc;
1060    use super::*;
1061
1062    #[test]
1063    fn time() {
1064        rasn::der::decode::<Time>(&[
1065            0x17, 0x0D, 0x31, 0x38, 0x30, 0x32, 0x30, 0x39, 0x31, 0x32, 0x33, 0x32, 0x30, 0x37,
1066            0x5A,
1067        ])
1068        .unwrap();
1069    }
1070
1071    #[test]
1072    fn algorithm_identifier() {
1073        let expected_de = AlgorithmIdentifier {
1074            algorithm: ObjectIdentifier::new_unchecked((&[1, 2, 840, 113549, 1, 1, 1][..]).into()),
1075            parameters: Some(Any::new(rasn::der::encode(&()).unwrap())),
1076        };
1077
1078        let expected_enc = &[
1079            0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05,
1080            0x00,
1081        ][..];
1082
1083        assert_eq!(expected_enc, rasn::der::encode(&expected_de).unwrap());
1084        assert_eq!(expected_de, rasn::der::decode(expected_enc).unwrap());
1085    }
1086
1087    #[test]
1088    fn certificate_policies() {
1089        let expected_de: CertificatePolicies = alloc::vec![
1090            PolicyInformation {
1091                policy_identifier: ObjectIdentifier::new_unchecked(
1092                    (&[2, 23, 140, 1, 2, 1][..]).into()
1093                ),
1094                policy_qualifiers: None,
1095            },
1096            PolicyInformation {
1097                policy_identifier: ObjectIdentifier::new_unchecked(
1098                    (&[1, 3, 6, 1, 4, 1, 44947, 1, 1, 1][..]).into()
1099                ),
1100                policy_qualifiers: Some(alloc::vec![PolicyQualifierInfo {
1101                    id: ObjectIdentifier::new_unchecked((&[1, 3, 6, 1, 5, 5, 7, 2, 1][..]).into()),
1102                    qualifier: Any::new(
1103                        rasn::der::encode(
1104                            &Ia5String::try_from(alloc::string::String::from(
1105                                "http://cps.root-x1.letsencrypt.org"
1106                            ))
1107                            .unwrap()
1108                        )
1109                        .unwrap()
1110                    ),
1111                }]),
1112            }
1113        ];
1114
1115        let expected_enc = &[
1116            0x30, 0x4B, 0x30, 0x08, 0x06, 0x06, 0x67, 0x81, 0x0C, 0x01, 0x02, 0x01, 0x30, 0x3F,
1117            0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xDF, 0x13, 0x01, 0x01, 0x01, 0x30,
1118            0x30, 0x30, 0x2E, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16,
1119            0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x63, 0x70, 0x73, 0x2E, 0x72, 0x6F,
1120            0x6F, 0x74, 0x2D, 0x78, 0x31, 0x2E, 0x6C, 0x65, 0x74, 0x73, 0x65, 0x6E, 0x63, 0x72,
1121            0x79, 0x70, 0x74, 0x2E, 0x6F, 0x72, 0x67,
1122        ][..];
1123
1124        assert_eq!(expected_enc, rasn::der::encode(&expected_de).unwrap());
1125        assert_eq!(
1126            expected_de,
1127            rasn::der::decode::<CertificatePolicies>(expected_enc).unwrap()
1128        );
1129    }
1130
1131    #[test]
1132    fn trust_anchor_info_version() {
1133        let alg_id = AlgorithmIdentifier {
1134            algorithm: ObjectIdentifier::new_unchecked((&[1, 2][..]).into()),
1135            parameters: None,
1136        };
1137
1138        let spki = SubjectPublicKeyInfo {
1139            algorithm: alg_id,
1140            subject_public_key: Default::default(),
1141        };
1142
1143        let tai = TrustAnchorInfo {
1144            version: Default::default(),
1145            pub_key: spki,
1146            key_id: Default::default(),
1147            ta_title: None,
1148            cert_path: None,
1149            exts: None,
1150            ta_title_lang_tag: None,
1151        };
1152
1153        let expected_enc = &[
1154            0x30, 0x0c, 0x30, 0x08, 0x30, 0x03, 0x06, 0x01, 0x2A, 0x03, 0x01, 0x00, 0x04, 0x00,
1155        ][..];
1156        let actual_enc = rasn::der::encode(&tai).unwrap();
1157
1158        assert_eq!(expected_enc, actual_enc);
1159        assert_eq!(TrustAnchorInfoVersion(1), tai.version);
1160    }
1161}