Botan  1.11.32
x509cert.cpp
Go to the documentation of this file.
1 /*
2 * X.509 Certificates
3 * (C) 1999-2010,2015 Jack Lloyd
4 * (C) 2016 RenĂ© Korthaus, Rohde & Schwarz Cybersecurity
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8 
9 #include <botan/x509cert.h>
10 #include <botan/x509_ext.h>
11 #include <botan/der_enc.h>
12 #include <botan/ber_dec.h>
13 #include <botan/internal/stl_util.h>
14 #include <botan/parsing.h>
15 #include <botan/bigint.h>
16 #include <botan/oids.h>
17 #include <botan/pem.h>
18 #include <botan/hash.h>
19 #include <botan/hex.h>
20 #include <algorithm>
21 #include <iterator>
22 #include <sstream>
23 
24 namespace Botan {
25 
26 namespace {
27 
28 /*
29 * Lookup each OID in the vector
30 */
31 std::vector<std::string> lookup_oids(const std::vector<std::string>& in)
32  {
33  std::vector<std::string> out;
34 
35  for(auto i = in.begin(); i != in.end(); ++i)
36  out.push_back(OIDS::lookup(OID(*i)));
37  return out;
38  }
39 
40 }
41 
42 /*
43 * X509_Certificate Constructor
44 */
45 X509_Certificate::X509_Certificate(DataSource& in) :
46  X509_Object(in, "CERTIFICATE/X509 CERTIFICATE"),
47  m_self_signed(false),
48  m_v3_extensions(false)
49  {
50  do_decode();
51  }
52 
53 /*
54 * X509_Certificate Constructor
55 */
56 X509_Certificate::X509_Certificate(const std::string& in) :
57  X509_Object(in, "CERTIFICATE/X509 CERTIFICATE"),
58  m_self_signed(false),
59  m_v3_extensions(false)
60  {
61  do_decode();
62  }
63 
64 /*
65 * X509_Certificate Constructor
66 */
67 X509_Certificate::X509_Certificate(const std::vector<byte>& in) :
68  X509_Object(in, "CERTIFICATE/X509 CERTIFICATE"),
69  m_self_signed(false),
70  m_v3_extensions(false)
71  {
72  do_decode();
73  }
74 
75 /*
76 * Decode the TBSCertificate data
77 */
78 void X509_Certificate::force_decode()
79  {
80  size_t version;
81  BigInt serial_bn;
82  AlgorithmIdentifier sig_algo_inner;
83  X509_DN dn_issuer, dn_subject;
84  X509_Time start, end;
85 
86  BER_Decoder tbs_cert(m_tbs_bits);
87 
88  tbs_cert.decode_optional(version, ASN1_Tag(0),
90  .decode(serial_bn)
91  .decode(sig_algo_inner)
92  .decode(dn_issuer)
94  .decode(start)
95  .decode(end)
96  .verify_end()
97  .end_cons()
98  .decode(dn_subject);
99 
100  if(version > 2)
101  throw Decoding_Error("Unknown X.509 cert version " + std::to_string(version));
102  if(m_sig_algo != sig_algo_inner)
103  throw Decoding_Error("Algorithm identifier mismatch");
104 
105 
106  m_subject.add(dn_subject.contents());
107  m_issuer.add(dn_issuer.contents());
108 
109  m_subject.add("X509.Certificate.dn_bits", ASN1::put_in_sequence(dn_subject.get_bits()));
110  m_issuer.add("X509.Certificate.dn_bits", ASN1::put_in_sequence(dn_issuer.get_bits()));
111 
112  BER_Object public_key = tbs_cert.get_next_object();
113  if(public_key.type_tag != SEQUENCE || public_key.class_tag != CONSTRUCTED)
114  throw BER_Bad_Tag("X509_Certificate: Unexpected tag for public key",
115  public_key.type_tag, public_key.class_tag);
116 
117  std::vector<byte> v2_issuer_key_id, v2_subject_key_id;
118 
119  tbs_cert.decode_optional_string(v2_issuer_key_id, BIT_STRING, 1);
120  tbs_cert.decode_optional_string(v2_subject_key_id, BIT_STRING, 2);
121 
122  BER_Object v3_exts_data = tbs_cert.get_next_object();
123  if(v3_exts_data.type_tag == 3 &&
124  v3_exts_data.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
125  {
126  BER_Decoder(v3_exts_data.value).decode(m_v3_extensions).verify_end();
127  m_v3_extensions.contents_to(m_subject, m_issuer);
128  }
129  else if(v3_exts_data.type_tag != NO_OBJECT)
130  throw BER_Bad_Tag("Unknown tag in X.509 cert",
131  v3_exts_data.type_tag, v3_exts_data.class_tag);
132 
133  if(tbs_cert.more_items())
134  throw Decoding_Error("TBSCertificate has more items that expected");
135 
136  m_subject.add("X509.Certificate.version", static_cast<u32bit>(version));
137  m_subject.add("X509.Certificate.serial", BigInt::encode(serial_bn));
138  m_subject.add("X509.Certificate.start", start.to_string());
139  m_subject.add("X509.Certificate.end", end.to_string());
140 
141  m_issuer.add("X509.Certificate.v2.key_id", v2_issuer_key_id);
142  m_subject.add("X509.Certificate.v2.key_id", v2_subject_key_id);
143 
144  m_subject.add("X509.Certificate.public_key",
145  hex_encode(public_key.value));
146 
147  std::unique_ptr<Public_Key> pub_key(subject_public_key());
148  m_self_signed = (dn_subject == dn_issuer) && check_signature(*pub_key);
149 
150  if(m_self_signed && version == 0)
151  {
152  m_subject.add("X509v3.BasicConstraints.is_ca", 1);
153  m_subject.add("X509v3.BasicConstraints.path_constraint", Cert_Extension::NO_CERT_PATH_LIMIT);
154  }
155 
156  if(is_CA_cert() &&
157  !m_subject.has_value("X509v3.BasicConstraints.path_constraint"))
158  {
159  const size_t limit = (x509_version() < 3) ?
160  Cert_Extension::NO_CERT_PATH_LIMIT : 0;
161 
162  m_subject.add("X509v3.BasicConstraints.path_constraint", static_cast<u32bit>(limit));
163  }
164  }
165 
166 /*
167 * Return the X.509 version in use
168 */
170  {
171  return (m_subject.get1_u32bit("X509.Certificate.version") + 1);
172  }
173 
174 /*
175 * Return the time this cert becomes valid
176 */
177 std::string X509_Certificate::start_time() const
178  {
179  return m_subject.get1("X509.Certificate.start");
180  }
181 
182 /*
183 * Return the time this cert becomes invalid
184 */
185 std::string X509_Certificate::end_time() const
186  {
187  return m_subject.get1("X509.Certificate.end");
188  }
189 
190 /*
191 * Return information about the subject
192 */
193 std::vector<std::string>
194 X509_Certificate::subject_info(const std::string& what) const
195  {
196  return m_subject.get(X509_DN::deref_info_field(what));
197  }
198 
199 /*
200 * Return information about the issuer
201 */
202 std::vector<std::string>
203 X509_Certificate::issuer_info(const std::string& what) const
204  {
205  return m_issuer.get(X509_DN::deref_info_field(what));
206  }
207 
208 /*
209 * Return the public key in this certificate
210 */
212  {
213  return X509::load_key(
215  }
216 
218  {
219  return hex_decode(m_subject.get1("X509.Certificate.public_key"));
220  }
221 
222 /*
223 * Check if the certificate is for a CA
224 */
226  {
227  if(!m_subject.get1_u32bit("X509v3.BasicConstraints.is_ca"))
228  return false;
229 
231  }
232 
234  {
235  if(constraints() == NO_CONSTRAINTS)
236  return true;
237  return ((constraints() & usage) == usage);
238  }
239 
240 bool X509_Certificate::allowed_extended_usage(const std::string& usage) const
241  {
242  const std::vector<std::string> ex = ex_constraints();
243 
244  if(ex.empty())
245  return true;
246 
247  if(std::find(ex.begin(), ex.end(), usage) != ex.end())
248  return true;
249 
250  return false;
251  }
252 
254  {
255  // These follow suggestions in RFC 5280 4.2.1.12
256 
257  switch(usage)
258  {
260  return true;
261 
264 
267 
270 
272  return is_CA_cert();
273  }
274 
275  return false;
276  }
277 
279  {
280  if(this->constraints() == NO_CONSTRAINTS)
281  {
282  return false;
283  }
284 
285  return ((this->constraints() & constraints) != 0);
286  }
287 
288 bool X509_Certificate::has_ex_constraint(const std::string& ex_constraint) const
289  {
290  const std::vector<std::string> ex = ex_constraints();
291 
292  if(ex.empty())
293  {
294  return false;
295  }
296 
297  if(std::find(ex.begin(), ex.end(), ex_constraint) != ex.end())
298  {
299  return true;
300  }
301 
302  return false;
303  }
304 
305 /*
306 * Return the path length constraint
307 */
309  {
310  return m_subject.get1_u32bit("X509v3.BasicConstraints.path_constraint", 0);
311  }
312 
313 /*
314 * Return if a certificate extension is marked critical
315 */
316 bool X509_Certificate::is_critical(const std::string& ex_name) const
317  {
318  return !!m_subject.get1_u32bit(ex_name + ".is_critical",0);
319  }
320 
321 /*
322 * Return the key usage constraints
323 */
325  {
326  return Key_Constraints(m_subject.get1_u32bit("X509v3.KeyUsage",
327  NO_CONSTRAINTS));
328  }
329 
330 /*
331 * Return the list of extended key usage OIDs
332 */
333 std::vector<std::string> X509_Certificate::ex_constraints() const
334  {
335  return lookup_oids(m_subject.get("X509v3.ExtendedKeyUsage"));
336  }
337 
338 /*
339 * Return the name constraints
340 */
342  {
343  std::vector<GeneralSubtree> permit, exclude;
344 
345  for(const std::string& v: m_subject.get("X509v3.NameConstraints.permitted"))
346  {
347  permit.push_back(GeneralSubtree(v));
348  }
349 
350  for(const std::string& v: m_subject.get("X509v3.NameConstraints.excluded"))
351  {
352  exclude.push_back(GeneralSubtree(v));
353  }
354 
355  return NameConstraints(std::move(permit),std::move(exclude));
356  }
357 
358 /*
359 * Return the list of certificate policies
360 */
361 std::vector<std::string> X509_Certificate::policies() const
362  {
363  return lookup_oids(m_subject.get("X509v3.CertificatePolicies"));
364  }
365 
367  {
368  return m_v3_extensions;
369  }
370 
372  {
373  return m_subject.get1("OCSP.responder", "");
374  }
375 
377  {
378  return m_subject.get1("CRL.DistributionPoint", "");
379  }
380 
381 /*
382 * Return the authority key id
383 */
384 std::vector<byte> X509_Certificate::authority_key_id() const
385  {
386  return m_issuer.get1_memvec("X509v3.AuthorityKeyIdentifier");
387  }
388 
389 /*
390 * Return the subject key id
391 */
392 std::vector<byte> X509_Certificate::subject_key_id() const
393  {
394  return m_subject.get1_memvec("X509v3.SubjectKeyIdentifier");
395  }
396 
397 /*
398 * Return the certificate serial number
399 */
400 std::vector<byte> X509_Certificate::serial_number() const
401  {
402  return m_subject.get1_memvec("X509.Certificate.serial");
403  }
404 
406  {
407  return create_dn(m_issuer);
408  }
409 
410 std::vector<byte> X509_Certificate::raw_issuer_dn() const
411  {
412  return m_issuer.get1_memvec("X509.Certificate.dn_bits");
413  }
414 
416  {
417  return create_dn(m_subject);
418  }
419 
420 std::vector<byte> X509_Certificate::raw_subject_dn() const
421  {
422  return m_subject.get1_memvec("X509.Certificate.dn_bits");
423  }
424 
425 std::string X509_Certificate::fingerprint(const std::string& hash_name) const
426  {
427  std::unique_ptr<HashFunction> hash(HashFunction::create(hash_name));
428  hash->update(this->BER_encode());
429  const auto hex_print = hex_encode(hash->final());
430 
431  std::string formatted_print;
432 
433  for(size_t i = 0; i != hex_print.size(); i += 2)
434  {
435  formatted_print.push_back(hex_print[i]);
436  formatted_print.push_back(hex_print[i+1]);
437 
438  if(i != hex_print.size() - 2)
439  formatted_print.push_back(':');
440  }
441 
442  return formatted_print;
443  }
444 
445 bool X509_Certificate::matches_dns_name(const std::string& name) const
446  {
447  if(name.empty())
448  return false;
449 
450  std::vector<std::string> issued_names = subject_info("DNS");
451 
452  // Fall back to CN only if no DNS names are set (RFC 6125 sec 6.4.4)
453  if(issued_names.empty())
454  issued_names = subject_info("Name");
455 
456  for(size_t i = 0; i != issued_names.size(); ++i)
457  {
458  if(host_wildcard_match(issued_names[i], name))
459  return true;
460  }
461 
462  return false;
463  }
464 
465 /*
466 * Compare two certificates for equality
467 */
469  {
470  return (m_sig == other.m_sig &&
471  m_sig_algo == other.m_sig_algo &&
472  m_self_signed == other.m_self_signed &&
473  m_issuer == other.m_issuer &&
474  m_subject == other.m_subject);
475  }
476 
478  {
479  /* If signature values are not equal, sort by lexicographic ordering of that */
480  if(m_sig != other.m_sig)
481  {
482  if(m_sig < other.m_sig)
483  return true;
484  return false;
485  }
486 
487  // Then compare the signed contents
488  return m_tbs_bits < other.m_tbs_bits;
489  }
490 
491 /*
492 * X.509 Certificate Comparison
493 */
494 bool operator!=(const X509_Certificate& cert1, const X509_Certificate& cert2)
495  {
496  return !(cert1 == cert2);
497  }
498 
499 std::string X509_Certificate::to_string() const
500  {
501  const std::vector<std::string> dn_fields{
502  "Name",
503  "Email",
504  "Organization",
505  "Organizational Unit",
506  "Locality",
507  "State",
508  "Country",
509  "IP",
510  "DNS",
511  "URI",
512  "PKIX.XMPPAddr"
513  };
514 
515  std::ostringstream out;
516 
517  for(auto&& field : dn_fields)
518  {
519  for(auto&& val : subject_info(field))
520  {
521  out << "Subject " << field << ": " << val << "\n";
522  }
523  }
524 
525  for(auto&& field : dn_fields)
526  {
527  for(auto&& val : issuer_info(field))
528  {
529  out << "Issuer " << field << ": " << val << "\n";
530  }
531  }
532 
533  out << "Version: " << this->x509_version() << "\n";
534 
535  out << "Not valid before: " << this->start_time() << "\n";
536  out << "Not valid after: " << this->end_time() << "\n";
537 
538  out << "Constraints:\n";
540  if(constraints == NO_CONSTRAINTS)
541  out << " None\n";
542  else
543  {
544  if(constraints & DIGITAL_SIGNATURE)
545  out << " Digital Signature\n";
546  if(constraints & NON_REPUDIATION)
547  out << " Non-Repudiation\n";
548  if(constraints & KEY_ENCIPHERMENT)
549  out << " Key Encipherment\n";
550  if(constraints & DATA_ENCIPHERMENT)
551  out << " Data Encipherment\n";
552  if(constraints & KEY_AGREEMENT)
553  out << " Key Agreement\n";
554  if(constraints & KEY_CERT_SIGN)
555  out << " Cert Sign\n";
556  if(constraints & CRL_SIGN)
557  out << " CRL Sign\n";
558  if(constraints & ENCIPHER_ONLY)
559  out << " Encipher Only\n";
560  if(constraints & DECIPHER_ONLY)
561  out << " Decipher Only\n";
562  }
563 
564  std::vector<std::string> policies = this->policies();
565  if(!policies.empty())
566  {
567  out << "Policies: " << "\n";
568  for(size_t i = 0; i != policies.size(); i++)
569  out << " " << policies[i] << "\n";
570  }
571 
572  std::vector<std::string> ex_constraints = this->ex_constraints();
573  if(!ex_constraints.empty())
574  {
575  out << "Extended Constraints:\n";
576  for(size_t i = 0; i != ex_constraints.size(); i++)
577  out << " " << ex_constraints[i] << "\n";
578  }
579 
581  if(!name_constraints.permitted().empty() ||
582  !name_constraints.excluded().empty())
583  {
584  out << "Name Constraints:\n";
585 
586  if(!name_constraints.permitted().empty())
587  {
588  out << " Permit";
589  for(auto st: name_constraints.permitted())
590  {
591  out << " " << st.base();
592  }
593  out << "\n";
594  }
595 
596  if(!name_constraints.excluded().empty())
597  {
598  out << " Exclude";
599  for(auto st: name_constraints.excluded())
600  {
601  out << " " << st.base();
602  }
603  out << "\n";
604  }
605  }
606 
607  if(!ocsp_responder().empty())
608  out << "OCSP responder " << ocsp_responder() << "\n";
609  if(!crl_distribution_point().empty())
610  out << "CRL " << crl_distribution_point() << "\n";
611 
612  out << "Signature algorithm: " <<
613  OIDS::lookup(this->signature_algorithm().oid) << "\n";
614 
615  out << "Serial number: " << hex_encode(this->serial_number()) << "\n";
616 
617  if(this->authority_key_id().size())
618  out << "Authority keyid: " << hex_encode(this->authority_key_id()) << "\n";
619 
620  if(this->subject_key_id().size())
621  out << "Subject keyid: " << hex_encode(this->subject_key_id()) << "\n";
622 
623  std::unique_ptr<X509_PublicKey> pubkey(this->subject_public_key());
624  out << "Public Key:\n" << X509::PEM_encode(*pubkey);
625 
626  return out.str();
627  }
628 
629 /*
630 * Create and populate a X509_DN
631 */
633  {
634  auto names = info.search_for(
635  [](const std::string& key, const std::string&)
636  {
637  return (key.find("X520.") != std::string::npos);
638  });
639 
640  X509_DN dn;
641 
642  for(auto i = names.begin(); i != names.end(); ++i)
643  dn.add_attribute(i->first, i->second);
644 
645  return dn;
646  }
647 
648 /*
649 * Create and populate an AlternativeName
650 */
652  {
653  auto names = info.search_for(
654  [](const std::string& key, const std::string&)
655  {
656  return (key == "RFC822" ||
657  key == "DNS" ||
658  key == "URI" ||
659  key == "IP");
660  });
661 
662  AlternativeName alt_name;
663 
664  for(auto i = names.begin(); i != names.end(); ++i)
665  alt_name.add_attribute(i->first, i->second);
666 
667  return alt_name;
668  }
669 
670 }
X509_DN issuer_dn() const
Definition: x509cert.cpp:405
std::vector< byte > BER_encode() const
Definition: x509_obj.cpp:113
X509_DN subject_dn() const
Definition: x509cert.cpp:415
bool allowed_usage(Key_Constraints usage) const
Definition: x509cert.cpp:233
AlgorithmIdentifier m_sig_algo
Definition: x509_obj.h:96
std::vector< byte > raw_issuer_dn() const
Definition: x509cert.cpp:410
u32bit path_limit() const
Definition: x509cert.cpp:308
std::vector< std::string > ex_constraints() const
Definition: x509cert.cpp:333
bool is_critical(const std::string &ex_name) const
Definition: x509cert.cpp:316
void add_attribute(const std::string &, const std::string &)
std::vector< byte > serial_number() const
Definition: x509cert.cpp:400
friend class BER_Decoder
Definition: x509cert.h:284
static std::vector< byte > encode(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:54
size_t hex_decode(byte output[], const char input[], size_t input_length, size_t &input_consumed, bool ignore_ws)
Definition: hex.cpp:49
bool operator!=(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
Definition: alg_id.cpp:82
std::string crl_distribution_point() const
Definition: x509cert.cpp:376
Public_Key * load_key(DataSource &source)
Definition: x509_key.cpp:41
std::vector< std::string > issuer_info(const std::string &name) const
Definition: x509cert.cpp:203
std::string end_time() const
Definition: x509cert.cpp:185
const std::vector< GeneralSubtree > & excluded() const
Excluded names.
bool has_value(const std::string &) const
Definition: datastor.cpp:27
BER_Decoder & decode(bool &v)
Definition: ber_dec.cpp:373
void add_attribute(const std::string &, const std::string &)
Definition: x509_dn.cpp:47
std::uint32_t u32bit
Definition: types.h:33
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:47
std::vector< byte > get_bits() const
Definition: x509_dn.cpp:111
std::string to_string() const
Definition: x509cert.cpp:499
bool matches_dns_name(const std::string &name) const
Definition: x509cert.cpp:445
bool check_signature(const Public_Key &key) const
Definition: x509_obj.cpp:187
secure_vector< byte > value
Definition: asn1_obj.h:91
NameConstraints name_constraints() const
Definition: x509cert.cpp:341
std::string ocsp_responder() const
Definition: x509cert.cpp:371
Extensions v3_extensions() const
Definition: x509cert.cpp:366
Key_Constraints constraints() const
Definition: x509cert.cpp:324
bool operator<(const X509_Certificate &other) const
Definition: x509cert.cpp:477
bool is_CA_cert() const
Definition: x509cert.cpp:225
std::vector< byte > raw_subject_dn() const
Definition: x509cert.cpp:420
std::multimap< std::string, std::string > search_for(std::function< bool(std::string, std::string)> predicate) const
Definition: datastor.cpp:35
BER_Decoder & decode_optional(T &out, ASN1_Tag type_tag, ASN1_Tag class_tag, const T &default_value=T())
Definition: ber_dec.h:181
bool has_ex_constraint(const std::string &ex_constraint) const
Definition: x509cert.cpp:288
bool has_constraints(Key_Constraints constraints) const
Returns true if the specified.
Definition: x509cert.cpp:278
AlgorithmIdentifier signature_algorithm() const
Definition: x509_obj.cpp:147
std::vector< byte > get1_memvec(const std::string &) const
Definition: datastor.cpp:92
bool allowed_extended_usage(const std::string &usage) const
Definition: x509cert.cpp:240
BER_Decoder & end_cons()
Definition: ber_dec.cpp:269
X509_DN create_dn(const Data_Store &info)
Definition: x509cert.cpp:632
std::vector< std::string > get(const std::string &) const
Definition: datastor.cpp:50
AlternativeName create_alt_name(const Data_Store &info)
Definition: x509cert.cpp:651
std::string lookup(const OID &oid)
Definition: oids.cpp:155
const std::vector< GeneralSubtree > & permitted() const
Permitted names.
ASN1_Tag
Definition: asn1_obj.h:22
std::vector< byte > subject_public_key_bits() const
Definition: x509cert.cpp:217
std::string start_time() const
Definition: x509cert.cpp:177
std::vector< byte > m_tbs_bits
Definition: x509_obj.h:97
static std::unique_ptr< HashFunction > create(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:82
std::vector< byte > authority_key_id() const
Definition: x509cert.cpp:384
std::vector< std::string > policies() const
Definition: x509cert.cpp:361
std::vector< byte > m_sig
Definition: x509_obj.h:97
BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: ber_dec.cpp:255
std::string PEM_encode(const Public_Key &key)
Definition: x509_key.cpp:32
Definition: alg_id.cpp:13
std::vector< byte > subject_key_id() const
Definition: x509cert.cpp:392
void contents_to(Data_Store &, Data_Store &) const
Definition: x509_ext.cpp:189
u32bit x509_version() const
Definition: x509cert.cpp:169
A single Name Constraints.
std::string to_string() const
Return an internal string representation of the time.
Definition: asn1_time.cpp:60
BER_Object get_next_object()
Definition: ber_dec.cpp:207
ASN1_Tag class_tag
Definition: asn1_obj.h:88
ASN1_Tag type_tag
Definition: asn1_obj.h:88
std::string get1(const std::string &key) const
Definition: datastor.cpp:62
std::string fingerprint(const std::string &="SHA-1") const
Definition: x509cert.cpp:425
Public_Key * subject_public_key() const
Definition: x509cert.cpp:211
BER_Decoder & verify_end()
Definition: ber_dec.cpp:165
u32bit get1_u32bit(const std::string &, u32bit=0) const
Definition: datastor.cpp:109
static std::string deref_info_field(const std::string &)
Definition: x509_dn.cpp:119
BER_Decoder & decode_optional_string(std::vector< byte, Alloc > &out, ASN1_Tag real_type, u16bit type_no, ASN1_Tag class_tag=CONTEXT_SPECIFIC)
Definition: ber_dec.h:130
bool host_wildcard_match(const std::string &issued, const std::string &host)
Definition: parsing.cpp:335
bool operator==(const X509_Certificate &other) const
Definition: x509cert.cpp:468
bool more_items() const
Definition: ber_dec.cpp:155
std::vector< byte > put_in_sequence(const std::vector< byte > &contents)
Definition: asn1_obj.cpp:35
std::vector< std::string > subject_info(const std::string &name) const
Definition: x509cert.cpp:194
MechanismType hash
Usage_Type
Definition: x509cert.h:24
std::multimap< std::string, std::string > contents() const
Definition: x509_dn.cpp:85
void add(const std::multimap< std::string, std::string > &)
Definition: datastor.cpp:155
Name Constraints.
void hex_encode(char output[], const byte input[], size_t input_length, bool uppercase)
Definition: hex.cpp:14