aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/cert/x509/name_constraint.h
blob: 345e64ff50af2ac6012350eadfd098a36d3d00c6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* X.509 Name Constraint
* (C) 2015 Kai Michaelis
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#ifndef BOTAN_NAME_CONSTRAINT_H__
#define BOTAN_NAME_CONSTRAINT_H__

#include <botan/asn1_obj.h>
#include <ostream>

namespace Botan {

   class X509_Certificate;

   /**
    * @brief X.509 GeneralName Type
    *
    * Handles parsing GeneralName types in their BER and canonical string
    * encoding. Allows matching GeneralNames against each other using
    * the rules laid out in the X.509 4.2.1.10 (Name Contraints).
    */
   class BOTAN_DLL GeneralName : public ASN1_Object
      {
      public:
         enum MatchResult : int
            {
            All,
            Some,
            None,
            NotFound,
            UnknownType,
            };

         GeneralName() : m_type(), m_name() {}

         /// Constructs a new GeneralName for its string format.
         GeneralName(const std::string& s);

         void encode_into(class DER_Encoder&) const override;
         void decode_from(class BER_Decoder&) override;

         /// Type of the name. Can be DN, DNS, IP, RFC822, URI.
         const std::string& type() const { return m_type; }

         /// The name as string. Format depends on type.
         const std::string& name() const { return m_name; }

         /// Checks whenever a given certificate (partially) matches this name.
         MatchResult matches(const X509_Certificate&) const;

      private:
         std::string m_type;
         std::string m_name;

         bool matches_dns(const std::string&) const;
         bool matches_dn(const std::string&) const;
         bool matches_ip(const std::string&) const;
      };

   std::ostream& operator<<(std::ostream& os, const GeneralName& gn);

   /**
    * @brief A single Name Constraints
    *
    * THe Name Constraint extension adds a minimum and maximum path
    * length to a GeneralName to form a constraint. The length limits
    * are currently unused.
    */
   class BOTAN_DLL GeneralSubtree : public ASN1_Object
      {
      public:
         GeneralSubtree() : m_base(), m_minimum(0), m_maximum(std::numeric_limits<std::size_t>::max())
         {}

         /// Constructs a new Name Constraint
         GeneralSubtree(GeneralName b,size_t min,size_t max)
         : m_base(b), m_minimum(min), m_maximum(max)
         {}

         /// Constructs a new GeneralSubtree for its string format.
         GeneralSubtree(const std::string&);

         void encode_into(class DER_Encoder&) const override;
         void decode_from(class BER_Decoder&) override;

         /// Name
         GeneralName base() const { return m_base; }

         // Minimum path length
         size_t minimum() const { return m_minimum; }

         // Maximum path length
         size_t maximum() const { return m_maximum; }

      private:
         GeneralName m_base;
         size_t m_minimum;
         size_t m_maximum;
      };

   std::ostream& operator<<(std::ostream& os, const GeneralSubtree& gs);

   /**
    * @brief Name Constraints
    *
    * Wraps the Name Constraints associated with a certificate.
    */
   class BOTAN_DLL NameConstraints
      {
      public:
         NameConstraints() : m_permitted_subtrees(), m_excluded_subtrees() {}

         NameConstraints(std::vector<GeneralSubtree>&& ps, std::vector<GeneralSubtree>&& es)
         : m_permitted_subtrees(ps), m_excluded_subtrees(es)
         {}

         /// Permitted names
         const std::vector<GeneralSubtree>& permitted() const { return m_permitted_subtrees; }

         /// Excluded names
         const std::vector<GeneralSubtree>& excluded() const { return m_excluded_subtrees; }

      private:
        std::vector<GeneralSubtree> m_permitted_subtrees;
        std::vector<GeneralSubtree> m_excluded_subtrees;
      };
}

#endif