Botan 3.9.0
Crypto and TLS for C&
Botan::GeneralName Class Referencefinal

X.509 GeneralName Type. More...

#include <pkix_types.h>

Inheritance diagram for Botan::GeneralName:
Botan::ASN1_Object

Public Types

enum  MatchResult : uint8_t {
  All , Some , None , NotFound ,
  UnknownType
}
enum class  NameType : uint8_t {
  Unknown = 0 , RFC822 = 1 , DNS = 2 , URI = 3 ,
  DN = 4 , IPv4 = 5 , Other = 6
}

Public Member Functions

std::vector< uint8_t > BER_encode () const
void decode_from (BER_Decoder &from) override
void encode_into (DER_Encoder &to) const override
 GeneralName ()=default
MatchResult matches (const X509_Certificate &cert) const
bool matches_dn (const X509_DN &dn) const
bool matches_dns (const std::string &dns_name) const
bool matches_ipv4 (uint32_t ip) const
std::string name () const
std::string type () const
NameType type_code () const

Detailed Description

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 RFC 5280, sec. 4.2.1.10 (Name Contraints).

This entire class is deprecated and will be removed in a future major release

Definition at line 260 of file pkix_types.h.

Member Enumeration Documentation

◆ MatchResult

Enumerator
All 
Some 
None 
NotFound 
UnknownType 

Definition at line 262 of file pkix_types.h.

◆ NameType

enum class Botan::GeneralName::NameType : uint8_t
strong
Enumerator
Unknown 
RFC822 
DNS 
URI 
DN 
IPv4 
Other 

Definition at line 270 of file pkix_types.h.

270 : uint8_t {
271 Unknown = 0,
272 RFC822 = 1,
273 DNS = 2,
274 URI = 3,
275 DN = 4,
276 IPv4 = 5,
277 Other = 6,
278 };

Constructor & Destructor Documentation

◆ GeneralName()

Botan::GeneralName::GeneralName ( )
default

References decode_from(), encode_into(), and GeneralName().

Referenced by GeneralName().

Member Function Documentation

◆ BER_encode()

std::vector< uint8_t > Botan::ASN1_Object::BER_encode ( ) const
inherited

Return the encoding of this object. This is a convenience method when just one object needs to be serialized. Use DER_Encoder for complicated encodings.

Definition at line 19 of file asn1_obj.cpp.

19 {
20 std::vector<uint8_t> output;
21 DER_Encoder der(output);
22 this->encode_into(der);
23 return output;
24}
virtual void encode_into(DER_Encoder &to) const =0

References encode_into().

Referenced by decode_from(), Botan::Certificate_Store_In_SQL::find_all_certs(), Botan::Certificate_Store_In_SQL::find_cert(), Botan::X509_Certificate::fingerprint(), Botan::Certificate_Store_In_SQL::insert_cert(), Botan::X509_Object::PEM_encode(), Botan::PSS_Params::PSS_Params(), and Botan::Certificate_Store_In_SQL::revoke_cert().

◆ decode_from()

void Botan::GeneralName::decode_from ( BER_Decoder & from)
overridevirtual

Decode whatever this object is from from

Parameters
fromthe BER_Decoder that will be read from

Implements Botan::ASN1_Object.

Definition at line 76 of file name_constraint.cpp.

76 {
77 BER_Object obj = ber.get_next_object();
78
80 m_type = NameType::Other;
81 } else if(obj.is_a(1, ASN1_Class::ContextSpecific)) {
82 m_type = NameType::RFC822;
83 m_name.emplace<RFC822_IDX>(ASN1::to_string(obj));
84 } else if(obj.is_a(2, ASN1_Class::ContextSpecific)) {
85 m_type = NameType::DNS;
86 // Store it in case insensitive form so we don't have to do it
87 // again while matching
88 m_name.emplace<DNS_IDX>(canonicalize_dns_name(ASN1::to_string(obj)));
89 } else if(obj.is_a(6, ASN1_Class::ContextSpecific)) {
90 m_type = NameType::URI;
91 m_name.emplace<URI_IDX>(ASN1::to_string(obj));
93 X509_DN dn;
94 BER_Decoder dec(obj);
95 dn.decode_from(dec);
96 m_type = NameType::DN;
97 m_name.emplace<DN_IDX>(dn);
98 } else if(obj.is_a(7, ASN1_Class::ContextSpecific)) {
99 if(obj.length() == 8) {
100 const uint32_t net = load_be<uint32_t>(obj.bits(), 0);
101 const uint32_t mask = load_be<uint32_t>(obj.bits(), 1);
102
103 m_type = NameType::IPv4;
104 m_name.emplace<IPV4_IDX>(std::make_pair(net, mask));
105 } else if(obj.length() == 32) {
106 // IPv6 name constraints are not implemented
107 m_type = NameType::Unknown;
108 } else {
109 throw Decoding_Error("Invalid IP name constraint size " + std::to_string(obj.length()));
110 }
111 } else {
112 m_type = NameType::Unknown;
113 }
114}
BOTAN_FORCE_INLINE BOTAN_FN_ISA_AES void dec(uint8x16_t &B, uint8x16_t K)
Definition aes_armv8.cpp:45
std::string to_string(const BER_Object &obj)
Definition asn1_obj.cpp:185
constexpr auto load_be(ParamTs &&... params)
Definition loadstor.h:504

