rasn_pkix/
lib.rs

1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(test), no_std)]
3
4extern crate alloc;
5
6pub mod attribute_certificate;
7pub mod est;
8
9use rasn::{types::*, Decode, Encode};
10
11pub type InvalidityDate = GeneralizedTime;
12pub type CertificateIssuer = GeneralNames;
13pub type CrlNumber = Integer;
14pub type BaseCrlNumber = CrlNumber;
15pub type SubjectInfoAccessSyntax = SequenceOf<AccessDescription>;
16pub type AuthorityInfoAccessSyntax = SequenceOf<AccessDescription>;
17pub type FreshestCrl = CrlDistributionPoints;
18pub type InhibitAnyPolicy = CrlDistributionPoints;
19pub type KeyPurposeId = ObjectIdentifier;
20pub type ExtKeyUsageSyntax = SequenceOf<KeyPurposeId>;
21pub type ReasonFlags = BitString;
22pub type SkipCerts = Integer;
23pub type BaseDistance = Integer;
24pub type CrlDistributionPoints = SequenceOf<DistributionPoint>;
25pub type GeneralSubtrees = SequenceOf<GeneralSubtree>;
26pub type SubjectDirectoryAttributes = SequenceOf<Attribute>;
27pub type GeneralNames = SequenceOf<GeneralName>;
28pub type SubjectAltName = GeneralNames;
29pub type PolicyMappings = SequenceOf<PolicyMapping>;
30pub type CpsUri = Ia5String;
31pub type CertPolicyId = ObjectIdentifier;
32pub type CertificatePolicies = SequenceOf<PolicyInformation>;
33pub type KeyUsage = BitString;
34pub type AttributeType = ObjectIdentifier;
35pub type AttributeValue = Any;
36pub type RdnSequence = SequenceOf<RelativeDistinguishedName>;
37pub type X520DnQualifier = PrintableString;
38pub type DomainComponent = Ia5String;
39pub type EmailAddress = Ia5String;
40pub type CertificateSerialNumber = Integer;
41pub type UniqueIdentifier = BitString;
42pub type NetworkAddress = X121Address;
43pub type X121Address = NumericString;
44pub type TerminalIdentifier = PrintableString;
45pub type OrganisationName = PrintableString;
46pub type NumericUserIdentifier = NumericString;
47pub type TerminalType = u8;
48pub type KeyIdentifier = OctetString;
49pub type SubjectKeyIdentifier = KeyIdentifier;
50pub type PolicyQualifierId = ObjectIdentifier;
51pub type TrustAnchorTitle = Utf8String;
52pub type TrustAnchorInfoVersion = Integer;
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, PartialOrd, Ord, 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, PartialOrd, Ord, 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 [RFC5280][X.509].  They are required
187/// when validating certification paths.  Though widely used, there is no
188/// standard format for representing trust anchor information.  The RFC-5914
189/// document describes the TrustAnchorInfo structure.
190#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
191pub struct TrustAnchorInfo {
192    /// version identifies the version of TrustAnchorInfo.  Defaults to 1.
193    #[rasn(tag(explicit(1)), default)]
194    pub version: TrustAnchorInfoVersion,
195    /// pubKey identifies the public key and algorithm associated with the
196    /// trust anchor using the SubjectPublicKeyInfo structure [RFC5280].  The
197    /// SubjectPublicKeyInfo structure contains the algorithm identifier
198    /// followed by the public key itself.
199    pub pub_key: SubjectPublicKeyInfo,
200    /// keyId contains the public key identifier of the trust anchor public key.
201    pub key_id: KeyIdentifier,
202    /// taTitle is OPTIONAL.  When it is present, it provides a human-readable name
203    /// for the trust anchor.
204    pub ta_title: Option<TrustAnchorTitle>,
205    /// certPath is OPTIONAL.  When it is present, it provides the controls
206    /// needed to initialize an X.509 certification path validation algorithm
207    /// implementation (see Section 6 of [RFC5280]).  When absent, the trust
208    /// anchor cannot be used to validate the signature on an X.509
209    /// certificate.
210    pub cert_path: Option<CertPathControls>,
211    #[rasn(tag(explicit(1)))]
212    /// exts is OPTIONAL.  When it is present, it can be used to associate
213    /// additional information with the trust anchor using the standard
214    /// Extensions structure.  Extensions that are anticipated to be widely
215    /// used have been included in the CertPathControls structure to avoid
216    /// overhead associated with use of the Extensions structure.  To avoid
217    /// duplication with the CertPathControls field, the following types of
218    /// extensions MUST NOT appear in the exts field and are ignored if they
219    /// do appear: id-ce-certificatePolicies, id-ce-policyConstraints, id-ce-
220    /// inhibitAnyPolicy, or id-ce-nameConstraints.
221    pub exts: Option<Extensions>,
222    #[rasn(tag(2))]
223    /// The taTitleLangTag field identifies the language used to express the
224    /// taTitle.  When taTitleLangTag is absent, English ("en" language tag)
225    /// is used.
226    pub ta_title_lang_tag: Option<Utf8String>,
227}
228
229/// CertPathControls provides the controls needed to initialize an X.509
230// certification path validation algorithm implementation
231#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
232pub struct CertPathControls {
233    /// taName provides the X.500 distinguished name associated with the
234    /// trust anchor, and this distinguished name is used to construct and
235    /// validate an X.509 certification path.  The name MUST NOT be an empty
236    /// sequence.
237    pub ta_name: Name,
238    #[rasn(tag(0))]
239    /// certificate provides an OPTIONAL X.509 certificate, which can be used
240    /// in some environments to represent the trust anchor in certification
241    /// path development and validation
242    pub certificate: Option<Certificate>,
243    #[rasn(tag(1))]
244    /// policySet contains a sequence of
245    /// certificate policy identifiers to be provided as inputs to the
246    /// certification path validation algorithm.
247    pub policy_set: Option<CertificatePolicies>,
248    #[rasn(tag(2))]
249    /// policyFlags is OPTIONAL.  When present, three Boolean values for
250    /// input to the certification path validation algorithm are provided in
251    /// a BIT STRING.  When absent, the input to the certification path
252    /// validation algorithm is { FALSE, FALSE, FALSE }, which represents the
253    /// most liberal setting for these flags.
254    pub policy_flags: Option<CertPolicyFlags>,
255    #[rasn(tag(3))]
256    /// nameConstrhas the same syntax and semantics as the
257    /// Name Constraints certificate extension [RFC5280], which includes a
258    /// list of permitted names and a list of excluded names.
259    pub name_constr: Option<NameConstraints>,
260    #[rasn(tag(4))]
261    /// The pathLenConstraint field gives the maximum number of non-self-
262    /// issued intermediate certificates that may follow this certificate in
263    /// a valid certification path.  (Note: The last certificate in the
264    /// certification path is not an intermediate certificate and is not
265    /// included in this limit.  Usually, the last certificate is an end
266    /// entity certificate, but it can be a CA certificate.
267    pub path_len_constraint: Option<Integer>,
268}
269
270/// TrustAnchorChoice provides three options for representing a trust anchor.
271///
272/// The certificate option allows for the use of a certificate with no additional
273/// associated constraints.
274///
275/// The tbsCert option allows for associating constraints by removing a signature
276/// on a certificate and changing the extensions field.
277///
278/// The taInfo option allows for use of the TrustAnchorInfo structure defined
279/// in RFC-5914.
280#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
281#[rasn(choice)]
282pub enum TrustAnchorChoice {
283    Certificate(Certificate),
284    #[rasn(tag(explicit(1)))]
285    TbsCertificate(TbsCertificate),
286    #[rasn(tag(explicit(2)))]
287    TrustAnchorInfo(TrustAnchorInfo),
288}
289
290/// The validity period of the certificate.
291#[derive(AsnType, Clone, Copy, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
292pub struct Validity {
293    pub not_before: Time,
294    pub not_after: Time,
295}
296
297/// A general time type.
298#[derive(AsnType, Clone, Copy, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
299#[rasn(choice)]
300pub enum Time {
301    Utc(UtcTime),
302    General(GeneralizedTime),
303}
304
305/// The subject's public key, and the algorithm used to encode it.
306#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
307pub struct SubjectPublicKeyInfo {
308    pub algorithm: AlgorithmIdentifier,
309    pub subject_public_key: BitString,
310}
311
312/// Identifying the public key corresponding to the private key used to sign a
313/// certificate.
314///
315/// This extension is used where an issuer has multiple signing keys (either due
316/// to multiple concurrent key pairs or due to changeover).  The identification
317/// MAY be based on either the key identifier (the subject key identifier in the
318/// issuer's certificate) or the issuer name and serial number.
319#[derive(AsnType, Default, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
320pub struct AuthorityKeyIdentifier {
321    #[rasn(tag(0))]
322    pub key_identifier: Option<KeyIdentifier>,
323    #[rasn(tag(1))]
324    pub authority_cert_issuer: Option<GeneralNames>,
325    #[rasn(tag(2))]
326    pub authority_cert_serial_number: Option<CertificateSerialNumber>,
327}
328
329/// Extension to an X.509 certificate.
330#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
331pub struct Extension {
332    pub extn_id: ObjectIdentifier,
333    #[rasn(default)]
334    pub critical: bool,
335    pub extn_value: OctetString,
336}
337
338/// A signed list of revoked certificates.
339#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
340pub struct CertificateList {
341    pub tbs_cert_list: TbsCertList,
342    pub signature_algorithm: AlgorithmIdentifier,
343    pub signature: BitString,
344}
345
346/// The list of revoked certificates along with associated metadata.
347#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
348pub struct TbsCertList {
349    /// The version of the list.
350    pub version: Version,
351    /// The algorithm used in the signature.
352    pub signature: AlgorithmIdentifier,
353    /// The authority that issued the certificate list.
354    pub issuer: Name,
355    /// The issue date of this list.
356    pub this_update: Time,
357    /// When the next update will be available. The update may be available
358    /// sooner than `next_update`, but it will not be issued later.
359    pub next_update: Option<Time>,
360    /// The list of revoked certificates.
361    pub revoked_certificates: SequenceOf<RevokedCerificate>,
362    /// Extensions to the list.
363    #[rasn(tag(explicit(0)))]
364    pub crl_extensions: Option<Extensions>,
365}
366
367/// Identifies a revoked certificate.
368#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
369pub struct RevokedCerificate {
370    /// The ID of the certificate being revoked.
371    pub user_certificate: CertificateSerialNumber,
372    /// When the certificate was revoked.
373    pub revocation_date: Time,
374    /// Extensions to the revoked entry.
375    pub crl_entry_extensions: Option<Extensions>,
376}
377
378/// Identifies what algorithm was used, along with any parameters used as input.
379#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
380pub struct AlgorithmIdentifier {
381    /// The identifier for the algorithm.
382    pub algorithm: ObjectIdentifier,
383    /// Parameters for the algorithm, if any.
384    pub parameters: Option<Any>,
385}
386
387#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
388pub struct OrAddress {
389    pub built_in_standard_attributes: BuiltInStandardAttributes,
390    pub built_in_domain_defined_attributes: Option<BuiltInDomainDefinedAttributes>,
391    pub extension_attributes: Option<ExtensionAttributes>,
392}
393
394#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
395pub struct BuiltInStandardAttributes {
396    pub country_name: Option<CountryName>,
397    pub administraion_domain_name: Option<AdministrationDomainName>,
398    #[rasn(tag(0))]
399    pub network_address: Option<NetworkAddress>,
400    #[rasn(tag(1))]
401    pub terminal_identifier: Option<TerminalIdentifier>,
402    #[rasn(tag(2))]
403    pub private_domain_name: Option<PrivateDomainName>,
404    #[rasn(tag(3))]
405    pub organisation_name: Option<OrganisationName>,
406    #[rasn(tag(4))]
407    pub numeric_user_identifier: Option<NumericUserIdentifier>,
408    #[rasn(tag(5))]
409    pub personal_name: Option<PersonalName>,
410    #[rasn(tag(6))]
411    pub organisational_unit_name: Option<OrganisationalUnitNames>,
412}
413
414#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
415#[rasn(delegate, size("1..=4"))]
416pub struct BuiltInDomainDefinedAttributes(SequenceOf<BuiltInDomainDefinedAttribute>);
417derefable!(
418    BuiltInDomainDefinedAttributes,
419    SequenceOf<BuiltInDomainDefinedAttribute>
420);
421
422#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
423pub struct BuiltInDomainDefinedAttribute {
424    #[rasn(size("1..=8"))]
425    pub r#type: PrintableString,
426    #[rasn(size("1..=128"))]
427    pub value: PrintableString,
428}
429
430#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
431#[rasn(tag(explicit(application, 1)))]
432#[rasn(choice)]
433pub enum CountryName {
434    #[rasn(size(3))]
435    X121DccCode(NumericString),
436    #[rasn(size(2))]
437    Iso3166Alpha2Code(PrintableString),
438}
439
440#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
441#[rasn(choice)]
442pub enum PrivateDomainName {
443    #[rasn(size("1..=16"))]
444    Numeric(NumericString),
445    #[rasn(size("1..=16"))]
446    Printable(PrintableString),
447}
448
449#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
450#[rasn(tag(explicit(application, 2)), choice)]
451pub enum AdministrationDomainName {
452    #[rasn(size("0..=16"))]
453    Numeric(NumericString),
454    #[rasn(size("0..=16"))]
455    Printable(PrintableString),
456}
457
458#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
459#[rasn(set)]
460pub struct PersonalName {
461    #[rasn(tag(0))]
462    pub surname: PrintableString,
463    #[rasn(tag(1))]
464    pub given_name: Option<PrintableString>,
465    #[rasn(tag(2))]
466    pub initials: Option<PrintableString>,
467    #[rasn(tag(3))]
468    pub generation_qualifier: Option<PrintableString>,
469}
470
471#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
472#[rasn(delegate, size("1..=4"))]
473pub struct OrganisationalUnitNames(SequenceOf<OrganisationalUnitName>);
474derefable!(OrganisationalUnitNames, SequenceOf<OrganisationalUnitName>);
475
476#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
477#[rasn(delegate, size("1..=32"))]
478pub struct OrganisationalUnitName(PrintableString);
479derefable!(OrganisationalUnitName, PrintableString);
480
481#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
482#[rasn(delegate, size("1.."))]
483pub struct Extensions(SequenceOf<Extension>);
484derefable!(Extensions, SequenceOf<Extension>);
485
486#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
487#[rasn(delegate, size("1.."))]
488pub struct RelativeDistinguishedName(SetOf<AttributeTypeAndValue>);
489derefable!(RelativeDistinguishedName, SetOf<AttributeTypeAndValue>);
490
491#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
492#[rasn(delegate, size("1..=256"))]
493pub struct ExtensionAttributes(SetOf<ExtensionAttribute>);
494derefable!(ExtensionAttributes, SetOf<ExtensionAttribute>);
495
496#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
497pub struct ExtensionAttribute {
498    #[rasn(tag(0), value("0..=256"))]
499    pub extension_attribute_type: u16,
500    #[rasn(tag(1))]
501    pub extension_attribute_value: Any,
502}
503
504#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
505#[rasn(set)]
506pub struct TeletexPersonalName {
507    #[rasn(tag(0), size("1..=40"))]
508    pub surname: TeletexString,
509    #[rasn(tag(1), size("1..=16"))]
510    pub given_name: Option<TeletexString>,
511    #[rasn(tag(2), size("1..=5"))]
512    pub initials: Option<TeletexString>,
513    #[rasn(tag(3), size("1..=3"))]
514    pub generation_qualifier: Option<TeletexString>,
515}
516
517#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
518#[rasn(choice)]
519pub enum PhysicalDeliveryCountryName {
520    #[rasn(size(3))]
521    X121DccCode(NumericString),
522    #[rasn(size(2))]
523    Iso3166Alpha2Code(PrintableString),
524}
525
526#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
527#[rasn(choice)]
528pub enum PostalCode {
529    #[rasn(size("1..=16"))]
530    Numeric(NumericString),
531    #[rasn(size("1..=16"))]
532    Printable(PrintableString),
533}
534
535#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
536#[rasn(delegate, size("1..=64"))]
537pub struct CommonName(PrintableString);
538derefable!(CommonName, PrintableString);
539
540#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
541#[rasn(delegate, size("1..=64"))]
542pub struct TeletexCommonName(TeletexString);
543derefable!(TeletexCommonName, TeletexString);
544
545#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
546#[rasn(delegate, size("1..=64"))]
547pub struct TeletexOrganizationName(TeletexString);
548derefable!(TeletexOrganizationName, TeletexString);
549
550#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
551#[rasn(delegate, size("1..=4"))]
552pub struct TeletexOrganisationalUnitNames(SequenceOf<TeletexOrganisationalUnitName>);
553derefable!(
554    TeletexOrganisationalUnitNames,
555    SequenceOf<TeletexOrganisationalUnitName>
556);
557
558#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
559#[rasn(delegate, size("1..=32"))]
560pub struct TeletexOrganisationalUnitName(TeletexString);
561derefable!(TeletexOrganisationalUnitName, TeletexString);
562
563#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
564#[rasn(delegate, size("1..=16"))]
565pub struct PdsName(PrintableString);
566derefable!(PdsName, PrintableString);
567
568#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
569#[rasn(delegate, size("1..=30"))]
570pub struct PrintableAddress(PrintableString);
571derefable!(PrintableAddress, PrintableString);
572
573#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
574#[rasn(delegate, size("1..=180"))]
575pub struct TeletexAddress(TeletexString);
576derefable!(TeletexAddress, TeletexString);
577
578#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
579#[rasn(set)]
580pub struct UnformattedPostalAddress {
581    #[rasn(size("1..=6"))]
582    pub printable_address: Option<SequenceOf<PrintableAddress>>,
583    pub teletex_string: Option<TeletexAddress>,
584}
585
586#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
587#[rasn(set)]
588pub struct PdsParameter {
589    #[rasn(size("1..=30"))]
590    pub printable_string: Option<PrintableString>,
591    #[rasn(size("1..=30"))]
592    pub teletex_string: Option<TeletexString>,
593}
594
595#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
596#[rasn(choice)]
597pub enum ExtendedNetworkAddress {
598    E1634Address(E1634Address),
599    #[rasn(tag(0))]
600    PsapAddress(PresentationAddress),
601}
602
603#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
604pub struct E1634Address {
605    #[rasn(tag(0), size("1..=15"))]
606    pub number: NumericString,
607    #[rasn(tag(1), size("1..=40"))]
608    pub sub_address: Option<NumericString>,
609}
610
611#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
612pub struct PresentationAddress {
613    #[rasn(tag(explicit(0)))]
614    pub p_selector: Option<OctetString>,
615    #[rasn(tag(explicit(1)))]
616    pub s_selector: Option<OctetString>,
617    #[rasn(tag(explicit(2)))]
618    pub t_selector: Option<OctetString>,
619    #[rasn(tag(explicit(3)), size("1.."))]
620    pub n_addresses: SetOf<OctetString>,
621}
622
623#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
624#[rasn(delegate, size("1..=4"))]
625pub struct TeletexDomainDefinedAttributes(SequenceOf<TeletexDomainDefinedAttribute>);
626
627#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
628pub struct TeletexDomainDefinedAttribute {
629    #[rasn(size("1..=8"))]
630    pub r#type: TeletexString,
631    #[rasn(size("1..=128"))]
632    pub value: TeletexString,
633}
634
635#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
636#[rasn(choice)]
637pub enum Name {
638    RdnSequence(RdnSequence),
639}
640
641#[derive(AsnType, Clone, Debug, Decode, Encode, PartialOrd, Ord, PartialEq, Eq, Hash)]
642pub struct Attribute {
643    pub r#type: AttributeType,
644    pub values: SetOf<AttributeValue>,
645}
646
647#[derive(AsnType, Clone, Debug, Decode, Encode, PartialOrd, Ord, PartialEq, Eq, Hash)]
648pub struct AttributeTypeAndValue {
649    pub r#type: AttributeType,
650    pub value: AttributeValue,
651}
652
653#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
654pub struct PolicyInformation {
655    pub policy_identifier: CertPolicyId,
656    pub policy_qualifiers: Option<SequenceOf<PolicyQualifierInfo>>,
657}
658
659#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
660pub struct PolicyQualifierInfo {
661    pub id: PolicyQualifierId,
662    pub qualifier: Any,
663}
664
665#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
666pub struct UserNotice {
667    pub notice_ref: Option<NoticeReference>,
668    pub explicit_text: Option<DisplayText>,
669}
670
671#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
672pub struct NoticeReference {
673    pub organisation: DisplayText,
674    pub notice_numbers: SequenceOf<Integer>,
675}
676
677#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
678#[rasn(choice)]
679pub enum DisplayText {
680    Ia5String(Ia5String),
681    VisibleString(VisibleString),
682    BmpString(BmpString),
683    Utf8String(Utf8String),
684}
685
686#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
687pub struct PolicyMapping {
688    pub issuer_domain_policy: CertPolicyId,
689    pub subject_domain_policy: CertPolicyId,
690}
691
692#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
693#[rasn(choice)]
694pub enum GeneralName {
695    #[rasn(tag(0))]
696    OtherName(InstanceOf<OctetString>),
697    #[rasn(tag(1))]
698    Rfc822Name(Ia5String),
699    #[rasn(tag(2))]
700    DnsName(Ia5String),
701    // Boxed because it's 368 bytes, and the next largest enum variant is 64.
702    #[rasn(tag(3))]
703    X400Address(alloc::boxed::Box<OrAddress>),
704    #[rasn(tag(4))]
705    DirectoryName(Name),
706    #[rasn(tag(5))]
707    EdiPartyName(EdiPartyName),
708    #[rasn(tag(6))]
709    Uri(Ia5String),
710    #[rasn(tag(7))]
711    IpAddress(OctetString),
712    #[rasn(tag(8))]
713    RegisteredId(ObjectIdentifier),
714}
715
716#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
717pub struct EdiPartyName {
718    #[rasn(tag(0))]
719    pub name_assigner: Option<DirectoryString>,
720    #[rasn(tag(1))]
721    pub party_name: DirectoryString,
722}
723
724#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
725#[rasn(delegate, size(2))]
726pub struct X520CountryName(PrintableString);
727derefable!(X520CountryName, PrintableString);
728
729#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
730#[rasn(delegate, size("1..=64"))]
731pub struct X520SerialNumber(PrintableString);
732derefable!(X520SerialNumber, PrintableString);
733
734#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
735#[rasn(choice)]
736pub enum X520StateOrProvinceName {
737    #[rasn(size("1..=128"))]
738    Teletex(TeletexString),
739    #[rasn(size("1..=128"))]
740    Printable(PrintableString),
741    #[rasn(size("1..=128"))]
742    Universal(UniversalString),
743    #[rasn(size("1..=128"))]
744    Utf8(Utf8String),
745    #[rasn(size("1..=128"))]
746    Bmp(BmpString),
747}
748
749#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
750#[rasn(choice)]
751pub enum X520OrganisationName {
752    #[rasn(size("1..=64"))]
753    Teletex(TeletexString),
754    #[rasn(size("1..=64"))]
755    Printable(PrintableString),
756    #[rasn(size("1..=64"))]
757    Universal(UniversalString),
758    #[rasn(size("1..=64"))]
759    Utf8(Utf8String),
760    #[rasn(size("1..=64"))]
761    Bmp(BmpString),
762}
763
764#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
765#[rasn(choice)]
766pub enum X520OrganisationalUnitName {
767    #[rasn(size("1..=64"))]
768    Teletex(TeletexString),
769    #[rasn(size("1..=64"))]
770    Printable(PrintableString),
771    #[rasn(size("1..=64"))]
772    Universal(UniversalString),
773    #[rasn(size("1..=64"))]
774    Utf8(Utf8String),
775    #[rasn(size("1..=64"))]
776    Bmp(BmpString),
777}
778
779#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
780#[rasn(choice)]
781pub enum X520Title {
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 X520Pseudonym {
797    #[rasn(size("1..=128"))]
798    Teletex(TeletexString),
799    #[rasn(size("1..=128"))]
800    Printable(PrintableString),
801    #[rasn(size("1..=128"))]
802    Universal(UniversalString),
803    #[rasn(size("1..=128"))]
804    Utf8(Utf8String),
805    #[rasn(size("1..=128"))]
806    Bmp(BmpString),
807}
808
809#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
810#[rasn(choice)]
811pub enum X520LocalityName {
812    #[rasn(size("1..=128"))]
813    Teletex(TeletexString),
814    #[rasn(size("1..=128"))]
815    Printable(PrintableString),
816    #[rasn(size("1..=128"))]
817    Universal(UniversalString),
818    #[rasn(size("1..=128"))]
819    Utf8(Utf8String),
820    #[rasn(size("1..=128"))]
821    Bmp(BmpString),
822}
823
824#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
825#[rasn(choice)]
826pub enum X520Name {
827    #[rasn(size("1..=32768"))]
828    Teletex(TeletexString),
829    #[rasn(size("1..=32768"))]
830    Printable(PrintableString),
831    #[rasn(size("1..=32768"))]
832    Universal(UniversalString),
833    #[rasn(size("1..=32768"))]
834    Utf8(Utf8String),
835    #[rasn(size("1..=32768"))]
836    Bmp(BmpString),
837}
838
839#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
840#[rasn(choice)]
841pub enum X520CommonName {
842    #[rasn(size("1..=64"))]
843    Teletex(TeletexString),
844    #[rasn(size("1..=64"))]
845    Printable(PrintableString),
846    #[rasn(size("1..=64"))]
847    Universal(UniversalString),
848    #[rasn(size("1..=64"))]
849    Utf8(Utf8String),
850    #[rasn(size("1..=64"))]
851    Bmp(BmpString),
852}
853
854macro_rules! directory_string_compat {
855    ($($from:ident),+ $(,)?) => {
856        $(
857            impl PartialEq<$from> for DirectoryString {
858                fn eq(&self, rhs: &$from) -> bool {
859                    match (rhs, self) {
860                        ($from::Teletex(lhs), Self::Teletex(rhs)) => lhs == rhs,
861                        ($from::Printable(lhs), Self::Printable(rhs)) => lhs == rhs,
862                        ($from::Universal(lhs), Self::Universal(rhs)) => lhs == rhs,
863                        ($from::Utf8(lhs), Self::Utf8(rhs)) => lhs == rhs,
864                        ($from::Bmp(lhs), Self::Bmp(rhs)) => lhs == rhs,
865                        _ => false,
866                    }
867                }
868            }
869
870            impl From<$from> for DirectoryString {
871                fn from(value: $from) -> Self {
872                    match value {
873                        $from::Teletex(value) => Self::Teletex(value),
874                        $from::Printable(value) => Self::Printable(value),
875                        $from::Universal(value) => Self::Universal(value),
876                        $from::Utf8(value) => Self::Utf8(value),
877                        $from::Bmp(value) => Self::Bmp(value),
878                    }
879                }
880            }
881        )+
882    }
883}
884
885directory_string_compat! {
886    X520Name,
887    X520CommonName,
888    X520LocalityName,
889    X520Pseudonym,
890    X520Title,
891    X520OrganisationalUnitName,
892    X520OrganisationName,
893    X520StateOrProvinceName,
894}
895
896#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
897#[rasn(choice)]
898pub enum DirectoryString {
899    #[rasn(size("1.."))]
900    Teletex(TeletexString),
901    #[rasn(size("1.."))]
902    Printable(PrintableString),
903    #[rasn(size("1.."))]
904    Universal(UniversalString),
905    #[rasn(size("1.."))]
906    Utf8(Utf8String),
907    #[rasn(size("1.."))]
908    Bmp(BmpString),
909}
910
911#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
912pub struct BasicConstraints {
913    #[rasn(default)]
914    pub ca: bool,
915    pub path_len_constraint: Option<Integer>,
916}
917
918#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
919pub struct NameConstraints {
920    #[rasn(tag(0))]
921    pub permitted_subtrees: Option<GeneralSubtrees>,
922    #[rasn(tag(1))]
923    pub excluded_subtrees: Option<GeneralSubtrees>,
924}
925
926#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
927pub struct GeneralSubtree {
928    pub base: GeneralName,
929    #[rasn(tag(0), default)]
930    pub minimum: BaseDistance,
931    #[rasn(tag(1))]
932    pub maximum: Option<BaseDistance>,
933}
934
935#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
936pub struct PolicyConstraints {
937    #[rasn(tag(0))]
938    pub require_explicit_policy: Option<SkipCerts>,
939    #[rasn(tag(1))]
940    pub inhibit_policy_mapping: Option<SkipCerts>,
941}
942
943#[derive(AsnType, Clone, Debug, Default, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
944pub struct DistributionPoint {
945    #[rasn(tag(0))]
946    pub distribution_point: Option<DistributionPointName>,
947    #[rasn(tag(1))]
948    pub reasons: Option<ReasonFlags>,
949    #[rasn(tag(2))]
950    pub crl_issuer: Option<GeneralNames>,
951}
952
953#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
954#[rasn(choice)]
955pub enum DistributionPointName {
956    #[rasn(tag(0))]
957    FullName(GeneralNames),
958    #[rasn(tag(1))]
959    NameRelativeToCrlIssuer(RelativeDistinguishedName),
960}
961
962#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
963pub struct AccessDescription {
964    pub access_method: ObjectIdentifier,
965    pub access_location: GeneralName,
966}
967
968#[derive(AsnType, Clone, Copy, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
969#[rasn(enumerated)]
970pub enum CrlReason {
971    Unspecified = 0,
972    KeyCompromise = 1,
973    CaCompromise = 2,
974    AffiliationChanged = 3,
975    Superseded = 4,
976    CessationOfOperation = 5,
977    CertificateHold = 6,
978    RemoveFromCRL = 8,
979    PrivilegeWithdrawn = 9,
980    AaCompromise = 10,
981}
982
983#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
984pub struct IssuingDistributionPoint {
985    #[rasn(tag(0))]
986    pub distribution_point: Option<DistributionPointName>,
987    #[rasn(tag(1), default)]
988    pub only_contains_user_certs: bool,
989    #[rasn(tag(2), default)]
990    pub only_contains_ca_certs: bool,
991    #[rasn(tag(3))]
992    pub only_some_reasons: Option<ReasonFlags>,
993    #[rasn(tag(4), default)]
994    pub indirect_crl: bool,
995    #[rasn(tag(5), default)]
996    pub only_contains_attribute_certs: bool,
997}
998
999#[cfg(test)]
1000mod tests {
1001    extern crate alloc;
1002    use super::*;
1003
1004    #[test]
1005    fn time() {
1006        rasn::der::decode::<Time>(&[
1007            0x17, 0x0D, 0x31, 0x38, 0x30, 0x32, 0x30, 0x39, 0x31, 0x32, 0x33, 0x32, 0x30, 0x37,
1008            0x5A,
1009        ])
1010        .unwrap();
1011    }
1012
1013    #[test]
1014    fn algorithm_identifier() {
1015        let expected_de = AlgorithmIdentifier {
1016            algorithm: ObjectIdentifier::new_unchecked((&[1, 2, 840, 113549, 1, 1, 1][..]).into()),
1017            parameters: Some(Any::new(rasn::der::encode(&()).unwrap())),
1018        };
1019
1020        let expected_enc = &[
1021            0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05,
1022            0x00,
1023        ][..];
1024
1025        assert_eq!(expected_enc, rasn::der::encode(&expected_de).unwrap());
1026        assert_eq!(expected_de, rasn::der::decode(expected_enc).unwrap());
1027    }
1028
1029    #[test]
1030    fn certificate_policies() {
1031        let expected_de: CertificatePolicies = alloc::vec![
1032            PolicyInformation {
1033                policy_identifier: ObjectIdentifier::new_unchecked(
1034                    (&[2, 23, 140, 1, 2, 1][..]).into()
1035                ),
1036                policy_qualifiers: None,
1037            },
1038            PolicyInformation {
1039                policy_identifier: ObjectIdentifier::new_unchecked(
1040                    (&[1, 3, 6, 1, 4, 1, 44947, 1, 1, 1][..]).into()
1041                ),
1042                policy_qualifiers: Some(alloc::vec![PolicyQualifierInfo {
1043                    id: ObjectIdentifier::new_unchecked((&[1, 3, 6, 1, 5, 5, 7, 2, 1][..]).into()),
1044                    qualifier: Any::new(
1045                        rasn::der::encode(
1046                            &Ia5String::try_from(alloc::string::String::from(
1047                                "http://cps.root-x1.letsencrypt.org"
1048                            ))
1049                            .unwrap()
1050                        )
1051                        .unwrap()
1052                    ),
1053                }]),
1054            }
1055        ];
1056
1057        let expected_enc = &[
1058            0x30, 0x4B, 0x30, 0x08, 0x06, 0x06, 0x67, 0x81, 0x0C, 0x01, 0x02, 0x01, 0x30, 0x3F,
1059            0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xDF, 0x13, 0x01, 0x01, 0x01, 0x30,
1060            0x30, 0x30, 0x2E, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16,
1061            0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x63, 0x70, 0x73, 0x2E, 0x72, 0x6F,
1062            0x6F, 0x74, 0x2D, 0x78, 0x31, 0x2E, 0x6C, 0x65, 0x74, 0x73, 0x65, 0x6E, 0x63, 0x72,
1063            0x79, 0x70, 0x74, 0x2E, 0x6F, 0x72, 0x67,
1064        ][..];
1065
1066        assert_eq!(expected_enc, rasn::der::encode(&expected_de).unwrap());
1067        assert_eq!(
1068            expected_de,
1069            rasn::der::decode::<CertificatePolicies>(expected_enc).unwrap()
1070        );
1071    }
1072}