Botan 3.5.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 : int {
  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 &) override
 
void encode_into (DER_Encoder &) 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 251 of file pkix_types.h.

Member Enumeration Documentation

◆ MatchResult

Enumerator
All 
Some 
None 
NotFound 
UnknownType 

Definition at line 253 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 261 of file pkix_types.h.

Constructor & Destructor Documentation

◆ GeneralName()

Botan::GeneralName::GeneralName ( )
default

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 Botan::ASN1_Object::encode_into().

Referenced by Botan::PSS_Params::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(), 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 68 of file name_constraint.cpp.

68 {
69 BER_Object obj = ber.get_next_object();
70
72 m_type = NameType::Other;
73 } else if(obj.is_a(1, ASN1_Class::ContextSpecific)) {
74 m_type = NameType::RFC822;
75 m_name.emplace<RFC822_IDX>(ASN1::to_string(obj));
76 } else if(obj.is_a(2, ASN1_Class::ContextSpecific)) {
77 m_type = NameType::DNS;
78 // Store it in case insensitive form so we don't have to do it
79 // again while matching
80 m_name.emplace<DNS_IDX>(tolower_string(ASN1::to_string(obj)));
81 } else if(obj.is_a(6, ASN1_Class::ContextSpecific)) {
82 m_type = NameType::URI;
83 m_name.emplace<URI_IDX>(ASN1::to_string(obj));
85 X509_DN dn;
86 BER_Decoder dec(obj);
87 dn.decode_from(dec);
88 m_type = NameType::DN;
89 m_name.emplace<DN_IDX>(dn);
90 } else if(obj.is_a(7, ASN1_Class::ContextSpecific)) {
91 if(obj.length() == 8) {
92 const uint32_t net = load_be<uint32_t>(obj.bits(), 0);
93 const uint32_t mask = load_be<uint32_t>(obj.bits(), 1);
94
95 m_type = NameType::IPv4;
96 m_name.emplace<IPV4_IDX>(std::make_pair(net, mask));
97 } else if(obj.length() == 32) {
98 // IPv6 name constraints are not implemented
99 m_type = NameType::Unknown;
100 } else {
101 throw Decoding_Error("Invalid IP name constraint size " + std::to_string(obj.length()));
102 }
103 } else {
104 m_type = NameType::Unknown;
105 }
106}
std::string to_string(const BER_Object &obj)
Definition asn1_obj.cpp:185
std::string tolower_string(std::string_view in)
Definition parsing.cpp:241
constexpr auto load_be(ParamTs &&... params)
Definition loadstor.h:467

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(), Botan::tolower_string(), Unknown, and URI.

◆ 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 64 of file name_constraint.cpp.

64 {
65 throw Not_Implemented("GeneralName encoding");
66}

◆ 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 132 of file name_constraint.cpp.

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

References Botan::AlternativeName::count(), Botan::AlternativeName::directory_names(), DN, DNS, Botan::AlternativeName::dns(), final, Botan::X509_DN::get_attribute(), IPv4, Botan::AlternativeName::ipv4_address(), matches_dn(), matches_dns(), 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 124 of file name_constraint.cpp.

124 {
125 if(m_type == NameType::DN) {
126 const X509_DN& constraint = std::get<DN_IDX>(m_name);
127 return matches_dn(dn, constraint);
128 }
129 return false;
130}

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 108 of file name_constraint.cpp.

108 {
109 if(m_type == NameType::DNS) {
110 const auto& constraint = std::get<DNS_IDX>(m_name);
111 return matches_dns(dns_name, constraint);
112 }
113 return false;
114}

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 116 of file name_constraint.cpp.

116 {
117 if(m_type == NameType::IPv4) {
118 auto [net, mask] = std::get<IPV4_IDX>(m_name);
119 return (ip & mask) == net;
120 }
121 return false;
122}

References IPv4.

◆ name()

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

Definition at line 45 of file name_constraint.cpp.

45 {
46 const size_t index = m_name.index();
47
48 if(index == RFC822_IDX) {
49 return std::get<RFC822_IDX>(m_name);
50 } else if(index == DNS_IDX) {
51 return std::get<DNS_IDX>(m_name);
52 } else if(index == URI_IDX) {
53 return std::get<URI_IDX>(m_name);
54 } else if(index == DN_IDX) {
55 return std::get<DN_IDX>(m_name).to_string();
56 } else if(index == IPV4_IDX) {
57 auto [net, mask] = std::get<IPV4_IDX>(m_name);
58 return fmt("{}/{}", ipv4_to_string(net), ipv4_to_string(mask));
59 } else {
61 }
62}
#define BOTAN_ASSERT_UNREACHABLE()
Definition assert.h:137
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 24 of file name_constraint.cpp.

24 {
25 switch(m_type) {
27 throw Encoding_Error("Could not convert unknown NameType to string");
29 return "RFC822";
30 case NameType::DNS:
31 return "DNS";
32 case NameType::URI:
33 return "URI";
34 case NameType::DN:
35 return "DN";
36 case NameType::IPv4:
37 return "IP";
38 case NameType::Other:
39 return "Other";
40 }
41
43}

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 281 of file pkix_types.h.

281{ return m_type; }

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