References Botan::BER_Object::bits(), Botan::Constructed, Botan::ContextSpecific, Botan::X509_DN::decode_from(), DN, DNS, Botan::ExplicitContextSpecific, Botan::BER_Decoder::get_next_object(), IPv4, Botan::BER_Object::is_a(), Botan::BER_Object::length(), Botan::load_be(), Other, RFC822, Botan::ASN1::to_string(), Unknown, and URI.

Referenced by GeneralName().

◆ encode_into()

void Botan::GeneralName::encode_into ( DER_Encoder & to) const
overridevirtual

Encode whatever this object is into to

Parameters
tothe DER_Encoder that will be written to

Implements Botan::ASN1_Object.

Definition at line 72 of file name_constraint.cpp.

72 {
73 throw Not_Implemented("GeneralName encoding");
74}

Referenced by GeneralName().

◆ matches()

GeneralName::MatchResult Botan::GeneralName::matches ( const X509_Certificate & cert) const

Checks whether a given certificate (partially) matches this name.

Parameters
certcertificate to be matched
Returns
the match result

Definition at line 140 of file name_constraint.cpp.

140 {
141 class MatchScore final {
142 public:
143 MatchScore() : m_any(false), m_some(false), m_all(true) {}
144
145 void add(bool m) {
146 m_any = true;
147 m_some |= m;
148 m_all &= m;
149 }
150
151 MatchResult result() const {
152 if(!m_any) {
153 return MatchResult::NotFound;
154 } else if(m_all) {
155 return MatchResult::All;
156 } else if(m_some) {
157 return MatchResult::Some;
158 } else {
159 return MatchResult::None;
160 }
161 }
162
163 private:
164 bool m_any;
165 bool m_some;
166 bool m_all;
167 };
168
169 const X509_DN& dn = cert.subject_dn();
170 const AlternativeName& alt_name = cert.subject_alt_name();
171
172 MatchScore score;
173
174 if(m_type == NameType::DNS) {
175 const auto& constraint = std::get<DNS_IDX>(m_name);
176
177 const auto& alt_names = alt_name.dns();
178
179 for(const std::string& dns : alt_names) {
180 score.add(matches_dns(dns, constraint));
181 }
182
183 if(alt_name.count() == 0) {
184 // Check CN instead...
185 for(const std::string& cn : dn.get_attribute("CN")) {
186 if(!string_to_ipv4(cn).has_value()) {
187 score.add(matches_dns(canonicalize_dns_name(cn), constraint));
188 }
189 }
190 }
191 } else if(m_type == NameType::DN) {
192 const X509_DN& constraint = std::get<DN_IDX>(m_name);
193 score.add(matches_dn(dn, constraint));
194
195 for(const auto& alt_dn : alt_name.directory_names()) {
196 score.add(matches_dn(alt_dn, constraint));
197 }
198 } else if(m_type == NameType::IPv4) {
199 auto [net, mask] = std::get<IPV4_IDX>(m_name);
200
201 if(alt_name.count() == 0) {
202 // Check CN instead...
203 for(const std::string& cn : dn.get_attribute("CN")) {
204 if(auto ipv4 = string_to_ipv4(cn)) {
205 bool match = (ipv4.value() & mask) == net;
206 score.add(match);
207 }
208 }
209 } else {
210 for(uint32_t ipv4 : alt_name.ipv4_address()) {
211 bool match = (ipv4 & mask) == net;
212 score.add(match);
213 }
214 }
215 } else {
216 // URI and email name constraint matching not implemented
218 }
219
220 return score.result();
221}
bool matches_dn(const X509_DN &dn) const
bool matches_dns(const std::string &dns_name) const
std::optional< uint32_t > string_to_ipv4(std::string_view str)
Definition parsing.cpp:156

