Botan  1.11.16
x509cert.cpp
Go to the documentation of this file.
1 /*
2 * X.509 Certificates
3 * (C) 1999-2010 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/lookup.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  {
48  self_signed = false;
49  do_decode();
50  }
51 
52 /*
53 * X509_Certificate Constructor
54 */
55 X509_Certificate::X509_Certificate(const std::string& in) :
56  X509_Object(in, "CERTIFICATE/X509 CERTIFICATE")
57  {
58  self_signed = false;
59  do_decode();
60  }
61 
62 /*
63 * X509_Certificate Constructor
64 */
65 X509_Certificate::X509_Certificate(const std::vector<byte>& in) :
66  X509_Object(in, "CERTIFICATE/X509 CERTIFICATE")
67  {
68  self_signed = false;
69  do_decode();
70  }
71 
72 /*
73 * Decode the TBSCertificate data
74 */
75 void X509_Certificate::force_decode()
76  {
77  size_t version;
78  BigInt serial_bn;
79  AlgorithmIdentifier sig_algo_inner;
80  X509_DN dn_issuer, dn_subject;
81  X509_Time start, end;
82 
83  BER_Decoder tbs_cert(tbs_bits);
84 
85  tbs_cert.decode_optional(version, ASN1_Tag(0),
87  .decode(serial_bn)
88  .decode(sig_algo_inner)
89  .decode(dn_issuer)
90  .start_cons(SEQUENCE)
91  .decode(start)
92  .decode(end)
93  .verify_end()
94  .end_cons()
95  .decode(dn_subject);
96 
97  if(version > 2)
98  throw Decoding_Error("Unknown X.509 cert version " + std::to_string(version));
99  if(sig_algo != sig_algo_inner)
100  throw Decoding_Error("Algorithm identifier mismatch");
101 
102  self_signed = (dn_subject == dn_issuer);
103 
104  subject.add(dn_subject.contents());
105  issuer.add(dn_issuer.contents());
106 
107  subject.add("X509.Certificate.dn_bits", ASN1::put_in_sequence(dn_subject.get_bits()));
108  issuer.add("X509.Certificate.dn_bits", ASN1::put_in_sequence(dn_issuer.get_bits()));
109 
110  BER_Object public_key = tbs_cert.get_next_object();
111  if(public_key.type_tag != SEQUENCE || public_key.class_tag != CONSTRUCTED)
112  throw BER_Bad_Tag("X509_Certificate: Unexpected tag for public key",
113  public_key.type_tag, public_key.class_tag);
114 
115  std::vector<byte> v2_issuer_key_id, v2_subject_key_id;
116 
117  tbs_cert.decode_optional_string(v2_issuer_key_id, BIT_STRING, 1);
118  tbs_cert.decode_optional_string(v2_subject_key_id, BIT_STRING, 2);
119 
120  BER_Object v3_exts_data = tbs_cert.get_next_object();
121  if(v3_exts_data.type_tag == 3 &&
122  v3_exts_data.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
123  {
124  Extensions extensions;
125 
126  BER_Decoder(v3_exts_data.value).decode(extensions).verify_end();
127 
128  extensions.contents_to(subject, 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  subject.add("X509.Certificate.version", version);
138  subject.add("X509.Certificate.serial", BigInt::encode(serial_bn));
139  subject.add("X509.Certificate.start", start.readable_string());
140  subject.add("X509.Certificate.end", end.readable_string());
141 
142  issuer.add("X509.Certificate.v2.key_id", v2_issuer_key_id);
143  subject.add("X509.Certificate.v2.key_id", v2_subject_key_id);
144 
145  subject.add("X509.Certificate.public_key",
146  hex_encode(public_key.value));
147 
148  if(self_signed && version == 0)
149  {
150  subject.add("X509v3.BasicConstraints.is_ca", 1);
151  subject.add("X509v3.BasicConstraints.path_constraint", Cert_Extension::NO_CERT_PATH_LIMIT);
152  }
153 
154  if(is_CA_cert() &&
155  !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  subject.add("X509v3.BasicConstraints.path_constraint", limit);
161  }
162  }
163 
164 /*
165 * Return the X.509 version in use
166 */
168  {
169  return (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 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 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 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 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(subject.get1("X509.Certificate.public_key"));
218  }
219 
220 /*
221 * Check if the certificate is for a CA
222 */
224  {
225  if(!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);
236  }
237 
238 bool X509_Certificate::allowed_usage(const std::string& usage) const
239  {
240  for(auto constraint : ex_constraints())
241  if(constraint == usage)
242  return true;
243 
244  return false;
245  }
246 
247 /*
248 * Return the path length constraint
249 */
251  {
252  return subject.get1_u32bit("X509v3.BasicConstraints.path_constraint", 0);
253  }
254 
255 /*
256 * Return the key usage constraints
257 */
259  {
260  return Key_Constraints(subject.get1_u32bit("X509v3.KeyUsage",
261  NO_CONSTRAINTS));
262  }
263 
264 /*
265 * Return the list of extended key usage OIDs
266 */
267 std::vector<std::string> X509_Certificate::ex_constraints() const
268  {
269  return lookup_oids(subject.get("X509v3.ExtendedKeyUsage"));
270  }
271 
272 /*
273 * Return the list of certificate policies
274 */
275 std::vector<std::string> X509_Certificate::policies() const
276  {
277  return lookup_oids(subject.get("X509v3.CertificatePolicies"));
278  }
279 
281  {
282  return subject.get1("OCSP.responder", "");
283  }
284 
286  {
287  return subject.get1("CRL.DistributionPoint", "");
288  }
289 
290 /*
291 * Return the authority key id
292 */
293 std::vector<byte> X509_Certificate::authority_key_id() const
294  {
295  return issuer.get1_memvec("X509v3.AuthorityKeyIdentifier");
296  }
297 
298 /*
299 * Return the subject key id
300 */
301 std::vector<byte> X509_Certificate::subject_key_id() const
302  {
303  return subject.get1_memvec("X509v3.SubjectKeyIdentifier");
304  }
305 
306 /*
307 * Return the certificate serial number
308 */
309 std::vector<byte> X509_Certificate::serial_number() const
310  {
311  return subject.get1_memvec("X509.Certificate.serial");
312  }
313 
314 /*
315 * Return the distinguished name of the issuer
316 */
318  {
319  return create_dn(issuer);
320  }
321 
322 std::vector<byte> X509_Certificate::raw_issuer_dn() const
323  {
324  return issuer.get1_memvec("X509.Certificate.dn_bits");
325  }
326 
327 /*
328 * Return the distinguished name of the subject
329 */
331  {
332  return create_dn(subject);
333  }
334 
335 std::vector<byte> X509_Certificate::raw_subject_dn() const
336  {
337  return subject.get1_memvec("X509.Certificate.dn_bits");
338  }
339 
340 namespace {
341 
342 bool cert_subject_dns_match(const std::string& name,
343  const std::vector<std::string>& cert_names)
344  {
345  for(size_t i = 0; i != cert_names.size(); ++i)
346  {
347  const std::string cn = cert_names[i];
348 
349  if(cn == name)
350  return true;
351 
352  /*
353  * Possible wildcard match. We only support the most basic form of
354  * cert wildcarding ala RFC 2595
355  */
356  if(cn.size() > 2 && cn[0] == '*' && cn[1] == '.' && name.size() > cn.size())
357  {
358  const std::string base = cn.substr(1, std::string::npos);
359 
360  if(name.compare(name.size() - base.size(), base.size(), base) == 0)
361  return true;
362  }
363  }
364 
365  return false;
366  }
367 
368 }
369 
370 std::string X509_Certificate::fingerprint(const std::string& hash_name) const
371  {
372  std::unique_ptr<HashFunction> hash(get_hash(hash_name));
373  hash->update(this->BER_encode());
374  const auto hex_print = hex_encode(hash->final());
375 
376  std::string formatted_print;
377 
378  for(size_t i = 0; i != hex_print.size(); i += 2)
379  {
380  formatted_print.push_back(hex_print[i]);
381  formatted_print.push_back(hex_print[i+1]);
382 
383  if(i != hex_print.size() - 2)
384  formatted_print.push_back(':');
385  }
386 
387  return formatted_print;
388  }
389 
390 bool X509_Certificate::matches_dns_name(const std::string& name) const
391  {
392  if(name == "")
393  return false;
394 
395  if(cert_subject_dns_match(name, subject_info("DNS")))
396  return true;
397 
398  if(cert_subject_dns_match(name, subject_info("Name")))
399  return true;
400 
401  return false;
402  }
403 
404 /*
405 * Compare two certificates for equality
406 */
408  {
409  return (sig == other.sig &&
410  sig_algo == other.sig_algo &&
411  self_signed == other.self_signed &&
412  issuer == other.issuer &&
413  subject == other.subject);
414  }
415 
417  {
418  /* If signature values are not equal, sort by lexicographic ordering of that */
419  if(sig != other.sig)
420  {
421  if(sig < other.sig)
422  return true;
423  return false;
424  }
425 
426  // Then compare the signed contents
427  return tbs_bits < other.tbs_bits;
428  }
429 
430 /*
431 * X.509 Certificate Comparison
432 */
433 bool operator!=(const X509_Certificate& cert1, const X509_Certificate& cert2)
434  {
435  return !(cert1 == cert2);
436  }
437 
438 std::string X509_Certificate::to_string() const
439  {
440  const char* dn_fields[] = { "Name",
441  "Email",
442  "Organization",
443  "Organizational Unit",
444  "Locality",
445  "State",
446  "Country",
447  "IP",
448  "DNS",
449  "URI",
450  "PKIX.XMPPAddr",
451  nullptr };
452 
453  std::ostringstream out;
454 
455  for(size_t i = 0; dn_fields[i]; ++i)
456  {
457  const std::vector<std::string> vals = this->subject_info(dn_fields[i]);
458 
459  if(vals.empty())
460  continue;
461 
462  out << "Subject " << dn_fields[i] << ":";
463  for(size_t j = 0; j != vals.size(); ++j)
464  out << " " << vals[j];
465  out << "\n";
466  }
467 
468  for(size_t i = 0; dn_fields[i]; ++i)
469  {
470  const std::vector<std::string> vals = this->issuer_info(dn_fields[i]);
471 
472  if(vals.empty())
473  continue;
474 
475  out << "Issuer " << dn_fields[i] << ":";
476  for(size_t j = 0; j != vals.size(); ++j)
477  out << " " << vals[j];
478  out << "\n";
479  }
480 
481  out << "Version: " << this->x509_version() << "\n";
482 
483  out << "Not valid before: " << this->start_time() << "\n";
484  out << "Not valid after: " << this->end_time() << "\n";
485 
486  out << "Constraints:\n";
488  if(constraints == NO_CONSTRAINTS)
489  out << " None\n";
490  else
491  {
492  if(constraints & DIGITAL_SIGNATURE)
493  out << " Digital Signature\n";
494  if(constraints & NON_REPUDIATION)
495  out << " Non-Repuidation\n";
496  if(constraints & KEY_ENCIPHERMENT)
497  out << " Key Encipherment\n";
498  if(constraints & DATA_ENCIPHERMENT)
499  out << " Data Encipherment\n";
500  if(constraints & KEY_AGREEMENT)
501  out << " Key Agreement\n";
502  if(constraints & KEY_CERT_SIGN)
503  out << " Cert Sign\n";
504  if(constraints & CRL_SIGN)
505  out << " CRL Sign\n";
506  }
507 
508  std::vector<std::string> policies = this->policies();
509  if(!policies.empty())
510  {
511  out << "Policies: " << "\n";
512  for(size_t i = 0; i != policies.size(); i++)
513  out << " " << policies[i] << "\n";
514  }
515 
516  std::vector<std::string> ex_constraints = this->ex_constraints();
517  if(!ex_constraints.empty())
518  {
519  out << "Extended Constraints:\n";
520  for(size_t i = 0; i != ex_constraints.size(); i++)
521  out << " " << ex_constraints[i] << "\n";
522  }
523 
524  if(ocsp_responder() != "")
525  out << "OCSP responder " << ocsp_responder() << "\n";
526  if(crl_distribution_point() != "")
527  out << "CRL " << crl_distribution_point() << "\n";
528 
529  out << "Signature algorithm: " <<
530  OIDS::lookup(this->signature_algorithm().oid) << "\n";
531 
532  out << "Serial number: " << hex_encode(this->serial_number()) << "\n";
533 
534  if(this->authority_key_id().size())
535  out << "Authority keyid: " << hex_encode(this->authority_key_id()) << "\n";
536 
537  if(this->subject_key_id().size())
538  out << "Subject keyid: " << hex_encode(this->subject_key_id()) << "\n";
539 
540  std::unique_ptr<X509_PublicKey> pubkey(this->subject_public_key());
541  out << "Public Key:\n" << X509::PEM_encode(*pubkey);
542 
543  return out.str();
544  }
545 
546 /*
547 * Create and populate a X509_DN
548 */
550  {
551  auto names = info.search_for(
552  [](const std::string& key, const std::string&)
553  {
554  return (key.find("X520.") != std::string::npos);
555  });
556 
557  X509_DN dn;
558 
559  for(auto i = names.begin(); i != names.end(); ++i)
560  dn.add_attribute(i->first, i->second);
561 
562  return dn;
563  }
564 
565 /*
566 * Create and populate an AlternativeName
567 */
569  {
570  auto names = info.search_for(
571  [](const std::string& key, const std::string&)
572  {
573  return (key == "RFC822" ||
574  key == "DNS" ||
575  key == "URI" ||
576  key == "IP");
577  });
578 
579  AlternativeName alt_name;
580 
581  for(auto i = names.begin(); i != names.end(); ++i)
582  alt_name.add_attribute(i->first, i->second);
583 
584  return alt_name;
585  }
586 
587 }
void add_attribute(const std::string &, const std::string &)
std::vector< byte > get_bits() const
Definition: x509_dn.cpp:110
friend class BER_Decoder
Definition: x509cert.h:226
bool operator==(const X509_Certificate &other) const
Definition: x509cert.cpp:407
static std::vector< byte > encode(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:54
HashFunction * get_hash(const std::string &algo_spec, const std::string &provider="")
Definition: lookup.h:70
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::vector< byte > sig
Definition: x509_obj.h:97
bool matches_dns_name(const std::string &name) const
Definition: x509cert.cpp:390
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:280
Key_Constraints constraints() const
Definition: x509cert.cpp:258
void add_attribute(const std::string &, const std::string &)
Definition: x509_dn.cpp:46
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:46
bool allowed_usage(Key_Constraints usage) const
Definition: x509cert.cpp:231
std::string crl_distribution_point() const
Definition: x509cert.cpp:285
void contents_to(Data_Store &, Data_Store &) const
Definition: x509_ext.cpp:159
std::vector< byte > raw_subject_dn() const
Definition: x509cert.cpp:335
secure_vector< byte > value
Definition: asn1_obj.h:84
std::string get1(const std::string &key) const
Definition: datastor.cpp:62
u32bit path_limit() const
Definition: x509cert.cpp:250
std::vector< byte > serial_number() const
Definition: x509cert.cpp:309
AlgorithmIdentifier sig_algo
Definition: x509_obj.h:96
X509_DN create_dn(const Data_Store &info)
Definition: x509cert.cpp:549
std::string end_time() const
Definition: x509cert.cpp:183
AlternativeName create_alt_name(const Data_Store &info)
Definition: x509cert.cpp:568
std::vector< byte > get1_memvec(const std::string &) const
Definition: datastor.cpp:92
std::string to_string() const
Definition: x509cert.cpp:438
std::vector< byte > BER_encode() const
Definition: x509_obj.cpp:113
std::string lookup(const OID &oid)
Definition: oids.cpp:155
uint32_t u32bit
Definition: types.h:33
ASN1_Tag
Definition: asn1_obj.h:19
std::string fingerprint(const std::string &="SHA-1") const
Definition: x509cert.cpp:370
std::vector< byte > subject_public_key_bits() const
Definition: x509cert.cpp:215
std::string start_time() const
Definition: x509cert.cpp:175
std::string PEM_encode(const Public_Key &key)
Definition: x509_key.cpp:32
bool operator<(const X509_Certificate &other) const
Definition: x509cert.cpp:416
std::vector< byte > raw_issuer_dn() const
Definition: x509cert.cpp:322
std::vector< byte > subject_key_id() const
Definition: x509cert.cpp:301
std::vector< std::string > policies() const
Definition: x509cert.cpp:275
ASN1_Tag class_tag
Definition: asn1_obj.h:83
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:83
X509_DN issuer_dn() const
Definition: x509cert.cpp:317
std::vector< std::string > subject_info(const std::string &name) const
Definition: x509cert.cpp:192
std::vector< std::string > ex_constraints() const
Definition: x509cert.cpp:267
static std::string deref_info_field(const std::string &)
Definition: x509_dn.cpp:118
std::string readable_string() const
Definition: asn1_time.cpp:228
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:293
Public_Key * subject_public_key() const
Definition: x509cert.cpp:209
std::multimap< std::string, std::string > contents() const
Definition: x509_dn.cpp:84
X509_DN subject_dn() const
Definition: x509cert.cpp:330
u32bit x509_version() const
Definition: x509cert.cpp:167
std::vector< byte > put_in_sequence(const std::vector< byte > &contents)
Definition: asn1_obj.cpp:34
std::vector< std::string > get(const std::string &) const
Definition: datastor.cpp:50
AlgorithmIdentifier signature_algorithm() const
Definition: x509_obj.cpp:147
void add(const std::multimap< std::string, std::string > &)
Definition: datastor.cpp:155
OID oid
Definition: x509_ext.cpp:447
bool operator!=(const secure_allocator< T > &, const secure_allocator< T > &)
Definition: secmem.h:90
std::vector< byte > tbs_bits
Definition: x509_obj.h:97
void hex_encode(char output[], const byte input[], size_t input_length, bool uppercase)
Definition: hex.cpp:14