x509_cert/
anchor.rs

1//! Trust anchor-related structures as defined in RFC 5914
2
3use crate::ext::pkix::{certpolicy::CertificatePolicies, NameConstraints};
4use crate::{ext::Extensions, name::Name};
5use crate::{Certificate, TbsCertificate};
6
7use alloc::string::String;
8use der::asn1::OctetString;
9use der::flagset::{flags, FlagSet};
10use der::{Choice, Enumerated, Sequence};
11use spki::SubjectPublicKeyInfoOwned;
12
13/// Version identifier for TrustAnchorInfo
14#[derive(Clone, Debug, Default, Copy, PartialEq, Eq, Enumerated)]
15#[asn1(type = "INTEGER")]
16#[repr(u8)]
17pub enum Version {
18    /// Version 1 (default)
19    #[default]
20    V1 = 0,
21}
22
23/// ```text
24/// TrustAnchorInfo ::= SEQUENCE {
25///     version         TrustAnchorInfoVersion DEFAULT v1,
26///     pubKey          SubjectPublicKeyInfo,
27///     keyId           KeyIdentifier,
28///     taTitle         TrustAnchorTitle OPTIONAL,
29///     certPath        CertPathControls OPTIONAL,
30///     exts            [1] EXPLICIT Extensions   OPTIONAL,
31///     taTitleLangTag  [2] UTF8String OPTIONAL
32/// }
33///
34/// TrustAnchorInfoVersion ::= INTEGER { v1(1) }
35///
36/// TrustAnchorTitle ::= UTF8String (SIZE (1..64))
37/// ```
38#[derive(Clone, Debug, PartialEq, Eq, Sequence)]
39#[allow(missing_docs)]
40pub struct TrustAnchorInfo {
41    #[asn1(default = "Default::default")]
42    pub version: Version,
43
44    pub pub_key: SubjectPublicKeyInfoOwned,
45
46    pub key_id: OctetString,
47
48    #[asn1(optional = "true")]
49    pub ta_title: Option<String>,
50
51    #[asn1(optional = "true")]
52    pub cert_path: Option<CertPathControls>,
53
54    #[asn1(context_specific = "1", tag_mode = "EXPLICIT", optional = "true")]
55    pub extensions: Option<Extensions>,
56
57    #[asn1(context_specific = "2", tag_mode = "IMPLICIT", optional = "true")]
58    pub ta_title_lang_tag: Option<String>,
59}
60
61/// ```text
62/// CertPathControls ::= SEQUENCE {
63///     taName              Name,
64///     certificate         [0] Certificate OPTIONAL,
65///     policySet           [1] CertificatePolicies OPTIONAL,
66///     policyFlags         [2] CertPolicyFlags OPTIONAL,
67///     nameConstr          [3] NameConstraints OPTIONAL,
68///     pathLenConstraint   [4] INTEGER (0..MAX) OPTIONAL
69/// }
70/// ```
71#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
72#[allow(missing_docs)]
73pub struct CertPathControls {
74    pub ta_name: Name,
75
76    #[asn1(context_specific = "0", tag_mode = "IMPLICIT", optional = "true")]
77    pub certificate: Option<Certificate>,
78
79    #[asn1(context_specific = "1", tag_mode = "IMPLICIT", optional = "true")]
80    pub policy_set: Option<CertificatePolicies>,
81
82    #[asn1(context_specific = "2", tag_mode = "IMPLICIT", optional = "true")]
83    pub policy_flags: Option<CertPolicyFlags>,
84
85    #[asn1(context_specific = "3", tag_mode = "IMPLICIT", optional = "true")]
86    pub name_constr: Option<NameConstraints>,
87
88    #[asn1(context_specific = "4", tag_mode = "IMPLICIT", optional = "true")]
89    pub path_len_constraint: Option<u32>,
90}
91
92flags! {
93    /// Certificate policies as defined in [RFC 5280 Section 4.2.1.13].
94    ///
95    /// ```text
96    /// CertPolicyFlags ::= BIT STRING {
97    ///     inhibitPolicyMapping    (0),
98    ///     requireExplicitPolicy   (1),
99    ///     inhibitAnyPolicy        (2)
100    /// }
101    /// ```
102    ///
103    /// [RFC 5280 Section 4.2.1.13]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.13
104    #[allow(missing_docs)]
105    pub enum CertPolicies: u8 {
106        InhibitPolicyMapping = 1 << 0,
107        RequireExplicitPolicy = 1 << 1,
108        InhibitAnyPolicy = 1 << 2,
109    }
110}
111
112/// Certificate policy flags as defined in [RFC 5280 Section 4.2.1.13].
113///
114/// [RFC 5280 Section 4.2.1.13]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.13
115pub type CertPolicyFlags = FlagSet<CertPolicies>;
116
117/// ```text
118/// TrustAnchorChoice ::= CHOICE {
119///   certificate  Certificate,
120///   tbsCert      [1] EXPLICIT TBSCertificate,
121///   taInfo       [2] EXPLICIT TrustAnchorInfo
122/// }
123/// ```
124#[derive(Clone, Debug, PartialEq, Eq, Choice)]
125#[allow(clippy::large_enum_variant)]
126#[allow(missing_docs)]
127pub enum TrustAnchorChoice {
128    Certificate(Certificate),
129
130    #[asn1(context_specific = "1", tag_mode = "EXPLICIT", constructed = "true")]
131    TbsCertificate(TbsCertificate),
132
133    #[asn1(context_specific = "2", tag_mode = "EXPLICIT", constructed = "true")]
134    TaInfo(TrustAnchorInfo),
135}