1 //! PKIX X.509 Certificate Extensions (RFC 5280)
2 
3 pub mod certpolicy;
4 pub mod constraints;
5 pub mod crl;
6 pub mod name;
7 
8 mod access;
9 mod authkeyid;
10 mod keyusage;
11 mod policymap;
12 
13 use crate::attr::AttributeTypeAndValue;
14 
15 pub use access::{AccessDescription, AuthorityInfoAccessSyntax, SubjectInfoAccessSyntax};
16 pub use authkeyid::AuthorityKeyIdentifier;
17 pub use certpolicy::CertificatePolicies;
18 use const_oid::{AssociatedOid, ObjectIdentifier};
19 pub use constraints::{BasicConstraints, NameConstraints, PolicyConstraints};
20 pub use crl::{
21     BaseCrlNumber, CrlDistributionPoints, CrlNumber, CrlReason, FreshestCrl,
22     IssuingDistributionPoint,
23 };
24 pub use keyusage::{ExtendedKeyUsage, KeyUsage, KeyUsages, PrivateKeyUsagePeriod};
25 pub use policymap::{PolicyMapping, PolicyMappings};
26 
27 pub use const_oid::db::rfc5280::{
28     ID_CE_INHIBIT_ANY_POLICY, ID_CE_ISSUER_ALT_NAME, ID_CE_SUBJECT_ALT_NAME,
29     ID_CE_SUBJECT_DIRECTORY_ATTRIBUTES, ID_CE_SUBJECT_KEY_IDENTIFIER,
30 };
31 
32 use alloc::vec::Vec;
33 
34 use der::asn1::OctetString;
35 
36 /// SubjectKeyIdentifier as defined in [RFC 5280 Section 4.2.1.2].
37 ///
38 /// ```text
39 /// SubjectKeyIdentifier ::= KeyIdentifier
40 /// ```
41 ///
42 /// [RFC 5280 Section 4.2.1.2]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.2
43 #[derive(Clone, Debug, PartialEq, Eq)]
44 pub struct SubjectKeyIdentifier(pub OctetString);
45 
46 impl AssociatedOid for SubjectKeyIdentifier {
47     const OID: ObjectIdentifier = ID_CE_SUBJECT_KEY_IDENTIFIER;
48 }
49 
50 impl_newtype!(SubjectKeyIdentifier, OctetString);
51 impl_extension!(SubjectKeyIdentifier, critical = false);
52 impl_key_identifier!(
53     SubjectKeyIdentifier,
54     (|result: &[u8]| Ok(Self(OctetString::new(result)?)))
55 );
56 
57 /// SubjectAltName as defined in [RFC 5280 Section 4.2.1.6].
58 ///
59 /// ```text
60 /// SubjectAltName ::= GeneralNames
61 /// ```
62 ///
63 /// [RFC 5280 Section 4.2.1.6]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.6
64 #[derive(Clone, Debug, Default, PartialEq, Eq)]
65 pub struct SubjectAltName(pub name::GeneralNames);
66 
67 impl AssociatedOid for SubjectAltName {
68     const OID: ObjectIdentifier = ID_CE_SUBJECT_ALT_NAME;
69 }
70 
71 impl_newtype!(SubjectAltName, name::GeneralNames);
72 
73 impl crate::ext::AsExtension for SubjectAltName {
critical(&self, subject: &crate::name::Name, _extensions: &[super::Extension]) -> bool74     fn critical(&self, subject: &crate::name::Name, _extensions: &[super::Extension]) -> bool {
75         // https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.6
76         //   Further, if the only subject identity included in the certificate is
77         //   an alternative name form (e.g., an electronic mail address), then the
78         //   subject distinguished name MUST be empty (an empty sequence), and the
79         //   subjectAltName extension MUST be present.  If the subject field
80         //   contains an empty sequence, then the issuing CA MUST include a
81         //   subjectAltName extension that is marked as critical.  When including
82         //   the subjectAltName extension in a certificate that has a non-empty
83         //   subject distinguished name, conforming CAs SHOULD mark the
84         //   subjectAltName extension as non-critical.
85 
86         subject.is_empty()
87     }
88 }
89 
90 /// IssuerAltName as defined in [RFC 5280 Section 4.2.1.7].
91 ///
92 /// ```text
93 /// IssuerAltName ::= GeneralNames
94 /// ```
95 ///
96 /// [RFC 5280 Section 4.2.1.7]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.7
97 #[derive(Clone, Debug, Default, PartialEq, Eq)]
98 pub struct IssuerAltName(pub name::GeneralNames);
99 
100 impl AssociatedOid for IssuerAltName {
101     const OID: ObjectIdentifier = ID_CE_ISSUER_ALT_NAME;
102 }
103 
104 impl_newtype!(IssuerAltName, name::GeneralNames);
105 impl_extension!(IssuerAltName, critical = false);
106 
107 /// SubjectDirectoryAttributes as defined in [RFC 5280 Section 4.2.1.8].
108 ///
109 /// ```text
110 /// SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF AttributeSet
111 /// ```
112 ///
113 /// [RFC 5280 Section 4.2.1.8]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.8
114 #[derive(Clone, Debug, Default, PartialEq, Eq)]
115 pub struct SubjectDirectoryAttributes(pub Vec<AttributeTypeAndValue>);
116 
117 impl AssociatedOid for SubjectDirectoryAttributes {
118     const OID: ObjectIdentifier = ID_CE_SUBJECT_DIRECTORY_ATTRIBUTES;
119 }
120 
121 impl_newtype!(SubjectDirectoryAttributes, Vec<AttributeTypeAndValue>);
122 impl_extension!(SubjectDirectoryAttributes, critical = false);
123 
124 /// InhibitAnyPolicy as defined in [RFC 5280 Section 4.2.1.14].
125 ///
126 /// ```text
127 /// InhibitAnyPolicy ::= SkipCerts
128 /// ```
129 ///
130 /// [RFC 5280 Section 4.2.1.14]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.14
131 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
132 pub struct InhibitAnyPolicy(pub u32);
133 
134 impl AssociatedOid for InhibitAnyPolicy {
135     const OID: ObjectIdentifier = ID_CE_INHIBIT_ANY_POLICY;
136 }
137 
138 impl_newtype!(InhibitAnyPolicy, u32);
139 impl_extension!(InhibitAnyPolicy, critical = true);
140