Botan 3.11.0
Crypto and TLS for C&
alt_name.cpp
Go to the documentation of this file.
1/*
2* (C) 2024 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/pkix_types.h>
8
9#include <botan/ber_dec.h>
10#include <botan/der_enc.h>
11#include <botan/internal/int_utils.h>
12#include <botan/internal/loadstor.h>
13#include <botan/internal/parsing.h>
14
15namespace Botan {
16
17void AlternativeName::add_uri(std::string_view uri) {
18 if(!uri.empty()) {
19 m_uri.insert(std::string(uri));
20 }
21}
22
23void AlternativeName::add_email(std::string_view addr) {
24 if(!addr.empty()) {
25 m_email.insert(std::string(addr));
26 }
27}
28
29void AlternativeName::add_dns(std::string_view dns) {
30 if(!dns.empty()) {
31 m_dns.insert(tolower_string(dns));
32 }
33}
34
35void AlternativeName::add_other_name(const OID& oid, const ASN1_String& value) {
36 m_othernames.insert(std::make_pair(oid, value));
37}
38
40 m_dn_names.insert(dn);
41}
42
44 m_ipv4_addr.insert(ip);
45}
46
47size_t AlternativeName::count() const {
48 const auto sum = checked_add(
49 m_dns.size(), m_uri.size(), m_email.size(), m_ipv4_addr.size(), m_dn_names.size(), m_othernames.size());
50
51 BOTAN_ASSERT_NOMSG(sum.has_value());
52 return sum.value();
53}
54
56 return this->count() > 0;
57}
58
60 der.start_sequence();
61
62 /*
63 GeneralName ::= CHOICE {
64 otherName [0] OtherName,
65 rfc822Name [1] IA5String,
66 dNSName [2] IA5String,
67 x400Address [3] ORAddress,
68 directoryName [4] Name,
69 ediPartyName [5] EDIPartyName,
70 uniformResourceIdentifier [6] IA5String,
71 iPAddress [7] OCTET STRING,
72 registeredID [8] OBJECT IDENTIFIER }
73 */
74
75 for(const auto& othername : m_othernames) {
76 der.start_explicit(0)
77 .encode(othername.first)
79 .encode(othername.second)
81 .end_explicit();
82 }
83
84 for(const auto& name : m_email) {
85 const ASN1_String str(name, ASN1_Type::Ia5String);
87 }
88
89 for(const auto& name : m_dns) {
90 const ASN1_String str(name, ASN1_Type::Ia5String);
92 }
93
94 for(const auto& name : m_dn_names) {
96 }
97
98 for(const auto& name : m_uri) {
99 const ASN1_String str(name, ASN1_Type::Ia5String);
101 }
102
103 for(const uint32_t ip : m_ipv4_addr) {
104 auto ip_buf = store_be(ip);
105 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
106 der.add_object(ASN1_Type(7), ASN1_Class::ContextSpecific, ip_buf.data(), 4);
107 }
108
109 der.end_cons();
110}
111
113 BER_Decoder names = source.start_sequence();
114
115 while(names.more_items()) {
116 const BER_Object obj = names.get_next_object();
117
119 BER_Decoder othername(obj);
120
121 OID oid;
122 othername.decode(oid);
123 if(othername.more_items()) {
124 const BER_Object othername_value_outer = othername.get_next_object();
125 othername.verify_end();
126
127 if(!othername_value_outer.is_a(0, ASN1_Class::ExplicitContextSpecific)) {
128 throw Decoding_Error("Invalid tags on otherName value");
129 }
130
131 BER_Decoder othername_value_inner(othername_value_outer);
132
133 const BER_Object value = othername_value_inner.get_next_object();
134 othername_value_inner.verify_end();
135
137 add_othername(oid, ASN1::to_string(value), value.type());
138 }
139 }
140 } else if(obj.is_a(1, ASN1_Class::ContextSpecific)) {
142 } else if(obj.is_a(2, ASN1_Class::ContextSpecific)) {
145 BER_Decoder dec(obj);
146 X509_DN dn;
147 dec.decode(dn);
148 this->add_dn(dn);
149 } else if(obj.is_a(6, ASN1_Class::ContextSpecific)) {
150 this->add_uri(ASN1::to_string(obj));
151 } else if(obj.is_a(7, ASN1_Class::ContextSpecific)) {
152 if(obj.length() == 4) {
153 const uint32_t ip = load_be<uint32_t>(obj.bits(), 0);
154 this->add_ipv4_address(ip);
155 } else if(obj.length() != 16) {
156 throw Decoding_Error("Invalid IP constraint neither IPv4 or IPv6");
157 }
158 }
159 }
160}
161
162} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
const std::string & value() const
Definition asn1_obj.h:365
static bool is_string_type(ASN1_Type tag)
Definition asn1_str.cpp:60
void add_dns(std::string_view dns)
Add a DNS name to this AlternativeName.
Definition alt_name.cpp:29
void add_ipv4_address(uint32_t ipv4)
Add an IP address to this alternative name.
Definition alt_name.cpp:43
void add_email(std::string_view addr)
Add a URI to this AlternativeName.
Definition alt_name.cpp:23
size_t count() const
Definition alt_name.cpp:47
void encode_into(DER_Encoder &to) const override
Definition alt_name.cpp:59
void add_uri(std::string_view uri)
Add a URI to this AlternativeName.
Definition alt_name.cpp:17
bool has_items() const
Return true if this has any names set.
Definition alt_name.cpp:55
const std::set< std::string > & dns() const
Return the set of DNS names included in this alternative name.
Definition pkix_types.h:175
void add_other_name(const OID &oid, const ASN1_String &value)
Add an "OtherName" identified by object identifier to this AlternativeName.
Definition alt_name.cpp:35
void add_othername(const OID &oid, std::string_view value, ASN1_Type type)
void add_dn(const X509_DN &dn)
Add a directory name to this AlternativeName.
Definition alt_name.cpp:39
void decode_from(BER_Decoder &from) override
Definition alt_name.cpp:112
BER_Object get_next_object()
Definition ber_dec.cpp:261
BER_Decoder & decode(bool &out)
Definition ber_dec.h:188
bool more_items() const
Definition ber_dec.cpp:207
BER_Decoder & verify_end()
Definition ber_dec.cpp:217
BER_Decoder start_sequence()
Definition ber_dec.h:128
size_t length() const
Definition asn1_obj.h:152
const uint8_t * bits() const
Definition asn1_obj.h:150
bool is_a(ASN1_Type type_tag, ASN1_Class class_tag) const
Definition asn1_obj.cpp:66
ASN1_Type type() const
Definition asn1_obj.h:146
ASN1_Class get_class() const
Definition asn1_obj.h:148
DER_Encoder & add_object(ASN1_Type type_tag, ASN1_Class class_tag, const uint8_t rep[], size_t length)
Definition der_enc.cpp:224
DER_Encoder & end_explicit()
Definition der_enc.cpp:202
DER_Encoder & start_explicit(uint16_t type_tag)
Definition der_enc.cpp:188
DER_Encoder & start_sequence()
Definition der_enc.h:67
DER_Encoder & end_cons()
Definition der_enc.cpp:173
DER_Encoder & encode(bool b)
Definition der_enc.cpp:252
std::string to_string(const BER_Object &obj)
Definition asn1_obj.cpp:190
constexpr std::optional< T > checked_add(T a, T b)
Definition int_utils.h:19
std::string tolower_string(std::string_view str)
Definition parsing.cpp:241
ASN1_Type
Definition asn1_obj.h:43
std::string check_and_canonicalize_dns_name(std::string_view name)
Definition parsing.cpp:369
constexpr auto store_be(ParamTs &&... params)
Definition loadstor.h:745
constexpr auto load_be(ParamTs &&... params)
Definition loadstor.h:504