Skip to main content
This is unreleased documentation for the main (development) branch of crypto-glue.

x509_cert/
anchor.rs

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