Skip to main content

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    #[rasn(default)]
392    pub revoked_certificates: SequenceOf<RevokedCertificate>,
393    /// Extensions to the list.
394    #[rasn(tag(explicit(0)))]
395    pub crl_extensions: Option<Extensions>,
396}
397
398/// Identifies a revoked certificate.
399#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
400pub struct RevokedCertificate {
401    /// The ID of the certificate being revoked.
402    pub user_certificate: CertificateSerialNumber,
403    /// When the certificate was revoked.
404    pub revocation_date: Time,
405    /// Extensions to the revoked entry.
406    pub crl_entry_extensions: Option<Extensions>,
407}
408
409/// Identifies what algorithm was used, along with any parameters used as input.
410#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
411pub struct AlgorithmIdentifier {
412    /// The identifier for the algorithm.
413    pub algorithm: ObjectIdentifier,
414    /// Parameters for the algorithm, if any.
415    pub parameters: Option<Any>,
416}
417
418#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
419pub struct OrAddress {
420    pub built_in_standard_attributes: BuiltInStandardAttributes,
421    pub built_in_domain_defined_attributes: Option<BuiltInDomainDefinedAttributes>,
422    pub extension_attributes: Option<ExtensionAttributes>,
423}
424
425#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
426pub struct BuiltInStandardAttributes {
427    pub country_name: Option<CountryName>,
428    pub administraion_domain_name: Option<AdministrationDomainName>,
429    #[rasn(tag(0))]
430    pub network_address: Option<NetworkAddress>,
431    #[rasn(tag(1))]
432    pub terminal_identifier: Option<TerminalIdentifier>,
433    #[rasn(tag(2))]
434    pub private_domain_name: Option<PrivateDomainName>,
435    #[rasn(tag(3))]
436    pub organisation_name: Option<OrganisationName>,
437    #[rasn(tag(4))]
438    pub numeric_user_identifier: Option<NumericUserIdentifier>,
439    #[rasn(tag(5))]
440    pub personal_name: Option<PersonalName>,
441    #[rasn(tag(6))]
442    pub organisational_unit_name: Option<OrganisationalUnitNames>,
443}
444
445#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
446#[rasn(delegate, size("1..=4"))]
447pub struct BuiltInDomainDefinedAttributes(SequenceOf<BuiltInDomainDefinedAttribute>);
448derefable!(
449    BuiltInDomainDefinedAttributes,
450    SequenceOf<BuiltInDomainDefinedAttribute>
451);
452
453#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
454pub struct BuiltInDomainDefinedAttribute {
455    #[rasn(size("1..=8"))]
456    pub r#type: PrintableString,
457    #[rasn(size("1..=128"))]
458    pub value: PrintableString,
459}
460
461#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
462#[rasn(tag(explicit(application, 1)))]
463#[rasn(choice)]
464pub enum CountryName {
465    #[rasn(size(3))]
466    X121DccCode(NumericString),
467    #[rasn(size(2))]
468    Iso3166Alpha2Code(PrintableString),
469}
470
471#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
472#[rasn(choice)]
473pub enum PrivateDomainName {
474    #[rasn(size("1..=16"))]
475    Numeric(NumericString),
476    #[rasn(size("1..=16"))]
477    Printable(PrintableString),
478}
479
480#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
481#[rasn(tag(explicit(application, 2)), choice)]
482pub enum AdministrationDomainName {
483    #[rasn(size("0..=16"))]
484    Numeric(NumericString),
485    #[rasn(size("0..=16"))]
486    Printable(PrintableString),
487}
488
489#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
490#[rasn(set)]
491pub struct PersonalName {
492    #[rasn(tag(0))]
493    pub surname: PrintableString,
494    #[rasn(tag(1))]
495    pub given_name: Option<PrintableString>,
496    #[rasn(tag(2))]
497    pub initials: Option<PrintableString>,
498    #[rasn(tag(3))]
499    pub generation_qualifier: Option<PrintableString>,
500}
501
502#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
503#[rasn(delegate, size("1..=4"))]
504pub struct OrganisationalUnitNames(SequenceOf<OrganisationalUnitName>);
505derefable!(OrganisationalUnitNames, SequenceOf<OrganisationalUnitName>);
506
507#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
508#[rasn(delegate, size("1..=32"))]
509pub struct OrganisationalUnitName(PrintableString);
510derefable!(OrganisationalUnitName, PrintableString);
511
512#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
513#[rasn(delegate, size("1.."))]
514pub struct Extensions(SequenceOf<Extension>);
515derefable!(Extensions, SequenceOf<Extension>);
516
517#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
518#[rasn(delegate, size("1.."))]
519pub struct RelativeDistinguishedName(SetOf<AttributeTypeAndValue>);
520derefable!(RelativeDistinguishedName, SetOf<AttributeTypeAndValue>);
521
522#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
523#[rasn(delegate, size("1..=256"))]
524pub struct ExtensionAttributes(SetOf<ExtensionAttribute>);
525derefable!(ExtensionAttributes, SetOf<ExtensionAttribute>);
526
527#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
528pub struct ExtensionAttribute {
529    #[rasn(tag(0), value("0..=256"))]
530    pub extension_attribute_type: u16,
531    #[rasn(tag(1))]
532    pub extension_attribute_value: Any,
533}
534
535#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
536#[rasn(set)]
537pub struct TeletexPersonalName {
538    #[rasn(tag(0), size("1..=40"))]
539    pub surname: TeletexString,
540    #[rasn(tag(1), size("1..=16"))]
541    pub given_name: Option<TeletexString>,
542    #[rasn(tag(2), size("1..=5"))]
543    pub initials: Option<TeletexString>,
544    #[rasn(tag(3), size("1..=3"))]
545    pub generation_qualifier: Option<TeletexString>,
546}
547
548#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
549#[rasn(choice)]
550pub enum PhysicalDeliveryCountryName {
551    #[rasn(size(3))]
552    X121DccCode(NumericString),
553    #[rasn(size(2))]
554    Iso3166Alpha2Code(PrintableString),
555}
556
557#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
558#[rasn(choice)]
559pub enum PostalCode {
560    #[rasn(size("1..=16"))]
561    Numeric(NumericString),
562    #[rasn(size("1..=16"))]
563    Printable(PrintableString),
564}
565
566#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
567#[rasn(delegate, size("1..=64"))]
568pub struct CommonName(PrintableString);
569derefable!(CommonName, PrintableString);
570
571#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
572#[rasn(delegate, size("1..=64"))]
573pub struct TeletexCommonName(TeletexString);
574derefable!(TeletexCommonName, TeletexString);
575
576#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
577#[rasn(delegate, size("1..=64"))]
578pub struct TeletexOrganizationName(TeletexString);
579derefable!(TeletexOrganizationName, TeletexString);
580
581#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
582#[rasn(delegate, size("1..=4"))]
583pub struct TeletexOrganisationalUnitNames(SequenceOf<TeletexOrganisationalUnitName>);
584derefable!(
585    TeletexOrganisationalUnitNames,
586    SequenceOf<TeletexOrganisationalUnitName>
587);
588
589#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
590#[rasn(delegate, size("1..=32"))]
591pub struct TeletexOrganisationalUnitName(TeletexString);
592derefable!(TeletexOrganisationalUnitName, TeletexString);
593
594#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
595#[rasn(delegate, size("1..=16"))]
596pub struct PdsName(PrintableString);
597derefable!(PdsName, PrintableString);
598
599#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
600#[rasn(delegate, size("1..=30"))]
601pub struct PrintableAddress(PrintableString);
602derefable!(PrintableAddress, PrintableString);
603
604#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
605#[rasn(delegate, size("1..=180"))]
606pub struct TeletexAddress(TeletexString);
607derefable!(TeletexAddress, TeletexString);
608
609#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
610#[rasn(set)]
611pub struct UnformattedPostalAddress {
612    #[rasn(size("1..=6"))]
613    pub printable_address: Option<SequenceOf<PrintableAddress>>,
614    pub teletex_string: Option<TeletexAddress>,
615}
616
617#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
618#[rasn(set)]
619pub struct PdsParameter {
620    #[rasn(size("1..=30"))]
621    pub printable_string: Option<PrintableString>,
622    #[rasn(size("1..=30"))]
623    pub teletex_string: Option<TeletexString>,
624}
625
626#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
627#[rasn(choice)]
628pub enum ExtendedNetworkAddress {
629    E1634Address(E1634Address),
630    #[rasn(tag(0))]
631    PsapAddress(PresentationAddress),
632}
633
634#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
635pub struct E1634Address {
636    #[rasn(tag(0), size("1..=15"))]
637    pub number: NumericString,
638    #[rasn(tag(1), size("1..=40"))]
639    pub sub_address: Option<NumericString>,
640}
641
642#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
643pub struct PresentationAddress {
644    #[rasn(tag(explicit(0)))]
645    pub p_selector: Option<OctetString>,
646    #[rasn(tag(explicit(1)))]
647    pub s_selector: Option<OctetString>,
648    #[rasn(tag(explicit(2)))]
649    pub t_selector: Option<OctetString>,
650    #[rasn(tag(explicit(3)), size("1.."))]
651    pub n_addresses: SetOf<OctetString>,
652}
653
654#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
655#[rasn(delegate, size("1..=4"))]
656pub struct TeletexDomainDefinedAttributes(SequenceOf<TeletexDomainDefinedAttribute>);
657
658#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
659pub struct TeletexDomainDefinedAttribute {
660    #[rasn(size("1..=8"))]
661    pub r#type: TeletexString,
662    #[rasn(size("1..=128"))]
663    pub value: TeletexString,
664}
665
666#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
667#[rasn(choice)]
668pub enum Name {
669    RdnSequence(RdnSequence),
670}
671
672#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
673pub struct Attribute {
674    pub r#type: AttributeType,
675    pub values: SetOf<AttributeValue>,
676}
677
678#[derive(AsnType, Clone, Debug, Decode, Encode, PartialOrd, Ord, PartialEq, Eq, Hash)]
679pub struct AttributeTypeAndValue {
680    pub r#type: AttributeType,
681    pub value: AttributeValue,
682}
683
684#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
685pub struct PolicyInformation {
686    pub policy_identifier: CertPolicyId,
687    pub policy_qualifiers: Option<SequenceOf<PolicyQualifierInfo>>,
688}
689
690#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
691pub struct PolicyQualifierInfo {
692    pub id: PolicyQualifierId,
693    pub qualifier: Any,
694}
695
696#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
697pub struct UserNotice {
698    pub notice_ref: Option<NoticeReference>,
699    pub explicit_text: Option<DisplayText>,
700}
701
702#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
703pub struct NoticeReference {
704    pub organisation: DisplayText,
705    pub notice_numbers: SequenceOf<Integer>,
706}
707
708#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
709#[rasn(choice)]
710pub enum DisplayText {
711    Ia5String(Ia5String),
712    VisibleString(VisibleString),
713    BmpString(BmpString),
714    Utf8String(Utf8String),
715}
716
717#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
718pub struct PolicyMapping {
719    pub issuer_domain_policy: CertPolicyId,
720    pub subject_domain_policy: CertPolicyId,
721}
722
723#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
724#[rasn(choice)]
725pub enum GeneralName {
726    #[rasn(tag(0))]
727    OtherName(InstanceOf<OctetString>),
728    #[rasn(tag(1))]
729    Rfc822Name(Ia5String),
730    #[rasn(tag(2))]
731    DnsName(Ia5String),
732    // Boxed because it's 368 bytes, and the next largest enum variant is 64.
733    #[rasn(tag(3))]
734    X400Address(alloc::boxed::Box<OrAddress>),
735    #[rasn(tag(4))]
736    DirectoryName(Name),
737    #[rasn(tag(5))]
738    EdiPartyName(EdiPartyName),
739    #[rasn(tag(6))]
740    Uri(Ia5String),
741    #[rasn(tag(7))]
742    IpAddress(OctetString),
743    #[rasn(tag(8))]
744    RegisteredId(ObjectIdentifier),
745}
746
747#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
748pub struct EdiPartyName {
749    #[rasn(tag(0))]
750    pub name_assigner: Option<DirectoryString>,
751    #[rasn(tag(1))]
752    pub party_name: DirectoryString,
753}
754
755#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
756#[rasn(delegate, size(2))]
757pub struct X520CountryName(PrintableString);
758derefable!(X520CountryName, PrintableString);
759
760#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
761#[rasn(delegate, size("1..=64"))]
762pub struct X520SerialNumber(PrintableString);
763derefable!(X520SerialNumber, PrintableString);
764
765#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
766#[rasn(choice)]
767pub enum X520StateOrProvinceName {
768    #[rasn(size("1..=128"))]
769    Teletex(TeletexString),
770    #[rasn(size("1..=128"))]
771    Printable(PrintableString),
772    #[rasn(size("1..=128"))]
773    Universal(UniversalString),
774    #[rasn(size("1..=128"))]
775    Utf8(Utf8String),
776    #[rasn(size("1..=128"))]
777    Bmp(BmpString),
778}
779
780#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
781#[rasn(choice)]
782pub enum X520OrganisationName {
783    #[rasn(size("1..=64"))]
784    Teletex(TeletexString),
785    #[rasn(size("1..=64"))]
786    Printable(PrintableString),
787    #[rasn(size("1..=64"))]
788    Universal(UniversalString),
789    #[rasn(size("1..=64"))]
790    Utf8(Utf8String),
791    #[rasn(size("1..=64"))]
792    Bmp(BmpString),
793}
794
795#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
796#[rasn(choice)]
797pub enum X520OrganisationalUnitName {
798    #[rasn(size("1..=64"))]
799    Teletex(TeletexString),
800    #[rasn(size("1..=64"))]
801    Printable(PrintableString),
802    #[rasn(size("1..=64"))]
803    Universal(UniversalString),
804    #[rasn(size("1..=64"))]
805    Utf8(Utf8String),
806    #[rasn(size("1..=64"))]
807    Bmp(BmpString),
808}
809
810#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
811#[rasn(choice)]
812pub enum X520Title {
813    #[rasn(size("1..=64"))]
814    Teletex(TeletexString),
815    #[rasn(size("1..=64"))]
816    Printable(PrintableString),
817    #[rasn(size("1..=64"))]
818    Universal(UniversalString),
819    #[rasn(size("1..=64"))]
820    Utf8(Utf8String),
821    #[rasn(size("1..=64"))]
822    Bmp(BmpString),
823}
824
825#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
826#[rasn(choice)]
827pub enum X520Pseudonym {
828    #[rasn(size("1..=128"))]
829    Teletex(TeletexString),
830    #[rasn(size("1..=128"))]
831    Printable(PrintableString),
832    #[rasn(size("1..=128"))]
833    Universal(UniversalString),
834    #[rasn(size("1..=128"))]
835    Utf8(Utf8String),
836    #[rasn(size("1..=128"))]
837    Bmp(BmpString),
838}
839
840#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
841#[rasn(choice)]
842pub enum X520LocalityName {
843    #[rasn(size("1..=128"))]
844    Teletex(TeletexString),
845    #[rasn(size("1..=128"))]
846    Printable(PrintableString),
847    #[rasn(size("1..=128"))]
848    Universal(UniversalString),
849    #[rasn(size("1..=128"))]
850    Utf8(Utf8String),
851    #[rasn(size("1..=128"))]
852    Bmp(BmpString),
853}
854
855#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
856#[rasn(choice)]
857pub enum X520Name {
858    #[rasn(size("1..=32768"))]
859    Teletex(TeletexString),
860    #[rasn(size("1..=32768"))]
861    Printable(PrintableString),
862    #[rasn(size("1..=32768"))]
863    Universal(UniversalString),
864    #[rasn(size("1..=32768"))]
865    Utf8(Utf8String),
866    #[rasn(size("1..=32768"))]
867    Bmp(BmpString),
868}
869
870#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
871#[rasn(choice)]
872pub enum X520CommonName {
873    #[rasn(size("1..=64"))]
874    Teletex(TeletexString),
875    #[rasn(size("1..=64"))]
876    Printable(PrintableString),
877    #[rasn(size("1..=64"))]
878    Universal(UniversalString),
879    #[rasn(size("1..=64"))]
880    Utf8(Utf8String),
881    #[rasn(size("1..=64"))]
882    Bmp(BmpString),
883}
884
885macro_rules! directory_string_compat {
886    ($($from:ident),+ $(,)?) => {
887        $(
888            impl PartialEq<$from> for DirectoryString {
889                fn eq(&self, rhs: &$from) -> bool {
890                    match (rhs, self) {
891                        ($from::Teletex(lhs), Self::Teletex(rhs)) => lhs == rhs,
892                        ($from::Printable(lhs), Self::Printable(rhs)) => lhs == rhs,
893                        ($from::Universal(lhs), Self::Universal(rhs)) => lhs == rhs,
894                        ($from::Utf8(lhs), Self::Utf8(rhs)) => lhs == rhs,
895                        ($from::Bmp(lhs), Self::Bmp(rhs)) => lhs == rhs,
896                        _ => false,
897                    }
898                }
899            }
900
901            impl From<$from> for DirectoryString {
902                fn from(value: $from) -> Self {
903                    match value {
904                        $from::Teletex(value) => Self::Teletex(value),
905                        $from::Printable(value) => Self::Printable(value),
906                        $from::Universal(value) => Self::Universal(value),
907                        $from::Utf8(value) => Self::Utf8(value),
908                        $from::Bmp(value) => Self::Bmp(value),
909                    }
910                }
911            }
912        )+
913    }
914}
915
916directory_string_compat! {
917    X520Name,
918    X520CommonName,
919    X520LocalityName,
920    X520Pseudonym,
921    X520Title,
922    X520OrganisationalUnitName,
923    X520OrganisationName,
924    X520StateOrProvinceName,
925}
926
927#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
928#[rasn(choice)]
929pub enum DirectoryString {
930    #[rasn(size("1.."))]
931    Teletex(TeletexString),
932    #[rasn(size("1.."))]
933    Printable(PrintableString),
934    #[rasn(size("1.."))]
935    Universal(UniversalString),
936    #[rasn(size("1.."))]
937    Utf8(Utf8String),
938    #[rasn(size("1.."))]
939    Bmp(BmpString),
940}
941
942#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
943pub struct BasicConstraints {
944    #[rasn(default)]
945    pub ca: bool,
946    pub path_len_constraint: Option<Integer>,
947}
948
949#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
950pub struct NameConstraints {
951    #[rasn(tag(0))]
952    pub permitted_subtrees: Option<GeneralSubtrees>,
953    #[rasn(tag(1))]
954    pub excluded_subtrees: Option<GeneralSubtrees>,
955}
956
957#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
958pub struct GeneralSubtree {
959    pub base: GeneralName,
960    #[rasn(tag(0), default)]
961    pub minimum: BaseDistance,
962    #[rasn(tag(1))]
963    pub maximum: Option<BaseDistance>,
964}
965
966#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
967pub struct PolicyConstraints {
968    #[rasn(tag(0))]
969    pub require_explicit_policy: Option<SkipCerts>,
970    #[rasn(tag(1))]
971    pub inhibit_policy_mapping: Option<SkipCerts>,
972}
973
974#[derive(AsnType, Clone, Debug, Default, Decode, Encode, PartialEq, Eq, Hash)]
975pub struct DistributionPoint {
976    #[rasn(tag(0))]
977    pub distribution_point: Option<DistributionPointName>,
978    #[rasn(tag(1))]
979    pub reasons: Option<ReasonFlags>,
980    #[rasn(tag(2))]
981    pub crl_issuer: Option<GeneralNames>,
982}
983
984#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
985#[rasn(choice)]
986pub enum DistributionPointName {
987    #[rasn(tag(0))]
988    FullName(GeneralNames),
989    #[rasn(tag(1))]
990    NameRelativeToCrlIssuer(RelativeDistinguishedName),
991}
992
993#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
994pub struct AccessDescription {
995    pub access_method: ObjectIdentifier,
996    pub access_location: GeneralName,
997}
998
999#[derive(AsnType, Clone, Copy, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
1000#[rasn(enumerated)]
1001pub enum CrlReason {
1002    Unspecified = 0,
1003    KeyCompromise = 1,
1004    CaCompromise = 2,
1005    AffiliationChanged = 3,
1006    Superseded = 4,
1007    CessationOfOperation = 5,
1008    CertificateHold = 6,
1009    RemoveFromCRL = 8,
1010    PrivilegeWithdrawn = 9,
1011    AaCompromise = 10,
1012}
1013
1014#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
1015pub struct IssuingDistributionPoint {
1016    #[rasn(tag(0))]
1017    pub distribution_point: Option<DistributionPointName>,
1018    #[rasn(tag(1), default)]
1019    pub only_contains_user_certs: bool,
1020    #[rasn(tag(2), default)]
1021    pub only_contains_ca_certs: bool,
1022    #[rasn(tag(3))]
1023    pub only_some_reasons: Option<ReasonFlags>,
1024    #[rasn(tag(4), default)]
1025    pub indirect_crl: bool,
1026    #[rasn(tag(5), default)]
1027    pub only_contains_attribute_certs: bool,
1028}
1029
1030/** PrivateKeyUsagePeriod
1031
1032This certificate extensions was deprecated in
1033[RFC3280 4.2.1.4](https://www.rfc-editor.org/rfc/rfc3280#section-4.2.1.4) but
1034this was undone by
1035[RFC5280 1](https://www.rfc-editor.org/rfc/rfc5280#section-1).
1036
1037[RFC 5280 A.2](https://www.rfc-editor.org/rfc/rfc5280#appendix-A.2):
1038
1039```text
1040   -- private key usage period extension OID and syntax
1041
1042   id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::=  { id-ce 16 }
1043
1044   PrivateKeyUsagePeriod ::= SEQUENCE {
1045        notBefore       [0]     GeneralizedTime OPTIONAL,
1046        notAfter        [1]     GeneralizedTime OPTIONAL }
1047        -- either notBefore or notAfter MUST be present
1048```
1049*/
1050#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
1051pub struct PrivateKeyUsagePeriod {
1052    #[rasn(tag(0))]
1053    pub not_before: Option<GeneralizedTime>,
1054    #[rasn(tag(1))]
1055    pub not_after: Option<GeneralizedTime>,
1056}
1057
1058#[cfg(test)]
1059mod tests {
1060    extern crate alloc;
1061    use super::*;
1062
1063    #[test]
1064    fn time() {
1065        rasn::der::decode::<Time>(&[
1066            0x17, 0x0D, 0x31, 0x38, 0x30, 0x32, 0x30, 0x39, 0x31, 0x32, 0x33, 0x32, 0x30, 0x37,
1067            0x5A,
1068        ])
1069        .unwrap();
1070    }
1071
1072    #[test]
1073    fn algorithm_identifier() {
1074        let expected_de = AlgorithmIdentifier {
1075            algorithm: ObjectIdentifier::new_unchecked((&[1, 2, 840, 113549, 1, 1, 1][..]).into()),
1076            parameters: Some(Any::new(rasn::der::encode(&()).unwrap())),
1077        };
1078
1079        let expected_enc = &[
1080            0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05,
1081            0x00,
1082        ][..];
1083
1084        assert_eq!(expected_enc, rasn::der::encode(&expected_de).unwrap());
1085        assert_eq!(expected_de, rasn::der::decode(expected_enc).unwrap());
1086    }
1087
1088    #[test]
1089    fn certificate_policies() {
1090        let expected_de: CertificatePolicies = alloc::vec![
1091            PolicyInformation {
1092                policy_identifier: ObjectIdentifier::new_unchecked(
1093                    (&[2, 23, 140, 1, 2, 1][..]).into()
1094                ),
1095                policy_qualifiers: None,
1096            },
1097            PolicyInformation {
1098                policy_identifier: ObjectIdentifier::new_unchecked(
1099                    (&[1, 3, 6, 1, 4, 1, 44947, 1, 1, 1][..]).into()
1100                ),
1101                policy_qualifiers: Some(alloc::vec![PolicyQualifierInfo {
1102                    id: ObjectIdentifier::new_unchecked((&[1, 3, 6, 1, 5, 5, 7, 2, 1][..]).into()),
1103                    qualifier: Any::new(
1104                        rasn::der::encode(
1105                            &Ia5String::try_from(alloc::string::String::from(
1106                                "http://cps.root-x1.letsencrypt.org"
1107                            ))
1108                            .unwrap()
1109                        )
1110                        .unwrap()
1111                    ),
1112                }]),
1113            }
1114        ];
1115
1116        let expected_enc = &[
1117            0x30, 0x4B, 0x30, 0x08, 0x06, 0x06, 0x67, 0x81, 0x0C, 0x01, 0x02, 0x01, 0x30, 0x3F,
1118            0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xDF, 0x13, 0x01, 0x01, 0x01, 0x30,
1119            0x30, 0x30, 0x2E, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16,
1120            0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x63, 0x70, 0x73, 0x2E, 0x72, 0x6F,
1121            0x6F, 0x74, 0x2D, 0x78, 0x31, 0x2E, 0x6C, 0x65, 0x74, 0x73, 0x65, 0x6E, 0x63, 0x72,
1122            0x79, 0x70, 0x74, 0x2E, 0x6F, 0x72, 0x67,
1123        ][..];
1124
1125        assert_eq!(expected_enc, rasn::der::encode(&expected_de).unwrap());
1126        assert_eq!(
1127            expected_de,
1128            rasn::der::decode::<CertificatePolicies>(expected_enc).unwrap()
1129        );
1130    }
1131
1132    #[test]
1133    fn trust_anchor_info_version() {
1134        let alg_id = AlgorithmIdentifier {
1135            algorithm: ObjectIdentifier::new_unchecked((&[1, 2][..]).into()),
1136            parameters: None,
1137        };
1138
1139        let spki = SubjectPublicKeyInfo {
1140            algorithm: alg_id,
1141            subject_public_key: Default::default(),
1142        };
1143
1144        let tai = TrustAnchorInfo {
1145            version: Default::default(),
1146            pub_key: spki,
1147            key_id: Default::default(),
1148            ta_title: None,
1149            cert_path: None,
1150            exts: None,
1151            ta_title_lang_tag: None,
1152        };
1153
1154        let expected_enc = &[
1155            0x30, 0x0c, 0x30, 0x08, 0x30, 0x03, 0x06, 0x01, 0x2A, 0x03, 0x01, 0x00, 0x04, 0x00,
1156        ][..];
1157        let actual_enc = rasn::der::encode(&tai).unwrap();
1158
1159        assert_eq!(expected_enc, actual_enc);
1160        assert_eq!(TrustAnchorInfoVersion(1), tai.version);
1161    }
1162}