Botan  2.1.0
Crypto and TLS for C++11
x509_ext.cpp
Go to the documentation of this file.
1 /*
2 * X.509 Certificate Extensions
3 * (C) 1999-2010,2012 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/x509_ext.h>
10 #include <botan/x509cert.h>
11 #include <botan/sha160.h>
12 #include <botan/der_enc.h>
13 #include <botan/ber_dec.h>
14 #include <botan/oids.h>
15 #include <botan/charset.h>
16 #include <botan/internal/bit_ops.h>
17 #include <algorithm>
18 #include <sstream>
19 
20 namespace Botan {
21 
22 /*
23 * List of X.509 Certificate Extensions
24 */
25 Certificate_Extension* Extensions::create_extension(const OID& oid, bool critical)
26  {
27 #define X509_EXTENSION(NAME, TYPE) \
28  if(oid == OIDS::lookup(NAME)) { return new Cert_Extension::TYPE(); }
29 
30  X509_EXTENSION("X509v3.KeyUsage", Key_Usage);
31  X509_EXTENSION("X509v3.BasicConstraints", Basic_Constraints);
32  X509_EXTENSION("X509v3.SubjectKeyIdentifier", Subject_Key_ID);
33  X509_EXTENSION("X509v3.AuthorityKeyIdentifier", Authority_Key_ID);
34  X509_EXTENSION("X509v3.ExtendedKeyUsage", Extended_Key_Usage);
35  X509_EXTENSION("X509v3.IssuerAlternativeName", Issuer_Alternative_Name);
36  X509_EXTENSION("X509v3.SubjectAlternativeName", Subject_Alternative_Name);
37  X509_EXTENSION("X509v3.NameConstraints", Name_Constraints);
38  X509_EXTENSION("X509v3.CertificatePolicies", Certificate_Policies);
39  X509_EXTENSION("X509v3.CRLDistributionPoints", CRL_Distribution_Points);
40  X509_EXTENSION("PKIX.AuthorityInformationAccess", Authority_Information_Access);
41  X509_EXTENSION("X509v3.CRLNumber", CRL_Number);
42  X509_EXTENSION("X509v3.ReasonCode", CRL_ReasonCode);
43 
44  return critical ? new Cert_Extension::Unknown_Critical_Extension(oid) : nullptr;
45  }
46 
47 /*
48 * Extensions Copy Constructor
49 */
51  {
52  *this = extensions;
53  }
54 
55 /*
56 * Extensions Assignment Operator
57 */
59  {
60  m_extensions.clear();
61 
62  for(size_t i = 0; i != other.m_extensions.size(); ++i)
63  m_extensions.push_back(
64  std::make_pair(std::unique_ptr<Certificate_Extension>(other.m_extensions[i].first->copy()),
65  other.m_extensions[i].second));
66 
67  m_extensions_raw = other.m_extensions_raw;
68  m_throw_on_unknown_critical = other.m_throw_on_unknown_critical;
69 
70  return (*this);
71  }
72 
73 /*
74 * Return the OID of this extension
75 */
77  {
78  return OIDS::lookup(oid_name());
79  }
80 
81 /*
82 * Validate the extension (the default implementation is a NOP)
83 */
85  const std::vector<std::shared_ptr<const X509_Certificate>>&,
86  std::vector<std::set<Certificate_Status_Code>>&,
87  size_t)
88  {
89  }
90 
91 void Extensions::add(Certificate_Extension* extn, bool critical)
92  {
93  // sanity check: we don't want to have the same extension more than once
94  for(const auto& ext : m_extensions)
95  {
96  if(ext.first->oid_of() == extn->oid_of())
97  {
98  throw Invalid_Argument(extn->oid_name() + " extension already present");
99  }
100  }
101 
102  if(m_extensions_raw.count(extn->oid_of()) > 0)
103  {
104  throw Invalid_Argument(extn->oid_name() + " extension already present");
105  }
106 
107  m_extensions.push_back(std::make_pair(std::unique_ptr<Certificate_Extension>(extn), critical));
108  m_extensions_raw.emplace(extn->oid_of(), std::make_pair(extn->encode_inner(), critical));
109  }
110 
111 void Extensions::replace(Certificate_Extension* extn, bool critical)
112  {
113  for(auto it = m_extensions.begin(); it != m_extensions.end(); ++it)
114  {
115  if(it->first->oid_of() == extn->oid_of())
116  {
117  m_extensions.erase(it);
118  break;
119  }
120  }
121 
122  m_extensions.push_back(std::make_pair(std::unique_ptr<Certificate_Extension>(extn), critical));
123  m_extensions_raw[extn->oid_of()] = std::make_pair(extn->encode_inner(), critical);
124  }
125 
126 std::unique_ptr<Certificate_Extension> Extensions::get(const OID& oid) const
127  {
128  for(auto& ext : m_extensions)
129  {
130  if(ext.first->oid_of() == oid)
131  {
132  return std::unique_ptr<Certificate_Extension>(ext.first->copy());
133  }
134  }
135 
136  return nullptr;
137  }
138 
139 std::vector<std::pair<std::unique_ptr<Certificate_Extension>, bool>> Extensions::extensions() const
140  {
141  std::vector<std::pair<std::unique_ptr<Certificate_Extension>, bool>> exts;
142  for(auto& ext : m_extensions)
143  {
144  exts.push_back(std::make_pair(std::unique_ptr<Certificate_Extension>(ext.first->copy()), ext.second));
145  }
146  return exts;
147  }
148 
149 std::map<OID, std::pair<std::vector<uint8_t>, bool>> Extensions::extensions_raw() const
150  {
151  return m_extensions_raw;
152  }
153 
154 /*
155 * Encode an Extensions list
156 */
157 void Extensions::encode_into(DER_Encoder& to_object) const
158  {
159  // encode any known extensions
160  for(size_t i = 0; i != m_extensions.size(); ++i)
161  {
162  const Certificate_Extension* ext = m_extensions[i].first.get();
163  const bool is_critical = m_extensions[i].second;
164 
165  const bool should_encode = ext->should_encode();
166 
167  if(should_encode)
168  {
169  to_object.start_cons(SEQUENCE)
170  .encode(ext->oid_of())
171  .encode_optional(is_critical, false)
173  .end_cons();
174  }
175  }
176 
177  // encode any unknown extensions
178  for(const auto& ext_raw : m_extensions_raw)
179  {
180  const bool is_critical = ext_raw.second.second;
181  const OID oid = ext_raw.first;
182  const std::vector<uint8_t> value = ext_raw.second.first;
183 
184  auto pos = std::find_if(std::begin(m_extensions), std::end(m_extensions),
185  [&oid](const std::pair<std::unique_ptr<Certificate_Extension>, bool>& ext) -> bool
186  {
187  return ext.first->oid_of() == oid;
188  });
189 
190  if(pos == std::end(m_extensions))
191  {
192  // not found in m_extensions, must be unknown
193  to_object.start_cons(SEQUENCE)
194  .encode(oid)
195  .encode_optional(is_critical, false)
196  .encode(value, OCTET_STRING)
197  .end_cons();
198  }
199  }
200  }
201 
202 /*
203 * Decode a list of Extensions
204 */
206  {
207  m_extensions.clear();
208  m_extensions_raw.clear();
209 
210  BER_Decoder sequence = from_source.start_cons(SEQUENCE);
211 
212  while(sequence.more_items())
213  {
214  OID oid;
215  std::vector<uint8_t> value;
216  bool critical;
217 
218  sequence.start_cons(SEQUENCE)
219  .decode(oid)
220  .decode_optional(critical, BOOLEAN, UNIVERSAL, false)
221  .decode(value, OCTET_STRING)
222  .end_cons();
223 
224  m_extensions_raw.emplace(oid, std::make_pair(value, critical));
225 
226  std::unique_ptr<Certificate_Extension> ext(create_extension(oid, critical));
227 
228  if(!ext && critical && m_throw_on_unknown_critical)
229  throw Decoding_Error("Encountered unknown X.509 extension marked "
230  "as critical; OID = " + oid.as_string());
231 
232  if(ext)
233  {
234  try
235  {
236  ext->decode_inner(value);
237  }
238  catch(std::exception& e)
239  {
240  throw Decoding_Error("Exception while decoding extension " +
241  oid.as_string() + ": " + e.what());
242  }
243 
244  m_extensions.push_back(std::make_pair(std::move(ext), critical));
245  }
246  }
247 
248  sequence.verify_end();
249  }
250 
251 /*
252 * Write the extensions to an info store
253 */
255  Data_Store& issuer_info) const
256  {
257  for(size_t i = 0; i != m_extensions.size(); ++i)
258  {
259  m_extensions[i].first->contents_to(subject_info, issuer_info);
260  subject_info.add(m_extensions[i].first->oid_name() + ".is_critical", (m_extensions[i].second ? 1 : 0));
261  }
262  }
263 
264 
265 namespace Cert_Extension {
266 
267 /*
268 * Checked accessor for the path_limit member
269 */
271  {
272  if(!m_is_ca)
273  throw Invalid_State("Basic_Constraints::get_path_limit: Not a CA");
274  return m_path_limit;
275  }
276 
277 /*
278 * Encode the extension
279 */
280 std::vector<uint8_t> Basic_Constraints::encode_inner() const
281  {
282  return DER_Encoder()
284  .encode_if(m_is_ca,
285  DER_Encoder()
286  .encode(m_is_ca)
287  .encode_optional(m_path_limit, NO_CERT_PATH_LIMIT)
288  )
289  .end_cons()
291  }
292 
293 /*
294 * Decode the extension
295 */
296 void Basic_Constraints::decode_inner(const std::vector<uint8_t>& in)
297  {
298  BER_Decoder(in)
300  .decode_optional(m_is_ca, BOOLEAN, UNIVERSAL, false)
301  .decode_optional(m_path_limit, INTEGER, UNIVERSAL, NO_CERT_PATH_LIMIT)
302  .end_cons();
303 
304  if(m_is_ca == false)
305  m_path_limit = 0;
306  }
307 
308 /*
309 * Return a textual representation
310 */
311 void Basic_Constraints::contents_to(Data_Store& subject, Data_Store&) const
312  {
313  subject.add("X509v3.BasicConstraints.is_ca", (m_is_ca ? 1 : 0));
314  subject.add("X509v3.BasicConstraints.path_constraint", static_cast<uint32_t>(m_path_limit));
315  }
316 
317 /*
318 * Encode the extension
319 */
320 std::vector<uint8_t> Key_Usage::encode_inner() const
321  {
322  if(m_constraints == NO_CONSTRAINTS)
323  throw Encoding_Error("Cannot encode zero usage constraints");
324 
325  const size_t unused_bits = low_bit(m_constraints) - 1;
326 
327  std::vector<uint8_t> der;
328  der.push_back(BIT_STRING);
329  der.push_back(2 + ((unused_bits < 8) ? 1 : 0));
330  der.push_back(unused_bits % 8);
331  der.push_back((m_constraints >> 8) & 0xFF);
332  if(m_constraints & 0xFF)
333  der.push_back(m_constraints & 0xFF);
334 
335  return der;
336  }
337 
338 /*
339 * Decode the extension
340 */
341 void Key_Usage::decode_inner(const std::vector<uint8_t>& in)
342  {
343  BER_Decoder ber(in);
344 
345  BER_Object obj = ber.get_next_object();
346 
347  if(obj.type_tag != BIT_STRING || obj.class_tag != UNIVERSAL)
348  throw BER_Bad_Tag("Bad tag for usage constraint",
349  obj.type_tag, obj.class_tag);
350 
351  if(obj.value.size() != 2 && obj.value.size() != 3)
352  throw BER_Decoding_Error("Bad size for BITSTRING in usage constraint");
353 
354  if(obj.value[0] >= 8)
355  throw BER_Decoding_Error("Invalid unused bits in usage constraint");
356 
357  obj.value[obj.value.size()-1] &= (0xFF << obj.value[0]);
358 
359  uint16_t usage = 0;
360  for(size_t i = 1; i != obj.value.size(); ++i)
361  {
362  usage = (obj.value[i] << 8*(sizeof(usage)-i)) | usage;
363  }
364 
365  m_constraints = Key_Constraints(usage);
366  }
367 
368 /*
369 * Return a textual representation
370 */
371 void Key_Usage::contents_to(Data_Store& subject, Data_Store&) const
372  {
373  subject.add("X509v3.KeyUsage", m_constraints);
374  }
375 
376 /*
377 * Encode the extension
378 */
379 std::vector<uint8_t> Subject_Key_ID::encode_inner() const
380  {
381  return DER_Encoder().encode(m_key_id, OCTET_STRING).get_contents_unlocked();
382  }
383 
384 /*
385 * Decode the extension
386 */
387 void Subject_Key_ID::decode_inner(const std::vector<uint8_t>& in)
388  {
389  BER_Decoder(in).decode(m_key_id, OCTET_STRING).verify_end();
390  }
391 
392 /*
393 * Return a textual representation
394 */
395 void Subject_Key_ID::contents_to(Data_Store& subject, Data_Store&) const
396  {
397  subject.add("X509v3.SubjectKeyIdentifier", m_key_id);
398  }
399 
400 /*
401 * Subject_Key_ID Constructor
402 */
403 Subject_Key_ID::Subject_Key_ID(const std::vector<uint8_t>& pub_key) : m_key_id(unlock(SHA_160().process(pub_key)))
404  {}
405 
406 /*
407 * Encode the extension
408 */
409 std::vector<uint8_t> Authority_Key_ID::encode_inner() const
410  {
411  return DER_Encoder()
414  .end_cons()
416  }
417 
418 /*
419 * Decode the extension
420 */
421 void Authority_Key_ID::decode_inner(const std::vector<uint8_t>& in)
422  {
423  BER_Decoder(in)
425  .decode_optional_string(m_key_id, OCTET_STRING, 0);
426  }
427 
428 /*
429 * Return a textual representation
430 */
431 void Authority_Key_ID::contents_to(Data_Store&, Data_Store& issuer) const
432  {
433  if(m_key_id.size())
434  issuer.add("X509v3.AuthorityKeyIdentifier", m_key_id);
435  }
436 
437 /*
438 * Encode the extension
439 */
440 std::vector<uint8_t> Alternative_Name::encode_inner() const
441  {
442  return DER_Encoder().encode(m_alt_name).get_contents_unlocked();
443  }
444 
445 /*
446 * Decode the extension
447 */
448 void Alternative_Name::decode_inner(const std::vector<uint8_t>& in)
449  {
450  BER_Decoder(in).decode(m_alt_name);
451  }
452 
453 /*
454 * Return a textual representation
455 */
456 void Alternative_Name::contents_to(Data_Store& subject_info,
457  Data_Store& issuer_info) const
458  {
459  std::multimap<std::string, std::string> contents =
461 
462  if(m_oid_name_str == "X509v3.SubjectAlternativeName")
463  subject_info.add(contents);
464  else if(m_oid_name_str == "X509v3.IssuerAlternativeName")
465  issuer_info.add(contents);
466  else
467  throw Internal_Error("In Alternative_Name, unknown type " +
468  m_oid_name_str);
469  }
470 
471 /*
472 * Alternative_Name Constructor
473 */
475  const std::string& oid_name_str) :
476  m_oid_name_str(oid_name_str),
477  m_alt_name(alt_name)
478  {}
479 
480 /*
481 * Subject_Alternative_Name Constructor
482 */
484  const AlternativeName& name) :
485  Alternative_Name(name, "X509v3.SubjectAlternativeName")
486  {
487  }
488 
489 /*
490 * Issuer_Alternative_Name Constructor
491 */
493  Alternative_Name(name, "X509v3.IssuerAlternativeName")
494  {
495  }
496 
497 /*
498 * Encode the extension
499 */
500 std::vector<uint8_t> Extended_Key_Usage::encode_inner() const
501  {
502  return DER_Encoder()
504  .encode_list(m_oids)
505  .end_cons()
507  }
508 
509 /*
510 * Decode the extension
511 */
512 void Extended_Key_Usage::decode_inner(const std::vector<uint8_t>& in)
513  {
514  BER_Decoder(in).decode_list(m_oids);
515  }
516 
517 /*
518 * Return a textual representation
519 */
520 void Extended_Key_Usage::contents_to(Data_Store& subject, Data_Store&) const
521  {
522  for(size_t i = 0; i != m_oids.size(); ++i)
523  subject.add("X509v3.ExtendedKeyUsage", m_oids[i].as_string());
524  }
525 
526 /*
527 * Encode the extension
528 */
529 std::vector<uint8_t> Name_Constraints::encode_inner() const
530  {
531  throw Not_Implemented("Name_Constraints encoding");
532  }
533 
534 
535 /*
536 * Decode the extension
537 */
538 void Name_Constraints::decode_inner(const std::vector<uint8_t>& in)
539  {
540  std::vector<GeneralSubtree> permit, exclude;
541  BER_Decoder ber(in);
542  BER_Decoder ext = ber.start_cons(SEQUENCE);
543  BER_Object per = ext.get_next_object();
544 
545  ext.push_back(per);
546  if(per.type_tag == 0 && per.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
547  {
548  ext.decode_list(permit,ASN1_Tag(0),ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC));
549  if(permit.empty())
550  throw Encoding_Error("Empty Name Contraint list");
551  }
552 
553  BER_Object exc = ext.get_next_object();
554  ext.push_back(exc);
555  if(per.type_tag == 1 && per.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
556  {
557  ext.decode_list(exclude,ASN1_Tag(1),ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC));
558  if(exclude.empty())
559  throw Encoding_Error("Empty Name Contraint list");
560  }
561 
562  ext.end_cons();
563 
564  if(permit.empty() && exclude.empty())
565  throw Encoding_Error("Empty Name Contraint extension");
566 
567  m_name_constraints = NameConstraints(std::move(permit),std::move(exclude));
568  }
569 
570 /*
571 * Return a textual representation
572 */
573 void Name_Constraints::contents_to(Data_Store& subject, Data_Store&) const
574  {
575  std::stringstream ss;
576 
577  for(const GeneralSubtree& gs: m_name_constraints.permitted())
578  {
579  ss << gs;
580  subject.add("X509v3.NameConstraints.permitted", ss.str());
581  ss.str(std::string());
582  }
583  for(const GeneralSubtree& gs: m_name_constraints.excluded())
584  {
585  ss << gs;
586  subject.add("X509v3.NameConstraints.excluded", ss.str());
587  ss.str(std::string());
588  }
589  }
590 
592  const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path,
593  std::vector<std::set<Certificate_Status_Code>>& cert_status,
594  size_t pos)
595  {
596  if(!m_name_constraints.permitted().empty() || !m_name_constraints.excluded().empty())
597  {
598  if(!subject.is_CA_cert() || !subject.is_critical("X509v3.NameConstraints"))
599  cert_status.at(pos).insert(Certificate_Status_Code::NAME_CONSTRAINT_ERROR);
600 
601  const bool at_self_signed_root = (pos == cert_path.size() - 1);
602 
603  // Check that all subordinate certs pass the name constraint
604  for(size_t j = 0; j <= pos; ++j)
605  {
606  if(pos == j && at_self_signed_root)
607  continue;
608 
609  bool permitted = m_name_constraints.permitted().empty();
610  bool failed = false;
611 
612  for(auto c: m_name_constraints.permitted())
613  {
614  switch(c.base().matches(*cert_path.at(j)))
615  {
616  case GeneralName::MatchResult::NotFound:
617  case GeneralName::MatchResult::All:
618  permitted = true;
619  break;
620  case GeneralName::MatchResult::UnknownType:
621  failed = issuer.is_critical("X509v3.NameConstraints");
622  permitted = true;
623  break;
624  default:
625  break;
626  }
627  }
628 
629  for(auto c: m_name_constraints.excluded())
630  {
631  switch(c.base().matches(*cert_path.at(j)))
632  {
633  case GeneralName::MatchResult::All:
634  case GeneralName::MatchResult::Some:
635  failed = true;
636  break;
637  case GeneralName::MatchResult::UnknownType:
638  failed = issuer.is_critical("X509v3.NameConstraints");
639  break;
640  default:
641  break;
642  }
643  }
644 
645  if(failed || !permitted)
646  {
647  cert_status.at(j).insert(Certificate_Status_Code::NAME_CONSTRAINT_ERROR);
648  }
649  }
650  }
651  }
652 
653 namespace {
654 
655 /*
656 * A policy specifier
657 */
658 class Policy_Information : public ASN1_Object
659  {
660  public:
661  Policy_Information() = default;
662  explicit Policy_Information(const OID& oid) : m_oid(oid) {}
663 
664  const OID& oid() const { return m_oid; }
665 
666  void encode_into(DER_Encoder& codec) const override
667  {
668  codec.start_cons(SEQUENCE)
669  .encode(m_oid)
670  .end_cons();
671  }
672 
673  void decode_from(BER_Decoder& codec) override
674  {
675  codec.start_cons(SEQUENCE)
676  .decode(m_oid)
677  .discard_remaining()
678  .end_cons();
679  }
680 
681  private:
682  OID m_oid;
683  };
684 
685 }
686 
687 /*
688 * Encode the extension
689 */
690 std::vector<uint8_t> Certificate_Policies::encode_inner() const
691  {
692  std::vector<Policy_Information> policies;
693 
694  for(size_t i = 0; i != m_oids.size(); ++i)
695  policies.push_back(Policy_Information(m_oids[i]));
696 
697  return DER_Encoder()
698  .start_cons(SEQUENCE)
699  .encode_list(policies)
700  .end_cons()
701  .get_contents_unlocked();
702  }
703 
704 /*
705 * Decode the extension
706 */
707 void Certificate_Policies::decode_inner(const std::vector<uint8_t>& in)
708  {
709  std::vector<Policy_Information> policies;
710 
711  BER_Decoder(in).decode_list(policies);
712 
713  m_oids.clear();
714  for(size_t i = 0; i != policies.size(); ++i)
715  m_oids.push_back(policies[i].oid());
716  }
717 
718 /*
719 * Return a textual representation
720 */
721 void Certificate_Policies::contents_to(Data_Store& info, Data_Store&) const
722  {
723  for(size_t i = 0; i != m_oids.size(); ++i)
724  info.add("X509v3.CertificatePolicies", m_oids[i].as_string());
725  }
726 
727 std::vector<uint8_t> Authority_Information_Access::encode_inner() const
728  {
729  ASN1_String url(m_ocsp_responder, IA5_STRING);
730 
731  return DER_Encoder()
732  .start_cons(SEQUENCE)
733  .start_cons(SEQUENCE)
734  .encode(OIDS::lookup("PKIX.OCSP"))
735  .add_object(ASN1_Tag(6), CONTEXT_SPECIFIC, url.iso_8859())
736  .end_cons()
737  .end_cons().get_contents_unlocked();
738  }
739 
740 void Authority_Information_Access::decode_inner(const std::vector<uint8_t>& in)
741  {
742  BER_Decoder ber = BER_Decoder(in).start_cons(SEQUENCE);
743 
744  while(ber.more_items())
745  {
746  OID oid;
747 
748  BER_Decoder info = ber.start_cons(SEQUENCE);
749 
750  info.decode(oid);
751 
752  if(oid == OIDS::lookup("PKIX.OCSP"))
753  {
754  BER_Object name = info.get_next_object();
755 
756  if(name.type_tag == 6 && name.class_tag == CONTEXT_SPECIFIC)
757  {
758  m_ocsp_responder = Charset::transcode(ASN1::to_string(name),
760  LOCAL_CHARSET);
761  }
762 
763  }
764  }
765  }
766 
767 void Authority_Information_Access::contents_to(Data_Store& subject, Data_Store&) const
768  {
769  if(!m_ocsp_responder.empty())
770  subject.add("OCSP.responder", m_ocsp_responder);
771  }
772 
773 /*
774 * Checked accessor for the crl_number member
775 */
777  {
778  if(!m_has_value)
779  throw Invalid_State("CRL_Number::get_crl_number: Not set");
780  return m_crl_number;
781  }
782 
783 /*
784 * Copy a CRL_Number extension
785 */
787  {
788  if(!m_has_value)
789  throw Invalid_State("CRL_Number::copy: Not set");
790  return new CRL_Number(m_crl_number);
791  }
792 
793 /*
794 * Encode the extension
795 */
796 std::vector<uint8_t> CRL_Number::encode_inner() const
797  {
798  return DER_Encoder().encode(m_crl_number).get_contents_unlocked();
799  }
800 
801 /*
802 * Decode the extension
803 */
804 void CRL_Number::decode_inner(const std::vector<uint8_t>& in)
805  {
806  BER_Decoder(in).decode(m_crl_number);
807  }
808 
809 /*
810 * Return a textual representation
811 */
812 void CRL_Number::contents_to(Data_Store& info, Data_Store&) const
813  {
814  info.add("X509v3.CRLNumber", static_cast<uint32_t>(m_crl_number));
815  }
816 
817 /*
818 * Encode the extension
819 */
820 std::vector<uint8_t> CRL_ReasonCode::encode_inner() const
821  {
822  return DER_Encoder()
823  .encode(static_cast<size_t>(m_reason), ENUMERATED, UNIVERSAL)
824  .get_contents_unlocked();
825  }
826 
827 /*
828 * Decode the extension
829 */
830 void CRL_ReasonCode::decode_inner(const std::vector<uint8_t>& in)
831  {
832  size_t reason_code = 0;
833  BER_Decoder(in).decode(reason_code, ENUMERATED, UNIVERSAL);
834  m_reason = static_cast<CRL_Code>(reason_code);
835  }
836 
837 /*
838 * Return a textual representation
839 */
840 void CRL_ReasonCode::contents_to(Data_Store& info, Data_Store&) const
841  {
842  info.add("X509v3.CRLReasonCode", m_reason);
843  }
844 
845 std::vector<uint8_t> CRL_Distribution_Points::encode_inner() const
846  {
847  throw Not_Implemented("CRL_Distribution_Points encoding");
848  }
849 
850 void CRL_Distribution_Points::decode_inner(const std::vector<uint8_t>& buf)
851  {
852  BER_Decoder(buf).decode_list(m_distribution_points).verify_end();
853  }
854 
855 void CRL_Distribution_Points::contents_to(Data_Store& info, Data_Store&) const
856  {
857  for(size_t i = 0; i != m_distribution_points.size(); ++i)
858  {
859  auto point = m_distribution_points[i].point().contents();
860 
861  auto uris = point.equal_range("URI");
862 
863  for(auto uri = uris.first; uri != uris.second; ++uri)
864  info.add("CRL.DistributionPoint", uri->second);
865  }
866  }
867 
869  {
870  throw Not_Implemented("CRL_Distribution_Points encoding");
871  }
872 
874  {
875  ber.start_cons(SEQUENCE)
877  .decode_optional_implicit(m_point, ASN1_Tag(0),
880  .end_cons().end_cons();
881  }
882 
883 std::vector<uint8_t> Unknown_Critical_Extension::encode_inner() const
884  {
885  throw Not_Implemented("Unknown_Critical_Extension encoding");
886  }
887 
888 void Unknown_Critical_Extension::decode_inner(const std::vector<uint8_t>&)
889  {
890  }
891 
892 void Unknown_Critical_Extension::contents_to(Data_Store&, Data_Store&) const
893  {
894  }
895 
896 }
897 
898 }
std::map< OID, std::pair< std::vector< uint8_t >, bool > > extensions_raw() const
Definition: x509_ext.cpp:149
DER_Encoder & encode_list(const std::vector< T > &values)
Definition: der_enc.h:85
virtual std::string oid_name() const =0
Issuer_Alternative_Name(const AlternativeName &=AlternativeName())
Definition: x509_ext.cpp:492
DER_Encoder & encode_optional(const T &value, const T &default_value)
Definition: der_enc.h:77
std::vector< uint8_t > get_contents_unlocked()
Definition: der_enc.h:27
BER_Decoder & decode_optional_string(std::vector< uint8_t, Alloc > &out, ASN1_Tag real_type, uint16_t type_no, ASN1_Tag class_tag=CONTEXT_SPECIFIC)
Definition: ber_dec.h:162
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
Extensions(const Extensions &)
Definition: x509_ext.cpp:50
bool is_CA_cert() const
Definition: x509cert.cpp:252
void encode_into(class DER_Encoder &) const override
Definition: x509_ext.cpp:868
Alternative_Name(const AlternativeName &, const std::string &oid_name)
Definition: x509_ext.cpp:474
const std::vector< GeneralSubtree > & permitted() const
void decode_from(class BER_Decoder &) override
Definition: x509_ext.cpp:205
void replace(Certificate_Extension *extn, bool critical=false)
Definition: x509_ext.cpp:111
BER_Decoder & decode(bool &v)
Definition: ber_dec.cpp:376
OID m_oid
Definition: x509_ext.cpp:682
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:47
std::multimap< std::string, std::string > contents() const
void contents_to(Data_Store &, Data_Store &) const
Definition: x509_ext.cpp:254
DER_Encoder & end_cons()
Definition: der_enc.cpp:147
std::vector< std::pair< std::unique_ptr< Certificate_Extension >, bool > > extensions() const
Definition: x509_ext.cpp:139
void validate(const X509_Certificate &subject, const X509_Certificate &issuer, const std::vector< std::shared_ptr< const X509_Certificate >> &cert_path, std::vector< std::set< Certificate_Status_Code >> &cert_status, size_t pos) override
Definition: x509_ext.cpp:591
void add(Certificate_Extension *extn, bool critical=false)
Definition: x509_ext.cpp:91
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:216
BER_Decoder & decode_optional(T &out, ASN1_Tag type_tag, ASN1_Tag class_tag, const T &default_value=T())
Definition: ber_dec.h:213
void encode_into(class DER_Encoder &) const override
Definition: x509_ext.cpp:157
const std::vector< GeneralSubtree > & excluded() const
BER_Decoder & end_cons()
Definition: ber_dec.cpp:272
bool more_items() const
Definition: ber_dec.cpp:158
std::string transcode(const std::string &str, Character_Set to, Character_Set from)
Definition: charset.cpp:103
virtual std::vector< uint8_t > encode_inner() const =0
std::string lookup(const OID &oid)
Definition: oids.cpp:18
ASN1_Tag
Definition: asn1_obj.h:22
std::unique_ptr< Certificate_Extension > get(const OID &oid) const
Definition: x509_ext.cpp:126
virtual bool should_encode() const
Definition: x509_ext.h:78
BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: ber_dec.cpp:258
Definition: alg_id.cpp:13
BER_Decoder & decode_optional_implicit(T &out, ASN1_Tag type_tag, ASN1_Tag class_tag, ASN1_Tag real_type, ASN1_Tag real_class, const T &default_value=T())
Definition: ber_dec.h:243
Subject_Alternative_Name(const AlternativeName &=AlternativeName())
Definition: x509_ext.cpp:483
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:125
AlternativeName get_alt_name() const
Definition: x509_ext.h:287
Extensions & operator=(const Extensions &)
Definition: x509_ext.cpp:58
DER_Encoder & encode_if(bool pred, DER_Encoder &enc)
Definition: der_enc.cpp:355
BER_Decoder & verify_end()
Definition: ber_dec.cpp:168
std::string as_string() const
Definition: asn1_oid.cpp:50
bool is_critical(const std::string &ex_name) const
Definition: x509cert.cpp:343
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:137
BER_Decoder & decode_list(std::vector< T > &out, ASN1_Tag type_tag=SEQUENCE, ASN1_Tag class_tag=UNIVERSAL)
Definition: ber_dec.h:272
virtual void validate(const X509_Certificate &subject, const X509_Certificate &issuer, const std::vector< std::shared_ptr< const X509_Certificate >> &cert_path, std::vector< std::set< Certificate_Status_Code >> &cert_status, size_t pos)
Definition: x509_ext.cpp:84
CRL_Code
Definition: crl_ent.h:20
CRL_Number * copy() const override
Definition: x509_ext.cpp:786
void add(const std::multimap< std::string, std::string > &)
Definition: datastor.cpp:154
size_t low_bit(T n)
Definition: bit_ops.h:52
virtual OID oid_of() const
Definition: x509_ext.cpp:76
#define X509_EXTENSION(NAME, TYPE)