Botan  1.11.10
x509cert.cpp
Go to the documentation of this file.
1 /*
2 * X.509 Certificates
3 * (C) 1999-2010 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
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/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  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  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  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(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)
89  .start_cons(SEQUENCE)
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(sig_algo != sig_algo_inner)
99  throw Decoding_Error("Algorithm identifier mismatch");
100 
101  self_signed = (dn_subject == dn_issuer);
102 
103  subject.add(dn_subject.contents());
104  issuer.add(dn_issuer.contents());
105 
106  subject.add("X509.Certificate.dn_bits", ASN1::put_in_sequence(dn_subject.get_bits()));
107  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  extensions.contents_to(subject, issuer);
128  }
129  else if(v3_exts_data.type_tag != NO_OBJECT)
130  throw BER_Bad_Tag("Unknown tag in X.509 cert",
131  v3_exts_data.type_tag, v3_exts_data.class_tag);
132 
133  if(tbs_cert.more_items())
134  throw Decoding_Error("TBSCertificate has more items that expected");
135 
136  subject.add("X509.Certificate.version", version);
137  subject.add("X509.Certificate.serial", BigInt::encode(serial_bn));
138  subject.add("X509.Certificate.start", start.readable_string());
139  subject.add("X509.Certificate.end", end.readable_string());
140 
141  issuer.add("X509.Certificate.v2.key_id", v2_issuer_key_id);
142  subject.add("X509.Certificate.v2.key_id", v2_subject_key_id);
143 
144  subject.add("X509.Certificate.public_key",
145  hex_encode(public_key.value));
146 
147  if(self_signed && version == 0)
148  {
149  subject.add("X509v3.BasicConstraints.is_ca", 1);
150  subject.add("X509v3.BasicConstraints.path_constraint", Cert_Extension::NO_CERT_PATH_LIMIT);
151  }
152 
153  if(is_CA_cert() &&
154  !subject.has_value("X509v3.BasicConstraints.path_constraint"))
155  {
156  const size_t limit = (x509_version() < 3) ?
157  Cert_Extension::NO_CERT_PATH_LIMIT : 0;
158 
159  subject.add("X509v3.BasicConstraints.path_constraint", limit);
160  }
161  }
162 
163 /*
164 * Return the X.509 version in use
165 */
167  {
168  return (subject.get1_u32bit("X509.Certificate.version") + 1);
169  }
170 
171 /*
172 * Return the time this cert becomes valid
173 */
174 std::string X509_Certificate::start_time() const
175  {
176  return subject.get1("X509.Certificate.start");
177  }
178 
179 /*
180 * Return the time this cert becomes invalid
181 */
182 std::string X509_Certificate::end_time() const
183  {
184  return subject.get1("X509.Certificate.end");
185  }
186 
187 /*
188 * Return information about the subject
189 */
190 std::vector<std::string>
191 X509_Certificate::subject_info(const std::string& what) const
192  {
193  return subject.get(X509_DN::deref_info_field(what));
194  }
195 
196 /*
197 * Return information about the issuer
198 */
199 std::vector<std::string>
200 X509_Certificate::issuer_info(const std::string& what) const
201  {
202  return issuer.get(X509_DN::deref_info_field(what));
203  }
204 
205 /*
206 * Return the public key in this certificate
207 */
209  {
210  return X509::load_key(
212  }
213 
215  {
216  return hex_decode(subject.get1("X509.Certificate.public_key"));
217  }
218 
219 /*
220 * Check if the certificate is for a CA
221 */
223  {
224  if(!subject.get1_u32bit("X509v3.BasicConstraints.is_ca"))
225  return false;
226 
228  }
229 
231  {
232  if(constraints() == NO_CONSTRAINTS)
233  return true;
234  return (constraints() & usage);
235  }
236 
237 bool X509_Certificate::allowed_usage(const std::string& usage) const
238  {
239  for(auto constraint : ex_constraints())
240  if(constraint == usage)
241  return true;
242 
243  return false;
244  }
245 
246 /*
247 * Return the path length constraint
248 */
250  {
251  return subject.get1_u32bit("X509v3.BasicConstraints.path_constraint", 0);
252  }
253 
254 /*
255 * Return the key usage constraints
256 */
258  {
259  return Key_Constraints(subject.get1_u32bit("X509v3.KeyUsage",
260  NO_CONSTRAINTS));
261  }
262 
263 /*
264 * Return the list of extended key usage OIDs
265 */
266 std::vector<std::string> X509_Certificate::ex_constraints() const
267  {
268  return lookup_oids(subject.get("X509v3.ExtendedKeyUsage"));
269  }
270 
271 /*
272 * Return the list of certificate policies
273 */
274 std::vector<std::string> X509_Certificate::policies() const
275  {
276  return lookup_oids(subject.get("X509v3.CertificatePolicies"));
277  }
278 
280  {
281  return subject.get1("OCSP.responder", "");
282  }
283 
285  {
286  return subject.get1("CRL.DistributionPoint", "");
287  }
288 
289 /*
290 * Return the authority key id
291 */
292 std::vector<byte> X509_Certificate::authority_key_id() const
293  {
294  return issuer.get1_memvec("X509v3.AuthorityKeyIdentifier");
295  }
296 
297 /*
298 * Return the subject key id
299 */
300 std::vector<byte> X509_Certificate::subject_key_id() const
301  {
302  return subject.get1_memvec("X509v3.SubjectKeyIdentifier");
303  }
304 
305 /*
306 * Return the certificate serial number
307 */
308 std::vector<byte> X509_Certificate::serial_number() const
309  {
310  return subject.get1_memvec("X509.Certificate.serial");
311  }
312 
313 /*
314 * Return the distinguished name of the issuer
315 */
317  {
318  return create_dn(issuer);
319  }
320 
321 std::vector<byte> X509_Certificate::raw_issuer_dn() const
322  {
323  return issuer.get1_memvec("X509.Certificate.dn_bits");
324  }
325 
326 /*
327 * Return the distinguished name of the subject
328 */
330  {
331  return create_dn(subject);
332  }
333 
334 std::vector<byte> X509_Certificate::raw_subject_dn() const
335  {
336  return subject.get1_memvec("X509.Certificate.dn_bits");
337  }
338 
339 namespace {
340 
341 bool cert_subject_dns_match(const std::string& name,
342  const std::vector<std::string>& cert_names)
343  {
344  for(size_t i = 0; i != cert_names.size(); ++i)
345  {
346  const std::string cn = cert_names[i];
347 
348  if(cn == name)
349  return true;
350 
351  /*
352  * Possible wildcard match. We only support the most basic form of
353  * cert wildcarding ala RFC 2595
354  */
355  if(cn.size() > 2 && cn[0] == '*' && cn[1] == '.' && name.size() > cn.size())
356  {
357  const std::string base = cn.substr(1, std::string::npos);
358 
359  if(name.compare(name.size() - base.size(), base.size(), base) == 0)
360  return true;
361  }
362  }
363 
364  return false;
365  }
366 
367 }
368 
369 std::string X509_Certificate::fingerprint(const std::string& hash_name) const
370  {
371  std::unique_ptr<HashFunction> hash(get_hash(hash_name));
372  hash->update(this->BER_encode());
373  const auto hex_print = hex_encode(hash->final());
374 
375  std::string formatted_print;
376 
377  for(size_t i = 0; i != hex_print.size(); i += 2)
378  {
379  formatted_print.push_back(hex_print[i]);
380  formatted_print.push_back(hex_print[i+1]);
381 
382  if(i != hex_print.size() - 2)
383  formatted_print.push_back(':');
384  }
385 
386  return formatted_print;
387  }
388 
389 bool X509_Certificate::matches_dns_name(const std::string& name) const
390  {
391  if(name == "")
392  return false;
393 
394  if(cert_subject_dns_match(name, subject_info("DNS")))
395  return true;
396 
397  if(cert_subject_dns_match(name, subject_info("Name")))
398  return true;
399 
400  return false;
401  }
402 
403 /*
404 * Compare two certificates for equality
405 */
407  {
408  return (sig == other.sig &&
409  sig_algo == other.sig_algo &&
410  self_signed == other.self_signed &&
411  issuer == other.issuer &&
412  subject == other.subject);
413  }
414 
416  {
417  /* If signature values are not equal, sort by lexicographic ordering of that */
418  if(sig != other.sig)
419  {
420  if(sig < other.sig)
421  return true;
422  return false;
423  }
424 
425  // Then compare the signed contents
426  return tbs_bits < other.tbs_bits;
427  }
428 
429 /*
430 * X.509 Certificate Comparison
431 */
432 bool operator!=(const X509_Certificate& cert1, const X509_Certificate& cert2)
433  {
434  return !(cert1 == cert2);
435  }
436 
437 std::string X509_Certificate::to_string() const
438  {
439  const char* dn_fields[] = { "Name",
440  "Email",
441  "Organization",
442  "Organizational Unit",
443  "Locality",
444  "State",
445  "Country",
446  "IP",
447  "DNS",
448  "URI",
449  "PKIX.XMPPAddr",
450  nullptr };
451 
452  std::ostringstream out;
453 
454  for(size_t i = 0; dn_fields[i]; ++i)
455  {
456  const std::vector<std::string> vals = this->subject_info(dn_fields[i]);
457 
458  if(vals.empty())
459  continue;
460 
461  out << "Subject " << dn_fields[i] << ":";
462  for(size_t j = 0; j != vals.size(); ++j)
463  out << " " << vals[j];
464  out << "\n";
465  }
466 
467  for(size_t i = 0; dn_fields[i]; ++i)
468  {
469  const std::vector<std::string> vals = this->issuer_info(dn_fields[i]);
470 
471  if(vals.empty())
472  continue;
473 
474  out << "Issuer " << dn_fields[i] << ":";
475  for(size_t j = 0; j != vals.size(); ++j)
476  out << " " << vals[j];
477  out << "\n";
478  }
479 
480  out << "Version: " << this->x509_version() << "\n";
481 
482  out << "Not valid before: " << this->start_time() << "\n";
483  out << "Not valid after: " << this->end_time() << "\n";
484 
485  out << "Constraints:\n";
487  if(constraints == NO_CONSTRAINTS)
488  out << " None\n";
489  else
490  {
491  if(constraints & DIGITAL_SIGNATURE)
492  out << " Digital Signature\n";
493  if(constraints & NON_REPUDIATION)
494  out << " Non-Repuidation\n";
495  if(constraints & KEY_ENCIPHERMENT)
496  out << " Key Encipherment\n";
497  if(constraints & DATA_ENCIPHERMENT)
498  out << " Data Encipherment\n";
499  if(constraints & KEY_AGREEMENT)
500  out << " Key Agreement\n";
501  if(constraints & KEY_CERT_SIGN)
502  out << " Cert Sign\n";
503  if(constraints & CRL_SIGN)
504  out << " CRL Sign\n";
505  }
506 
507  std::vector<std::string> policies = this->policies();
508  if(!policies.empty())
509  {
510  out << "Policies: " << "\n";
511  for(size_t i = 0; i != policies.size(); i++)
512  out << " " << policies[i] << "\n";
513  }
514 
515  std::vector<std::string> ex_constraints = this->ex_constraints();
516  if(!ex_constraints.empty())
517  {
518  out << "Extended Constraints:\n";
519  for(size_t i = 0; i != ex_constraints.size(); i++)
520  out << " " << ex_constraints[i] << "\n";
521  }
522 
523  if(ocsp_responder() != "")
524  out << "OCSP responder " << ocsp_responder() << "\n";
525  if(crl_distribution_point() != "")
526  out << "CRL " << crl_distribution_point() << "\n";
527 
528  out << "Signature algorithm: " <<
529  OIDS::lookup(this->signature_algorithm().oid) << "\n";
530 
531  out << "Serial number: " << hex_encode(this->serial_number()) << "\n";
532 
533  if(this->authority_key_id().size())
534  out << "Authority keyid: " << hex_encode(this->authority_key_id()) << "\n";
535 
536  if(this->subject_key_id().size())
537  out << "Subject keyid: " << hex_encode(this->subject_key_id()) << "\n";
538 
539  std::unique_ptr<X509_PublicKey> pubkey(this->subject_public_key());
540  out << "Public Key:\n" << X509::PEM_encode(*pubkey);
541 
542  return out.str();
543  }
544 
545 /*
546 * Create and populate a X509_DN
547 */
549  {
550  auto names = info.search_for(
551  [](const std::string& key, const std::string&)
552  {
553  return (key.find("X520.") != std::string::npos);
554  });
555 
556  X509_DN dn;
557 
558  for(auto i = names.begin(); i != names.end(); ++i)
559  dn.add_attribute(i->first, i->second);
560 
561  return dn;
562  }
563 
564 /*
565 * Create and populate an AlternativeName
566 */
568  {
569  auto names = info.search_for(
570  [](const std::string& key, const std::string&)
571  {
572  return (key == "RFC822" ||
573  key == "DNS" ||
574  key == "URI" ||
575  key == "IP");
576  });
577 
578  AlternativeName alt_name;
579 
580  for(auto i = names.begin(); i != names.end(); ++i)
581  alt_name.add_attribute(i->first, i->second);
582 
583  return alt_name;
584  }
585 
586 }
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 OctetString &s1, const OctetString &s2)
Definition: symkey.cpp:105
bool operator==(const X509_Certificate &other) const
Definition: x509cert.cpp:406
static std::vector< byte > encode(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:54
HashFunction * get_hash(const std::string &algo_spec)
Definition: lookup.h:113
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:98
bool matches_dns_name(const std::string &name) const
Definition: x509cert.cpp:389
Public_Key * load_key(DataSource &source)
Definition: x509_key.cpp:41
bool is_CA_cert() const
Definition: x509cert.cpp:222
std::string ocsp_responder() const
Definition: x509cert.cpp:279
Key_Constraints constraints() const
Definition: x509cert.cpp:257
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:230
std::string crl_distribution_point() const
Definition: x509cert.cpp:284
void contents_to(Data_Store &, Data_Store &) const
Definition: x509_ext.cpp:157
std::vector< byte > raw_subject_dn() const
Definition: x509cert.cpp:334
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:249
std::vector< byte > serial_number() const
Definition: x509cert.cpp:308
AlgorithmIdentifier sig_algo
Definition: x509_obj.h:97
X509_DN create_dn(const Data_Store &info)
Definition: x509cert.cpp:548
std::string end_time() const
Definition: x509cert.cpp:182
AlternativeName create_alt_name(const Data_Store &info)
Definition: x509cert.cpp:567
std::vector< byte > get1_memvec(const std::string &) const
Definition: datastor.cpp:92
std::string to_string() const
Definition: x509cert.cpp:437
std::vector< byte > BER_encode() const
Definition: x509_obj.cpp:113
std::string lookup(const OID &oid)
Definition: oids.cpp:111
uint32_t u32bit
Definition: types.h:32
ASN1_Tag
Definition: asn1_obj.h:19
std::string fingerprint(const std::string &="SHA-1") const
Definition: x509cert.cpp:369
std::vector< byte > subject_public_key_bits() const
Definition: x509cert.cpp:214
std::string start_time() const
Definition: x509cert.cpp:174
std::string PEM_encode(const Public_Key &key)
Definition: x509_key.cpp:32
bool operator<(const X509_Certificate &other) const
Definition: x509cert.cpp:415
std::vector< byte > raw_issuer_dn() const
Definition: x509cert.cpp:321
std::vector< byte > subject_key_id() const
Definition: x509cert.cpp:300
std::vector< std::string > policies() const
Definition: x509cert.cpp:274
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:316
std::vector< std::string > subject_info(const std::string &name) const
Definition: x509cert.cpp:191
std::vector< std::string > ex_constraints() const
Definition: x509cert.cpp:266
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:200
std::vector< byte > authority_key_id() const
Definition: x509cert.cpp:292
Public_Key * subject_public_key() const
Definition: x509cert.cpp:208
std::multimap< std::string, std::string > contents() const
Definition: x509_dn.cpp:84
X509_DN subject_dn() const
Definition: x509cert.cpp:329
u32bit x509_version() const
Definition: x509cert.cpp:166
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:445
GMP_MPZ base
Definition: gmp_powm.cpp:29
std::vector< byte > tbs_bits
Definition: x509_obj.h:98
void hex_encode(char output[], const byte input[], size_t input_length, bool uppercase)
Definition: hex.cpp:14