Botan  2.4.0
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,2017 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/datastor.h>
11 #include <botan/pk_keys.h>
12 #include <botan/x509_ext.h>
13 #include <botan/ber_dec.h>
14 #include <botan/parsing.h>
15 #include <botan/bigint.h>
16 #include <botan/oids.h>
17 #include <botan/hash.h>
18 #include <botan/hex.h>
19 #include <algorithm>
20 #include <sstream>
21 
22 namespace Botan {
23 
24 struct X509_Certificate_Data
25  {
26  std::vector<uint8_t> m_serial;
27  AlgorithmIdentifier m_sig_algo_inner;
28  X509_DN m_issuer_dn;
29  X509_DN m_subject_dn;
30  std::vector<uint8_t> m_issuer_dn_bits;
31  std::vector<uint8_t> m_subject_dn_bits;
32  X509_Time m_not_before;
33  X509_Time m_not_after;
34  std::vector<uint8_t> m_subject_public_key_bits;
35  std::vector<uint8_t> m_subject_public_key_bitstring;
36  std::vector<uint8_t> m_subject_public_key_bitstring_sha1;
37  AlgorithmIdentifier m_subject_public_key_algid;
38 
39  std::vector<uint8_t> m_v2_issuer_key_id;
40  std::vector<uint8_t> m_v2_subject_key_id;
41  Extensions m_v3_extensions;
42 
43  std::vector<OID> m_extended_key_usage;
44  std::vector<uint8_t> m_authority_key_id;
45  std::vector<uint8_t> m_subject_key_id;
46  std::vector<OID> m_cert_policies;
47 
48  std::vector<std::string> m_crl_distribution_points;
49  std::string m_ocsp_responder;
50  std::vector<std::string> m_ca_issuers;
51 
52  AlternativeName m_subject_alt_name;
53  AlternativeName m_issuer_alt_name;
54  NameConstraints m_name_constraints;
55 
56  Data_Store m_subject_ds;
57  Data_Store m_issuer_ds;
58 
59  size_t m_version = 0;
60  size_t m_path_len_constraint = 0;
61  Key_Constraints m_key_constraints = NO_CONSTRAINTS;
62  bool m_self_signed = false;
63  bool m_is_ca_certificate = false;
64  bool m_serial_negative = false;
65  };
66 
67 std::string X509_Certificate::PEM_label() const
68  {
69  return "CERTIFICATE";
70  }
71 
72 std::vector<std::string> X509_Certificate::alternate_PEM_labels() const
73  {
74  return { "X509 CERTIFICATE" };
75  }
76 
78  {
79  load_data(src);
80  }
81 
82 X509_Certificate::X509_Certificate(const std::vector<uint8_t>& vec)
83  {
84  DataSource_Memory src(vec.data(), vec.size());
85  load_data(src);
86  }
87 
88 #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
89 X509_Certificate::X509_Certificate(const std::string& fsname)
90  {
91  DataSource_Stream src(fsname, true);
92  load_data(src);
93  }
94 #endif
95 
96 namespace {
97 
98 std::unique_ptr<X509_Certificate_Data> parse_x509_cert_body(const X509_Object& obj)
99  {
100  std::unique_ptr<X509_Certificate_Data> data(new X509_Certificate_Data);
101 
102  BER_Decoder tbs_cert(obj.signed_body());
103  BigInt serial_bn;
104 
105  tbs_cert.decode_optional(data->m_version, ASN1_Tag(0),
107  .decode(serial_bn)
108  .decode(data->m_sig_algo_inner)
109  .decode(data->m_issuer_dn)
110  .start_cons(SEQUENCE)
111  .decode(data->m_not_before)
112  .decode(data->m_not_after)
113  .end_cons()
114  .decode(data->m_subject_dn);
115 
116  if(data->m_version > 2)
117  throw Decoding_Error("Unknown X.509 cert version " + std::to_string(data->m_version));
118  if(obj.signature_algorithm() != data->m_sig_algo_inner)
119  throw Decoding_Error("X.509 Certificate had differing algorithm identifers in inner and outer ID fields");
120  // crude method to save the serial's sign; will get lost during decoding, otherwise
121  data->m_serial_negative = serial_bn.is_negative();
122 
123  // for general sanity convert wire version (0 based) to standards version (v1 .. v3)
124  data->m_version += 1;
125 
126  data->m_serial = BigInt::encode(serial_bn);
127  data->m_subject_dn_bits = ASN1::put_in_sequence(data->m_subject_dn.get_bits());
128  data->m_issuer_dn_bits = ASN1::put_in_sequence(data->m_issuer_dn.get_bits());
129 
130  BER_Object public_key = tbs_cert.get_next_object();
131  if(public_key.type_tag != SEQUENCE || public_key.class_tag != CONSTRUCTED)
132  throw BER_Bad_Tag("X509_Certificate: Unexpected tag for public key",
133  public_key.type_tag, public_key.class_tag);
134 
135  // validate_public_key_params(public_key.value);
136  AlgorithmIdentifier public_key_alg_id;
137  BER_Decoder(public_key.value).decode(public_key_alg_id).discard_remaining();
138 
139  std::vector<std::string> public_key_info =
140  split_on(OIDS::oid2str(public_key_alg_id.get_oid()), '/');
141 
142  if(!public_key_info.empty() && public_key_info[0] == "RSA")
143  {
144  // RFC4055: If PublicKeyAlgo = PSS or OAEP: limit the use of the public key exclusively to either RSASSA - PSS or RSAES - OAEP
145  if(public_key_info.size() >= 2)
146  {
147  if(public_key_info[1] == "EMSA4")
148  {
149  /*
150  When the RSA private key owner wishes to limit the use of the public
151  key exclusively to RSASSA-PSS, then the id-RSASSA-PSS object
152  identifier MUST be used in the algorithm field within the subject
153  public key information, and, if present, the parameters field MUST
154  contain RSASSA-PSS-params.
155 
156  All parameters in the signature structure algorithm identifier MUST
157  match the parameters in the key structure algorithm identifier
158  except the saltLength field. The saltLength field in the signature parameters
159  MUST be greater or equal to that in the key parameters field.
160 
161  ToDo: Allow salt length to be greater
162  */
163  if(public_key_alg_id != obj.signature_algorithm())
164  {
165  throw Decoding_Error("Algorithm identifier mismatch");
166  }
167  }
168  if(public_key_info[1] == "OAEP")
169  {
170  throw Decoding_Error("Decoding subject public keys of type RSAES-OAEP is currently not supported");
171  }
172  }
173  else
174  {
175  // oid = rsaEncryption -> parameters field MUST contain NULL
176  if(public_key_alg_id != AlgorithmIdentifier(public_key_alg_id.get_oid(), AlgorithmIdentifier::USE_NULL_PARAM))
177  {
178  throw Decoding_Error("Parameters field MUST contain NULL");
179  }
180  }
181  }
182 
183  data->m_subject_public_key_bits = unlock(public_key.value);
184 
185  BER_Decoder(data->m_subject_public_key_bits)
186  .decode(data->m_subject_public_key_algid)
187  .decode(data->m_subject_public_key_bitstring, BIT_STRING);
188 
189  tbs_cert.decode_optional_string(data->m_v2_issuer_key_id, BIT_STRING, 1);
190  tbs_cert.decode_optional_string(data->m_v2_subject_key_id, BIT_STRING, 2);
191 
192  BER_Object v3_exts_data = tbs_cert.get_next_object();
193  if(v3_exts_data.type_tag == 3 &&
194  v3_exts_data.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
195  {
196  BER_Decoder(v3_exts_data.value).decode(data->m_v3_extensions).verify_end();
197  }
198  else if(v3_exts_data.type_tag != NO_OBJECT)
199  throw BER_Bad_Tag("Unknown tag in X.509 cert",
200  v3_exts_data.type_tag, v3_exts_data.class_tag);
201 
202  if(tbs_cert.more_items())
203  throw Decoding_Error("TBSCertificate has extra data after extensions block");
204 
205  // Now cache some fields from the extensions
206  if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Key_Usage>())
207  {
208  data->m_key_constraints = ext->get_constraints();
209  }
210  else
211  {
212  data->m_key_constraints = NO_CONSTRAINTS;
213  }
214 
215  if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Subject_Key_ID>())
216  {
217  data->m_subject_key_id = ext->get_key_id();
218  }
219 
220  if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Authority_Key_ID>())
221  {
222  data->m_authority_key_id = ext->get_key_id();
223  }
224 
225  if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Name_Constraints>())
226  {
227  data->m_name_constraints = ext->get_name_constraints();
228  }
229 
230  if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Basic_Constraints>())
231  {
232  if(ext->get_is_ca() == true)
233  {
234  if(data->m_key_constraints == NO_CONSTRAINTS ||
235  (data->m_key_constraints & KEY_CERT_SIGN))
236  {
237  data->m_is_ca_certificate = true;
238  data->m_path_len_constraint = ext->get_path_limit();
239  }
240  }
241  }
242 
243  if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Issuer_Alternative_Name>())
244  {
245  data->m_issuer_alt_name = ext->get_alt_name();
246  }
247 
248  if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Subject_Alternative_Name>())
249  {
250  data->m_subject_alt_name = ext->get_alt_name();
251  }
252 
253  if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Extended_Key_Usage>())
254  {
255  data->m_extended_key_usage = ext->get_oids();
256  }
257 
258  if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Certificate_Policies>())
259  {
260  data->m_cert_policies = ext->get_policy_oids();
261  }
262 
263  if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Authority_Information_Access>())
264  {
265  data->m_ocsp_responder = ext->ocsp_responder();
266  data->m_ca_issuers = ext->ca_issuers();
267  }
268 
269  if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::CRL_Distribution_Points>())
270  {
271  data->m_crl_distribution_points = ext->crl_distribution_urls();
272  }
273 
274  // Check for self-signed vs self-issued certificates
275  if(data->m_subject_dn == data->m_issuer_dn)
276  {
277  data->m_self_signed = false;
278 
279  try
280  {
281  std::unique_ptr<Public_Key> pub_key(
282  X509::load_key(ASN1::put_in_sequence(data->m_subject_public_key_bits)));
283 
284  Certificate_Status_Code sig_status = obj.verify_signature(*pub_key);
285 
286  if(sig_status == Certificate_Status_Code::OK ||
288  {
289  data->m_self_signed = true;
290  }
291  }
292  catch(...)
293  {
294  // ignore errors here to allow parsing to continue
295  }
296  }
297 
298  std::unique_ptr<HashFunction> sha1(HashFunction::create("SHA-1"));
299  if(sha1)
300  {
301  sha1->update(data->m_subject_public_key_bitstring);
302  data->m_subject_public_key_bitstring_sha1 = sha1->final_stdvec();
303  // otherwise left as empty, and we will throw if subject_public_key_bitstring_sha1 is called
304  }
305 
306  data->m_subject_ds.add(data->m_subject_dn.contents());
307  data->m_issuer_ds.add(data->m_issuer_dn.contents());
308  data->m_v3_extensions.contents_to(data->m_subject_ds, data->m_issuer_ds);
309 
310  return data;
311  }
312 
313 }
314 
315 /*
316 * Decode the TBSCertificate data
317 */
318 void X509_Certificate::force_decode()
319  {
320  m_data.reset();
321 
322  std::unique_ptr<X509_Certificate_Data> data = parse_x509_cert_body(*this);
323 
324  m_data.reset(data.release());
325  }
326 
327 const X509_Certificate_Data& X509_Certificate::data() const
328  {
329  if(m_data == nullptr)
330  {
331  throw Invalid_State("X509_Certificate uninitialized");
332  }
333  return *m_data.get();
334  }
335 
337  {
338  return data().m_version;
339  }
340 
342  {
343  return data().m_self_signed;
344  }
345 
347  {
348  return data().m_not_before;
349  }
350 
352  {
353  return data().m_not_after;
354  }
355 
357  {
358  return data().m_subject_public_key_algid;
359  }
360 
361 const std::vector<uint8_t>& X509_Certificate::v2_issuer_key_id() const
362  {
363  return data().m_v2_issuer_key_id;
364  }
365 
366 const std::vector<uint8_t>& X509_Certificate::v2_subject_key_id() const
367  {
368  return data().m_v2_subject_key_id;
369  }
370 
371 const std::vector<uint8_t>& X509_Certificate::subject_public_key_bits() const
372  {
373  return data().m_subject_public_key_bits;
374  }
375 
376 const std::vector<uint8_t>& X509_Certificate::subject_public_key_bitstring() const
377  {
378  return data().m_subject_public_key_bitstring;
379  }
380 
381 const std::vector<uint8_t>& X509_Certificate::subject_public_key_bitstring_sha1() const
382  {
383  if(data().m_subject_public_key_bitstring_sha1.empty())
384  throw Encoding_Error("X509_Certificate::subject_public_key_bitstring_sha1 called but SHA-1 disabled in build");
385 
386  return data().m_subject_public_key_bitstring_sha1;
387  }
388 
389 const std::vector<uint8_t>& X509_Certificate::authority_key_id() const
390  {
391  return data().m_authority_key_id;
392  }
393 
394 const std::vector<uint8_t>& X509_Certificate::subject_key_id() const
395  {
396  return data().m_subject_key_id;
397  }
398 
399 const std::vector<uint8_t>& X509_Certificate::serial_number() const
400  {
401  return data().m_serial;
402  }
403 
405  {
406  return data().m_serial_negative;
407  }
408 
409 
411  {
412  return data().m_issuer_dn;
413  }
414 
416  {
417  return data().m_subject_dn;
418  }
419 
420 const std::vector<uint8_t>& X509_Certificate::raw_issuer_dn() const
421  {
422  return data().m_issuer_dn_bits;
423  }
424 
425 const std::vector<uint8_t>& X509_Certificate::raw_subject_dn() const
426  {
427  return data().m_subject_dn_bits;
428  }
429 
431  {
432  return data().m_is_ca_certificate;
433  }
434 
436  {
437  return data().m_path_len_constraint;
438  }
439 
441  {
442  return data().m_key_constraints;
443  }
444 
445 const std::vector<OID>& X509_Certificate::extended_key_usage() const
446  {
447  return data().m_extended_key_usage;
448  }
449 
450 const std::vector<OID>& X509_Certificate::certificate_policy_oids() const
451  {
452  return data().m_cert_policies;
453  }
454 
456  {
457  return data().m_name_constraints;
458  }
459 
461  {
462  return data().m_v3_extensions;
463  }
464 
466  {
467  if(constraints() == NO_CONSTRAINTS)
468  return true;
469  return ((constraints() & usage) == usage);
470  }
471 
472 bool X509_Certificate::allowed_extended_usage(const std::string& usage) const
473  {
474  return allowed_extended_usage(OIDS::str2oid(usage));
475  }
476 
478  {
479  const std::vector<OID>& ex = extended_key_usage();
480  if(ex.empty())
481  return true;
482 
483  if(std::find(ex.begin(), ex.end(), usage) != ex.end())
484  return true;
485 
486  return false;
487  }
488 
490  {
491  // These follow suggestions in RFC 5280 4.2.1.12
492 
493  switch(usage)
494  {
496  return true;
497 
499  return (allowed_usage(KEY_AGREEMENT) || allowed_usage(KEY_ENCIPHERMENT) || allowed_usage(DIGITAL_SIGNATURE)) && allowed_extended_usage("PKIX.ServerAuth");
500 
502  return (allowed_usage(DIGITAL_SIGNATURE) || allowed_usage(KEY_AGREEMENT)) && allowed_extended_usage("PKIX.ClientAuth");
503 
505  return (allowed_usage(DIGITAL_SIGNATURE) || allowed_usage(NON_REPUDIATION)) && allowed_extended_usage("PKIX.OCSPSigning");
506 
508  return is_CA_cert();
509  }
510 
511  return false;
512  }
513 
515  {
516  if(this->constraints() == NO_CONSTRAINTS)
517  {
518  return false;
519  }
520 
521  return ((this->constraints() & constraints) != 0);
522  }
523 
524 bool X509_Certificate::has_ex_constraint(const std::string& ex_constraint) const
525  {
526  return has_ex_constraint(OIDS::str2oid(ex_constraint));
527  }
528 
529 bool X509_Certificate::has_ex_constraint(const OID& usage) const
530  {
531  const std::vector<OID>& ex = extended_key_usage();
532  return (std::find(ex.begin(), ex.end(), usage) != ex.end());
533  }
534 
535 /*
536 * Return if a certificate extension is marked critical
537 */
538 bool X509_Certificate::is_critical(const std::string& ex_name) const
539  {
540  return v3_extensions().critical_extension_set(OIDS::str2oid(ex_name));
541  }
542 
544  {
545  return data().m_ocsp_responder;
546  }
547 
548 std::vector<std::string> X509_Certificate::ca_issuers() const
549  {
550  return data().m_ca_issuers;
551  }
552 
554  {
555  // just returns the first (arbitrarily)
556  if(data().m_crl_distribution_points.size() > 0)
557  return data().m_crl_distribution_points[0];
558  return "";
559  }
560 
562  {
563  return data().m_subject_alt_name;
564  }
565 
567  {
568  return data().m_issuer_alt_name;
569  }
570 
571 /*
572 * Return information about the subject
573 */
574 std::vector<std::string>
575 X509_Certificate::subject_info(const std::string& req) const
576  {
577  if(subject_dn().has_field(req))
578  return subject_dn().get_attribute(req);
579 
580  if(subject_alt_name().has_field(req))
581  return subject_alt_name().get_attribute(req);
582 
583  // These will be removed later:
584  if(req == "X509.Certificate.v2.key_id")
585  return {hex_encode(this->v2_subject_key_id())};
586  if(req == "X509v3.SubjectKeyIdentifier")
587  return {hex_encode(this->subject_key_id())};
588  if(req == "X509.Certificate.dn_bits")
589  return {hex_encode(this->raw_subject_dn())};
590  if(req == "X509.Certificate.start")
591  return {not_before().to_string()};
592  if(req == "X509.Certificate.end")
593  return {not_after().to_string()};
594 
595  if(req == "X509.Certificate.version")
596  return {std::to_string(x509_version())};
597  if(req == "X509.Certificate.serial")
598  return {hex_encode(serial_number())};
599 
600  return data().m_subject_ds.get(req);
601  }
602 
603 /*
604 * Return information about the issuer
605 */
606 std::vector<std::string>
607 X509_Certificate::issuer_info(const std::string& req) const
608  {
609  if(issuer_dn().has_field(req))
610  return issuer_dn().get_attribute(req);
611 
612  if(issuer_alt_name().has_field(req))
613  return issuer_alt_name().get_attribute(req);
614 
615  // These will be removed later:
616  if(req == "X509.Certificate.v2.key_id")
617  return {hex_encode(this->v2_issuer_key_id())};
618  if(req == "X509v3.AuthorityKeyIdentifier")
619  return {hex_encode(this->authority_key_id())};
620  if(req == "X509.Certificate.dn_bits")
621  return {hex_encode(this->raw_issuer_dn())};
622 
623  return data().m_issuer_ds.get(req);
624  }
625 
626 /*
627 * Return the public key in this certificate
628 */
629 std::unique_ptr<Public_Key> X509_Certificate::load_subject_public_key() const
630  {
631  try
632  {
633  return std::unique_ptr<Public_Key>(X509::load_key(ASN1::put_in_sequence(this->subject_public_key_bits())));
634  }
635  catch(std::exception& e)
636  {
637  throw Decoding_Error("X509_Certificate::load_subject_public_key", e.what());
638  }
639  }
640 
641 std::vector<uint8_t> X509_Certificate::raw_issuer_dn_sha256() const
642  {
643  std::unique_ptr<HashFunction> hash(HashFunction::create_or_throw("SHA-256"));
644  hash->update(raw_issuer_dn());
645  return hash->final_stdvec();
646  }
647 
648 std::vector<uint8_t> X509_Certificate::raw_subject_dn_sha256() const
649  {
650  std::unique_ptr<HashFunction> hash(HashFunction::create("SHA-256"));
651  hash->update(raw_subject_dn());
652  return hash->final_stdvec();
653  }
654 
655 namespace {
656 
657 /*
658 * Lookup each OID in the vector
659 */
660 std::vector<std::string> lookup_oids(const std::vector<OID>& oids)
661  {
662  std::vector<std::string> out;
663 
664  for(const OID& oid : oids)
665  {
666  out.push_back(OIDS::oid2str(oid));
667  }
668  return out;
669  }
670 
671 }
672 
673 /*
674 * Return the list of extended key usage OIDs
675 */
676 std::vector<std::string> X509_Certificate::ex_constraints() const
677  {
678  return lookup_oids(extended_key_usage());
679  }
680 
681 /*
682 * Return the list of certificate policies
683 */
684 std::vector<std::string> X509_Certificate::policies() const
685  {
686  return lookup_oids(certificate_policy_oids());
687  }
688 
689 std::string X509_Certificate::fingerprint(const std::string& hash_name) const
690  {
691  return create_hex_fingerprint(this->BER_encode(), hash_name);
692  }
693 
694 bool X509_Certificate::matches_dns_name(const std::string& name) const
695  {
696  if(name.empty())
697  return false;
698 
699  std::vector<std::string> issued_names = subject_info("DNS");
700 
701  // Fall back to CN only if no DNS names are set (RFC 6125 sec 6.4.4)
702  if(issued_names.empty())
703  issued_names = subject_info("Name");
704 
705  for(size_t i = 0; i != issued_names.size(); ++i)
706  {
707  if(host_wildcard_match(issued_names[i], name))
708  return true;
709  }
710 
711  return false;
712  }
713 
714 /*
715 * Compare two certificates for equality
716 */
718  {
719  return (this->signature() == other.signature() &&
720  this->signature_algorithm() == other.signature_algorithm() &&
721  this->signed_body() == other.signed_body());
722  }
723 
725  {
726  /* If signature values are not equal, sort by lexicographic ordering of that */
727  if(this->signature() != other.signature())
728  {
729  return (this->signature() < other.signature());
730  }
731 
732  // Then compare the signed contents
733  return this->signed_body() < other.signed_body();
734  }
735 
736 /*
737 * X.509 Certificate Comparison
738 */
739 bool operator!=(const X509_Certificate& cert1, const X509_Certificate& cert2)
740  {
741  return !(cert1 == cert2);
742  }
743 
744 std::string X509_Certificate::to_string() const
745  {
746  std::ostringstream out;
747 
748  out << "Version: " << this->x509_version() << "\n";
749  out << "Subject: " << subject_dn() << "\n";
750  out << "Issuer: " << issuer_dn() << "\n";
751  out << "Issued: " << this->not_before().readable_string() << "\n";
752  out << "Expires: " << this->not_after().readable_string() << "\n";
753 
754  out << "Constraints:\n";
755  Key_Constraints constraints = this->constraints();
756  if(constraints == NO_CONSTRAINTS)
757  out << " None\n";
758  else
759  {
760  if(constraints & DIGITAL_SIGNATURE)
761  out << " Digital Signature\n";
762  if(constraints & NON_REPUDIATION)
763  out << " Non-Repudiation\n";
764  if(constraints & KEY_ENCIPHERMENT)
765  out << " Key Encipherment\n";
766  if(constraints & DATA_ENCIPHERMENT)
767  out << " Data Encipherment\n";
768  if(constraints & KEY_AGREEMENT)
769  out << " Key Agreement\n";
770  if(constraints & KEY_CERT_SIGN)
771  out << " Cert Sign\n";
772  if(constraints & CRL_SIGN)
773  out << " CRL Sign\n";
774  if(constraints & ENCIPHER_ONLY)
775  out << " Encipher Only\n";
776  if(constraints & DECIPHER_ONLY)
777  out << " Decipher Only\n";
778  }
779 
780  const std::vector<OID> policies = this->certificate_policy_oids();
781  if(!policies.empty())
782  {
783  out << "Policies: " << "\n";
784  for(auto oid : policies)
785  out << " " << oid.as_string() << "\n";
786  }
787 
788  std::vector<OID> ex_constraints = this->extended_key_usage();
789  if(!ex_constraints.empty())
790  {
791  out << "Extended Constraints:\n";
792  for(size_t i = 0; i != ex_constraints.size(); i++)
793  out << " " << OIDS::oid2str(ex_constraints[i]) << "\n";
794  }
795 
796  const NameConstraints& name_constraints = this->name_constraints();
797 
798  if(!name_constraints.permitted().empty() || !name_constraints.excluded().empty())
799  {
800  out << "Name Constraints:\n";
801 
802  if(!name_constraints.permitted().empty())
803  {
804  out << " Permit";
805  for(auto st: name_constraints.permitted())
806  {
807  out << " " << st.base();
808  }
809  out << "\n";
810  }
811 
812  if(!name_constraints.excluded().empty())
813  {
814  out << " Exclude";
815  for(auto st: name_constraints.excluded())
816  {
817  out << " " << st.base();
818  }
819  out << "\n";
820  }
821  }
822 
823  if(!ocsp_responder().empty())
824  out << "OCSP responder " << ocsp_responder() << "\n";
825 
826  std::vector<std::string> ca_issuers = this->ca_issuers();
827  if(!ca_issuers.empty())
828  {
829  out << "CA Issuers:\n";
830  for(size_t i = 0; i != ca_issuers.size(); i++)
831  out << " URI: " << ca_issuers[i] << "\n";
832  }
833 
834  if(!crl_distribution_point().empty())
835  out << "CRL " << crl_distribution_point() << "\n";
836 
837  out << "Signature algorithm: " <<
838  OIDS::oid2str(this->signature_algorithm().get_oid()) << "\n";
839 
840  out << "Serial number: " << hex_encode(this->serial_number()) << "\n";
841 
842  if(this->authority_key_id().size())
843  out << "Authority keyid: " << hex_encode(this->authority_key_id()) << "\n";
844 
845  if(this->subject_key_id().size())
846  out << "Subject keyid: " << hex_encode(this->subject_key_id()) << "\n";
847 
848  try
849  {
850  std::unique_ptr<Public_Key> pubkey(this->subject_public_key());
851  out << "Public Key [" << pubkey->algo_name() << "-" << pubkey->key_length() << "]\n\n";
852  out << X509::PEM_encode(*pubkey);
853  }
854  catch(Decoding_Error&)
855  {
856  const AlgorithmIdentifier& alg_id = this->subject_public_key_algo();
857  out << "Failed to decode key with oid " << alg_id.get_oid().as_string() << "\n";
858  }
859 
860  return out.str();
861  }
862 
863 }
Certificate_Status_Code verify_signature(const Public_Key &key) const
Definition: x509_obj.cpp:192
bool allowed_usage(Key_Constraints usage) const
Definition: x509cert.cpp:465
void hex_encode(char output[], const uint8_t input[], size_t input_length, bool uppercase)
Definition: hex.cpp:14
bool operator!=(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
Definition: alg_id.cpp:90
std::vector< std::string > ex_constraints() const
Definition: x509cert.cpp:676
bool is_critical(const std::string &ex_name) const
Definition: x509cert.cpp:538
bool is_self_signed() const
Definition: x509cert.cpp:341
std::vector< uint8_t > raw_issuer_dn_sha256() const
Definition: x509cert.cpp:641
const AlgorithmIdentifier & signature_algorithm() const
Definition: x509_obj.h:47
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:345
const std::vector< uint8_t > & raw_subject_dn() const
Definition: x509cert.cpp:425
std::string PEM_encode(const Public_Key &key)
Definition: x509_key.cpp:28
const std::vector< uint8_t > & subject_public_key_bits() const
Definition: x509cert.cpp:371
std::vector< std::string > split_on(const std::string &str, char delim)
Definition: parsing.cpp:142
BER_Decoder & decode_optional_string(std::vector< uint8_t, Alloc > &out, ASN1_Tag real_type, uint16_t type_no, ASN1_Tag class_tag=CONTEXT_SPECIFIC)
Definition: ber_dec.h:179
std::string crl_distribution_point() const
Definition: x509cert.cpp:553
std::string as_string() const
Definition: asn1_oid.cpp:50
std::vector< std::string > issuer_info(const std::string &name) const
Definition: x509cert.cpp:607
const std::vector< OID > & certificate_policy_oids() const
Definition: x509cert.cpp:450
bool host_wildcard_match(const std::string &issued, const std::string &host)
Definition: parsing.cpp:341
const std::vector< GeneralSubtree > & excluded() const
BER_Decoder & decode(bool &v)
Definition: ber_dec.cpp:355
const std::vector< uint8_t > & authority_key_id() const
Definition: x509cert.cpp:389
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:108
ASN1_Tag
Definition: asn1_obj.h:22
std::string to_string() const
Definition: x509cert.cpp:744
bool matches_dns_name(const std::string &name) const
Definition: x509cert.cpp:694
const std::vector< uint8_t > & subject_key_id() const
Definition: x509cert.cpp:394
std::string ocsp_responder() const
Definition: x509cert.cpp:543
Key_Constraints constraints() const
Definition: x509cert.cpp:440
bool operator<(const X509_Certificate &other) const
Definition: x509cert.cpp:724
const AlternativeName & issuer_alt_name() const
Definition: x509cert.cpp:566
bool is_CA_cert() const
Definition: x509cert.cpp:430
OID str2oid(const std::string &name)
Definition: oids.h:37
bool has_ex_constraint(const std::string &ex_constraint) const
Definition: x509cert.cpp:524
bool has_constraints(Key_Constraints constraints) const
Definition: x509cert.cpp:514
uint32_t x509_version() const
Definition: x509cert.cpp:336
const X509_DN & subject_dn() const
Definition: x509cert.cpp:415
const std::vector< uint8_t > & signature() const
Definition: x509_obj.h:37
const X509_Time & not_after() const
Definition: x509cert.cpp:351
secure_vector< uint8_t > value
Definition: asn1_obj.h:97
const AlgorithmIdentifier & subject_public_key_algo() const
Definition: x509cert.cpp:356
bool allowed_extended_usage(const std::string &usage) const
Definition: x509cert.cpp:472
const std::vector< uint8_t > & subject_public_key_bitstring_sha1() const
Definition: x509cert.cpp:381
bool is_serial_negative() const
Definition: x509cert.cpp:404
const std::vector< GeneralSubtree > & permitted() const
const Extensions & v3_extensions() const
Definition: x509cert.cpp:460
uint32_t path_limit() const
Definition: x509cert.cpp:435
static std::unique_ptr< HashFunction > create(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:106
std::vector< std::string > policies() const
Definition: x509cert.cpp:684
const std::vector< uint8_t > & signed_body() const
Definition: x509_obj.h:42
const std::vector< OID > & extended_key_usage() const
Definition: x509cert.cpp:445
const X509_DN & issuer_dn() const
Definition: x509cert.cpp:410
std::string fingerprint(const std::string &hash_name="SHA-1") const
Definition: x509cert.cpp:689
BER_Decoder & discard_remaining()
Definition: ber_dec.cpp:186
Definition: alg_id.cpp:13
secure_vector< uint8_t > BER_encode(const Private_Key &key)
Definition: pkcs8.cpp:131
const std::vector< uint8_t > & subject_public_key_bitstring() const
Definition: x509cert.cpp:376
std::vector< std::string > ca_issuers() const
Definition: x509cert.cpp:548
std::vector< uint8_t > put_in_sequence(const std::vector< uint8_t > &contents)
Definition: asn1_obj.cpp:96
std::string create_hex_fingerprint(const uint8_t bits[], size_t bits_len, const std::string &hash_name)
Definition: pk_keys.cpp:17
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:95
ASN1_Tag class_tag
Definition: asn1_obj.h:94
ASN1_Tag type_tag
Definition: asn1_obj.h:94
std::string oid2str(const OID &oid)
Definition: oids.h:32
const X509_Time & not_before() const
Definition: x509cert.cpp:346
const OID & get_oid() const
Definition: alg_id.h:37
BER_Decoder & verify_end()
Definition: ber_dec.cpp:176
std::unique_ptr< Public_Key > load_subject_public_key() const
Definition: x509cert.cpp:629
const NameConstraints & name_constraints() const
Definition: x509cert.cpp:455
const std::vector< uint8_t > & serial_number() const
Definition: x509cert.cpp:399
bool operator==(const X509_Certificate &other) const
Definition: x509cert.cpp:717
Certificate_Status_Code
Definition: cert_status.h:18
static std::vector< uint8_t > encode(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:54
const std::vector< uint8_t > & v2_subject_key_id() const
Definition: x509cert.cpp:366
const std::vector< uint8_t > & v2_issuer_key_id() const
Definition: x509cert.cpp:361
std::vector< std::string > subject_info(const std::string &name) const
Definition: x509cert.cpp:575
MechanismType hash
static BigInt decode(const uint8_t buf[], size_t length, Base base=Binary)
Definition: big_code.cpp:114
Usage_Type
Definition: x509cert.h:25
const AlternativeName & subject_alt_name() const
Definition: x509cert.cpp:561
Public_Key * load_key(DataSource &source)
Definition: x509_key.cpp:37
const std::vector< uint8_t > & raw_issuer_dn() const
Definition: x509cert.cpp:420
Name Constraints.
std::vector< uint8_t > raw_subject_dn_sha256() const
Definition: x509cert.cpp:648