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