Async 1.8.0
AsyncSslX509ExtSubjectAltName.h
Go to the documentation of this file.
1
31#ifndef ASYNC_SSL_X509_EXT_SUBJECT_ALT_NAME_INCLUDED
32#define ASYNC_SSL_X509_EXT_SUBJECT_ALT_NAME_INCLUDED
33
34
35/****************************************************************************
36 *
37 * System Includes
38 *
39 ****************************************************************************/
40
41#include <functional>
42
43
44/****************************************************************************
45 *
46 * Project Includes
47 *
48 ****************************************************************************/
49
50
51
52/****************************************************************************
53 *
54 * Local Includes
55 *
56 ****************************************************************************/
57
58
59
60/****************************************************************************
61 *
62 * Forward declarations
63 *
64 ****************************************************************************/
65
66
67
68/****************************************************************************
69 *
70 * Namespace
71 *
72 ****************************************************************************/
73
74namespace Async
75{
76
77
78/****************************************************************************
79 *
80 * Forward declarations of classes inside of the declared namespace
81 *
82 ****************************************************************************/
83
84
85
86/****************************************************************************
87 *
88 * Defines & typedefs
89 *
90 ****************************************************************************/
91
92
93
94/****************************************************************************
95 *
96 * Exported Global Variables
97 *
98 ****************************************************************************/
99
100
101
102/****************************************************************************
103 *
104 * Class definitions
105 *
106 ****************************************************************************/
107
116{
117 public:
118 using ForeachFunction = std::function<void(int, std::string)>;
119
123 //SslX509ExtSubjectAltName(void);
124
132 explicit SslX509ExtSubjectAltName(const std::string& names)
133 {
134 m_ext = X509V3_EXT_conf_nid(NULL, NULL, NID_subject_alt_name,
135 names.c_str());
136 }
137
142 SslX509ExtSubjectAltName(const X509_EXTENSION* ext)
143 {
144#if OPENSSL_VERSION_MAJOR >= 3
145 m_ext = X509_EXTENSION_dup(ext);
146#else
147 m_ext = X509_EXTENSION_dup(const_cast<X509_EXTENSION*>(ext));
148#endif
149 }
150
155 explicit SslX509ExtSubjectAltName(GENERAL_NAMES* names)
156 {
157 int crit = 0;
158 m_ext = X509V3_EXT_i2d(NID_subject_alt_name, crit, names);
159 }
160
166 {
167 m_ext = other.m_ext;
168 other.m_ext = nullptr;
169 }
170
175
180 = delete;
181
186 {
187 if (m_ext != nullptr)
188 {
189 X509_EXTENSION_free(m_ext);
190 m_ext = nullptr;
191 }
192 }
193
198 bool isNull(void) const { return m_ext == nullptr; }
199
200#if 0
201 bool add(const std::string& name)
202 {
203 auto names = reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(m_ext));
204 if (names == nullptr)
205 {
206 names = GENERAL_NAME_new();
207 }
208 auto asn1_str = ASN1_STRING_new();
209 ASN1_STRING_set(asn1_str, name.c_str(), name.size());
210 // How to create a GENERAL_NAME?
211 // GENERAL_NAME* general_name =
212 ASN1_STRING_free(asn1_str);
213 sk_GENERAL_NAME_push(names, general_name);
214 }
215#endif
216
221 operator const X509_EXTENSION*() const { return m_ext; }
222
230 void forEach(ForeachFunction f, int type=-1) const
231 {
232 if (m_ext == nullptr)
233 {
234 return;
235 }
236
237 const auto names = reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(m_ext));
238 const int count = sk_GENERAL_NAME_num(names);
239 for (int i = 0; i < count; ++i)
240 {
241 const GENERAL_NAME* entry = sk_GENERAL_NAME_value(names, i);
242 if ((entry == nullptr) || ((type >= 0) && (entry->type != type)))
243 {
244 continue;
245 }
246
247 std::string name;
248 switch (entry->type)
249 {
250 case GEN_OTHERNAME:
251 break;
252
253 case GEN_EMAIL:
254 name = asn1StringToUtf8(entry->d.rfc822Name);
255 break;
256
257 case GEN_DNS:
258 name = asn1StringToUtf8(entry->d.dNSName);
259 break;
260
261 case GEN_X400:
262 case GEN_DIRNAME:
263 case GEN_EDIPARTY:
264 case GEN_URI:
265 break;
266
267 case GEN_IPADD:
268 {
269 int len = ASN1_STRING_length(entry->d.iPAddress);
270 if (len == 4)
271 {
272 const unsigned char* data =
273 ASN1_STRING_get0_data(entry->d.iPAddress);
274 struct in_addr in_addr = {0};
275 in_addr.s_addr = *reinterpret_cast<const unsigned long*>(data);
276 Async::IpAddress addr(in_addr);
277 name = addr.toString();
278 }
279 else if (len == 16)
280 {
281 // FIXME: IPv6
282 }
283 break;
284 }
285
286 case GEN_RID:
287 break;
288
289 default:
290 // Ignore unknown SAN type
291 break;
292 }
293 if (!name.empty())
294 {
295 f(entry->type, name);
296 }
297 }
298 GENERAL_NAMES_free(names);
299 } /* forEach */
300
308 std::string toString(int type=-1) const
309 {
310 std::string sep;
311 std::string str;
312 forEach(
313 [&](int type, std::string name)
314 {
315 switch (type)
316 {
317 case GEN_OTHERNAME:
318 break;
319
320 case GEN_EMAIL:
321 str += sep + "email:" + name;
322 break;
323
324 case GEN_DNS:
325 str += sep + "DNS:" + name;
326 break;
327
328 case GEN_X400:
329 case GEN_DIRNAME:
330 case GEN_EDIPARTY:
331 case GEN_URI:
332 break;
333
334 case GEN_IPADD:
335 str += sep + "IP Address:" + name;
336 break;
337
338 case GEN_RID:
339 break;
340
341 default:
342 // Ignore unknown SAN type
343 break;
344 }
345 sep = ", ";
346 },
347 type);
348 return str;
349 } /* toString */
350
351 private:
352 X509_EXTENSION* m_ext = nullptr;
353
354 std::string asn1StringToUtf8(ASN1_IA5STRING* asn1str) const
355 {
356 std::string str;
357 if (asn1str == nullptr)
358 {
359 return str;
360 }
361 unsigned char* utf8 = nullptr;
362 const int len = ASN1_STRING_to_UTF8(&utf8, asn1str);
363 if ((utf8 != nullptr) && (len > 0))
364 {
365 str.assign(utf8, utf8+len);
366 }
367 OPENSSL_free(utf8);
368 return str;
369 }
370
371}; /* class SslX509ExtSubjectAltName */
372
373
374} /* namespace Async */
375
376#endif /* ASYNC_SSL_X509_EXT_SUBJECT_ALT_NAME_INCLUDED */
377
378/*
379 * This file has not been truncated
380 */
A class for representing an IP address in an OS independent way.
std::string toString(void) const
Return the string representation of the IP address.
A class representing the X.509 Subject Alternative Name extension.
void forEach(ForeachFunction f, int type=-1) const
Loop through all names calling the given function for each one.
bool isNull(void) const
Check if the object is initialized.
SslX509ExtSubjectAltName(const std::string &names)
Default constructor.
SslX509ExtSubjectAltName & operator=(const SslX509ExtSubjectAltName &)=delete
Disallow copy assignment.
std::string toString(int type=-1) const
Convert all SANs to a string.
SslX509ExtSubjectAltName(const SslX509ExtSubjectAltName &)=delete
Disallow copy construction.
SslX509ExtSubjectAltName(SslX509ExtSubjectAltName &&other)
Move Constructor.
SslX509ExtSubjectAltName(const X509_EXTENSION *ext)
Constructor.
SslX509ExtSubjectAltName(GENERAL_NAMES *names)
Constructor.
std::function< void(int, std::string)> ForeachFunction
Namespace for the asynchronous programming classes.