References All, Botan::AlternativeName::count(), Botan::AlternativeName::directory_names(), DN, DNS, Botan::AlternativeName::dns(), Botan::X509_DN::get_attribute(), IPv4, Botan::AlternativeName::ipv4_address(), matches_dn(), matches_dns(), None, NotFound, Some, Botan::string_to_ipv4(), Botan::X509_Certificate::subject_alt_name(), Botan::X509_Certificate::subject_dn(), and UnknownType.

◆ matches_dn()

bool Botan::GeneralName::matches_dn ( const X509_DN & dn) const

Definition at line 132 of file name_constraint.cpp.

132 {
133 if(m_type == NameType::DN) {
134 const X509_DN& constraint = std::get<DN_IDX>(m_name);
135 return matches_dn(dn, constraint);
136 }
137 return false;
138}

References DN, and matches_dn().

Referenced by matches(), and matches_dn().

◆ matches_dns()

bool Botan::GeneralName::matches_dns ( const std::string & dns_name) const

Definition at line 116 of file name_constraint.cpp.

116 {
117 if(m_type == NameType::DNS) {
118 const auto& constraint = std::get<DNS_IDX>(m_name);
119 return matches_dns(dns_name, constraint);
120 }
121 return false;
122}

References DNS, and matches_dns().

Referenced by matches(), and matches_dns().

◆ matches_ipv4()

bool Botan::GeneralName::matches_ipv4 ( uint32_t ip) const

Definition at line 124 of file name_constraint.cpp.

124 {
125 if(m_type == NameType::IPv4) {
126 auto [net, mask] = std::get<IPV4_IDX>(m_name);
127 return (ip & mask) == net;
128 }
129 return false;
130}

References IPv4.

◆ name()

std::string Botan::GeneralName::name ( ) const
Returns
The name as string. Format depends on type.

Definition at line 53 of file name_constraint.cpp.

53 {
54 const size_t index = m_name.index();
55
56 if(index == RFC822_IDX) {
57 return std::get<RFC822_IDX>(m_name);
58 } else if(index == DNS_IDX) {
59 return std::get<DNS_IDX>(m_name);
60 } else if(index == URI_IDX) {
61 return std::get<URI_IDX>(m_name);
62 } else if(index == DN_IDX) {
63 return std::get<DN_IDX>(m_name).to_string();
64 } else if(index == IPV4_IDX) {
65 auto [net, mask] = std::get<IPV4_IDX>(m_name);
66 return fmt("{}/{}", ipv4_to_string(net), ipv4_to_string(mask));
67 } else {
69 }
70}
#define BOTAN_ASSERT_UNREACHABLE()
Definition assert.h:163
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53
std::string ipv4_to_string(uint32_t ip)
Definition parsing.cpp:225

References BOTAN_ASSERT_UNREACHABLE, Botan::fmt(), and Botan::ipv4_to_string().

Referenced by Botan::operator<<().

◆ type()

std::string Botan::GeneralName::type ( ) const
Returns
Type of the name. Can be DN, DNS, IP, RFC822 or URI.

Definition at line 32 of file name_constraint.cpp.

32 {
33 switch(m_type) {
35 throw Encoding_Error("Could not convert unknown NameType to string");
37 return "RFC822";
38 case NameType::DNS:
39 return "DNS";
40 case NameType::URI:
41 return "URI";
42 case NameType::DN:
43 return "DN";
44 case NameType::IPv4:
45 return "IP";
46 case NameType::Other:
47 return "Other";
48 }
49
51}

References BOTAN_ASSERT_UNREACHABLE, DN, DNS, IPv4, Other, RFC822, Unknown, and URI.

Referenced by Botan::operator<<().

◆ type_code()

NameType Botan::GeneralName::type_code ( ) const
inline
Returns
Type of the name expressed in this restriction

Definition at line 290 of file pkix_types.h.

290{ return m_type; }

References type_code().

Referenced by type_code().


The documentation for this class was generated from the following files: