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