Botan 3.5.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#include <botan/internal/stl_util.h>
15
16namespace Botan {
17
18void AlternativeName::add_uri(std::string_view uri) {
19 if(!uri.empty()) {
20 m_uri.insert(std::string(uri));
21 }
22}
23
24void AlternativeName::add_email(std::string_view addr) {
25 if(!addr.empty()) {
26 m_email.insert(std::string(addr));
27 }
28}
29
30void AlternativeName::add_dns(std::string_view dns) {
31 if(!dns.empty()) {
32 m_dns.insert(tolower_string(dns));
33 }
34}
35
36void AlternativeName::add_other_name(const OID& oid, const ASN1_String& value) {
37 m_othernames.insert(std::make_pair(oid, value));
38}
39
41 m_dn_names.insert(dn);
42}
43
45 m_ipv4_addr.insert(ip);
46}
47
48size_t AlternativeName::count() const {
49 const auto sum = checked_add(
50 m_dns.size(), m_uri.size(), m_email.size(), m_ipv4_addr.size(), m_dn_names.size(), m_othernames.size());
51
52 return BOTAN_ASSERT_IS_SOME(sum);
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) {
87 }
88
89 for(const auto& name : m_dns) {
92 }
93
94 for(const auto& name : m_dn_names) {
96 }
97
98 for(const auto& name : m_uri) {
101 }
102
103 for(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 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 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 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
const std::string & value() const
Definition asn1_obj.h:422
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:30
void add_ipv4_address(uint32_t ipv4)
Add an IP address to this alternative name.
Definition alt_name.cpp:44
void add_email(std::string_view addr)
Add a URI to this AlternativeName.
Definition alt_name.cpp:24
size_t count() const
Definition alt_name.cpp:48
void add_uri(std::string_view uri)
Add a URI to this AlternativeName.
Definition alt_name.cpp:18
void encode_into(DER_Encoder &) const override
Definition alt_name.cpp:59
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:152
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:36
void add_othername(const OID &oid, std::string_view value, ASN1_Type type)
void decode_from(BER_Decoder &) override
Definition alt_name.cpp:112
void add_dn(const X509_DN &dn)
Add a directory name to this AlternativeName.
Definition alt_name.cpp:40
BER_Object get_next_object()
Definition ber_dec.cpp:245
BER_Decoder & decode(bool &out)
Definition ber_dec.h:186
bool more_items() const
Definition ber_dec.cpp:201
BER_Decoder & verify_end()
Definition ber_dec.cpp:211
BER_Decoder start_sequence()
Definition ber_dec.h:123
size_t length() const
Definition asn1_obj.h:153
const uint8_t * bits() const
Definition asn1_obj.h:151
bool is_a(ASN1_Type type_tag, ASN1_Class class_tag) const
Definition asn1_obj.cpp:61
ASN1_Type type() const
Definition asn1_obj.h:147
ASN1_Class get_class() const
Definition asn1_obj.h:149
DER_Encoder & add_object(ASN1_Type type_tag, ASN1_Class class_tag, const uint8_t rep[], size_t length)
Definition der_enc.cpp:222
DER_Encoder & end_explicit()
Definition der_enc.cpp:200
DER_Encoder & start_explicit(uint16_t type_tag)
Definition der_enc.cpp:186
DER_Encoder & start_sequence()
Definition der_enc.h:64
DER_Encoder & end_cons()
Definition der_enc.cpp:171
DER_Encoder & encode(bool b)
Definition der_enc.cpp:250
std::string name
std::string to_string(const BER_Object &obj)
Definition asn1_obj.cpp:185
constexpr std::optional< T > checked_add(T a, T b)
Definition int_utils.h:19
ASN1_Type
Definition asn1_obj.h:44
std::string tolower_string(std::string_view in)
Definition parsing.cpp:241
constexpr auto store_be(ParamTs &&... params)
Definition loadstor.h:707
constexpr auto load_be(ParamTs &&... params)
Definition loadstor.h:467
#define BOTAN_ASSERT_IS_SOME(v)
Definition stl_util.h:389