1 //! PKIX Name Constraint extension
2 
3 use alloc::vec::Vec;
4 
5 use const_oid::{db::rfc5280::ID_CE_NAME_CONSTRAINTS, AssociatedOid, ObjectIdentifier};
6 use der::Sequence;
7 
8 use super::super::name::GeneralName;
9 
10 /// NameConstraints extension as defined in [RFC 5280 Section 4.2.1.10].
11 ///
12 /// ```text
13 /// NameConstraints ::= SEQUENCE {
14 ///      permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
15 ///      excludedSubtrees        [1]     GeneralSubtrees OPTIONAL
16 /// }
17 /// ```
18 ///
19 /// [RFC 5280 Section 4.2.1.10]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.10
20 #[derive(Clone, Debug, Eq, PartialEq, Sequence)]
21 #[allow(missing_docs)]
22 pub struct NameConstraints {
23     #[asn1(context_specific = "0", optional = "true", tag_mode = "IMPLICIT")]
24     pub permitted_subtrees: Option<GeneralSubtrees>,
25 
26     #[asn1(context_specific = "1", optional = "true", tag_mode = "IMPLICIT")]
27     pub excluded_subtrees: Option<GeneralSubtrees>,
28 }
29 
30 impl AssociatedOid for NameConstraints {
31     const OID: ObjectIdentifier = ID_CE_NAME_CONSTRAINTS;
32 }
33 
34 impl_extension!(NameConstraints, critical = true);
35 
36 /// GeneralSubtrees as defined in [RFC 5280 Section 4.2.1.10].
37 ///
38 /// ```text
39 /// GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
40 /// ```
41 ///
42 /// [RFC 5280 Section 4.2.1.10]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.10
43 pub type GeneralSubtrees = Vec<GeneralSubtree>;
44 
45 /// GeneralSubtree as defined in [RFC 5280 Section 4.2.1.10].
46 ///
47 /// ```text
48 /// GeneralSubtree ::= SEQUENCE {
49 ///     base                    GeneralName,
50 ///     minimum         [0]     BaseDistance DEFAULT 0,
51 ///     maximum         [1]     BaseDistance OPTIONAL
52 /// }
53 /// ```
54 ///
55 /// [RFC 5280 Section 4.2.1.10]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.10
56 #[derive(Clone, Debug, Eq, PartialEq, Sequence)]
57 #[allow(missing_docs)]
58 pub struct GeneralSubtree {
59     pub base: GeneralName,
60 
61     #[asn1(
62         context_specific = "0",
63         tag_mode = "IMPLICIT",
64         default = "Default::default"
65     )]
66     pub minimum: u32,
67 
68     #[asn1(context_specific = "1", tag_mode = "IMPLICIT", optional = "true")]
69     pub maximum: Option<u32>,
70 }
71