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