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