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