Coverage Report

Created: 2021-10-13 08:49

/src/botan/src/lib/x509/x509_ext.cpp
Line
Count
Source (jump to first uncovered line)
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/der_enc.h>
13
#include <botan/ber_dec.h>
14
#include <botan/hash.h>
15
#include <botan/internal/loadstor.h>
16
#include <botan/internal/bit_ops.h>
17
#include <algorithm>
18
#include <set>
19
#include <sstream>
20
21
namespace Botan {
22
23
namespace {
24
25
std::unique_ptr<Certificate_Extension>
26
extension_from_oid(const OID& oid)
27
52.9k
   {
28
52.9k
   if(oid == Cert_Extension::Subject_Key_ID::static_oid())
29
1.58k
      return std::make_unique<Cert_Extension::Subject_Key_ID>();
30
31
51.3k
   if(oid == Cert_Extension::Key_Usage::static_oid())
32
1.92k
      return std::make_unique<Cert_Extension::Key_Usage>();
33
34
49.4k
   if(oid == Cert_Extension::Subject_Alternative_Name::static_oid())
35
2.77k
      return std::make_unique<Cert_Extension::Subject_Alternative_Name>();
36
37
46.6k
   if(oid == Cert_Extension::Issuer_Alternative_Name::static_oid())
38
2.42k
      return std::make_unique<Cert_Extension::Issuer_Alternative_Name>();
39
40
44.2k
   if(oid == Cert_Extension::Basic_Constraints::static_oid())
41
2.33k
      return std::make_unique<Cert_Extension::Basic_Constraints>();
42
43
41.9k
   if(oid == Cert_Extension::CRL_Number::static_oid())
44
1.87k
      return std::make_unique<Cert_Extension::CRL_Number>();
45
46
40.0k
   if(oid == Cert_Extension::CRL_ReasonCode::static_oid())
47
3.13k
      return std::make_unique<Cert_Extension::CRL_ReasonCode>();
48
49
36.9k
   if(oid == Cert_Extension::Authority_Key_ID::static_oid())
50
1.06k
      return std::make_unique<Cert_Extension::Authority_Key_ID>();
51
52
35.8k
   if(oid == Cert_Extension::Name_Constraints::static_oid())
53
4.01k
      return std::make_unique<Cert_Extension::Name_Constraints>();
54
55
31.8k
   if(oid == Cert_Extension::CRL_Distribution_Points::static_oid())
56
2.30k
      return std::make_unique<Cert_Extension::CRL_Distribution_Points>();
57
58
29.5k
   if(oid == Cert_Extension::CRL_Issuing_Distribution_Point::static_oid())
59
696
      return std::make_unique<Cert_Extension::CRL_Issuing_Distribution_Point>();
60
61
28.8k
   if(oid == Cert_Extension::Certificate_Policies::static_oid())
62
2.82k
      return std::make_unique<Cert_Extension::Certificate_Policies>();
63
64
26.0k
   if(oid == Cert_Extension::Extended_Key_Usage::static_oid())
65
1.86k
      return std::make_unique<Cert_Extension::Extended_Key_Usage>();
66
67
24.1k
   if(oid == Cert_Extension::Authority_Information_Access::static_oid())
68
631
      return std::make_unique<Cert_Extension::Authority_Information_Access>();
69
70
23.5k
   return nullptr; // unknown
71
24.1k
   }
72
73
}
74
75
/*
76
* Create a Certificate_Extension object of some kind to handle
77
*/
78
std::unique_ptr<Certificate_Extension>
79
Extensions::create_extn_obj(const OID& oid,
80
                            bool critical,
81
                            const std::vector<uint8_t>& body)
82
52.9k
   {
83
52.9k
   const std::string oid_str = oid.to_string();
84
85
52.9k
   std::unique_ptr<Certificate_Extension> extn = extension_from_oid(oid);
86
87
52.9k
   if(!extn)
88
23.5k
      {
89
      // some other unknown extension type
90
23.5k
      extn = std::make_unique<Cert_Extension::Unknown_Extension>(oid, critical);
91
23.5k
      }
92
93
52.9k
   try
94
52.9k
      {
95
52.9k
      extn->decode_inner(body);
96
52.9k
      }
97
52.9k
   catch(Decoding_Error&)
98
52.9k
      {
99
22.3k
      extn.reset(new Cert_Extension::Unknown_Extension(oid, critical));
100
22.3k
      extn->decode_inner(body);
101
22.3k
      }
102
52.9k
   return extn;
103
52.9k
   }
104
105
/*
106
* Validate the extension (the default implementation is a NOP)
107
*/
108
void Certificate_Extension::validate(const X509_Certificate&, const X509_Certificate&,
109
      const std::vector<X509_Certificate>&,
110
      std::vector<std::set<Certificate_Status_Code>>&,
111
      size_t)
112
0
   {
113
0
   }
114
115
/*
116
* Add a new cert
117
*/
118
void Extensions::add(std::unique_ptr<Certificate_Extension> extn, bool critical)
119
0
   {
120
   // sanity check: we don't want to have the same extension more than once
121
0
   if(m_extension_info.count(extn->oid_of()) > 0)
122
0
      {
123
0
      const std::string name = extn->oid_name();
124
0
      throw Invalid_Argument("Extension " + name + " already present in Extensions::add");
125
0
      }
126
127
0
   const OID oid = extn->oid_of();
128
0
   Extensions_Info info(critical, std::move(extn));
129
0
   m_extension_oids.push_back(oid);
130
0
   m_extension_info.emplace(oid, info);
131
0
   }
132
133
bool Extensions::add_new(std::unique_ptr<Certificate_Extension> extn, bool critical)
134
0
   {
135
0
   if(m_extension_info.count(extn->oid_of()) > 0)
136
0
      {
137
0
      return false; // already exists
138
0
      }
139
140
0
   const OID oid = extn->oid_of();
141
0
   Extensions_Info info(critical, std::move(extn));
142
0
   m_extension_oids.push_back(oid);
143
0
   m_extension_info.emplace(oid, info);
144
0
   return true;
145
0
   }
146
147
bool Extensions::remove(const OID& oid)
148
0
   {
149
0
   const bool erased = m_extension_info.erase(oid) > 0;
150
151
0
   if(erased)
152
0
      {
153
0
      m_extension_oids.erase(std::find(m_extension_oids.begin(), m_extension_oids.end(), oid));
154
0
      }
155
156
0
   return erased;
157
0
   }
158
159
void Extensions::replace(std::unique_ptr<Certificate_Extension> extn, bool critical)
160
0
   {
161
   // Remove it if it existed
162
0
   remove(extn->oid_of());
163
164
0
   const OID oid = extn->oid_of();
165
0
   Extensions_Info info(critical, std::move(extn));
166
0
   m_extension_oids.push_back(oid);
167
0
   m_extension_info.emplace(oid, info);
168
0
   }
169
170
bool Extensions::extension_set(const OID& oid) const
171
0
   {
172
0
   return (m_extension_info.find(oid) != m_extension_info.end());
173
0
   }
174
175
bool Extensions::critical_extension_set(const OID& oid) const
176
0
   {
177
0
   auto i = m_extension_info.find(oid);
178
0
   if(i != m_extension_info.end())
179
0
      return i->second.is_critical();
180
0
   return false;
181
0
   }
182
183
std::vector<uint8_t> Extensions::get_extension_bits(const OID& oid) const
184
0
   {
185
0
   auto i = m_extension_info.find(oid);
186
0
   if(i == m_extension_info.end())
187
0
      throw Invalid_Argument("Extensions::get_extension_bits no such extension set");
188
189
0
   return i->second.bits();
190
0
   }
191
192
const Certificate_Extension* Extensions::get_extension_object(const OID& oid) const
193
117k
   {
194
117k
   auto extn = m_extension_info.find(oid);
195
117k
   if(extn == m_extension_info.end())
196
113k
      return nullptr;
197
198
3.91k
   return &extn->second.obj();
199
117k
   }
200
201
std::unique_ptr<Certificate_Extension> Extensions::get(const OID& oid) const
202
0
   {
203
0
   if(const Certificate_Extension* ext = this->get_extension_object(oid))
204
0
      {
205
0
      return ext->copy();
206
0
      }
207
0
   return nullptr;
208
0
   }
209
210
std::vector<std::pair<std::unique_ptr<Certificate_Extension>, bool>> Extensions::extensions() const
211
0
   {
212
0
   std::vector<std::pair<std::unique_ptr<Certificate_Extension>, bool>> exts;
213
0
   for(auto&& ext : m_extension_info)
214
0
      {
215
0
      exts.push_back(
216
0
         std::make_pair(
217
0
            ext.second.obj().copy(),
218
0
            ext.second.is_critical())
219
0
         );
220
0
      }
221
0
   return exts;
222
0
   }
223
224
std::map<OID, std::pair<std::vector<uint8_t>, bool>> Extensions::extensions_raw() const
225
0
   {
226
0
   std::map<OID, std::pair<std::vector<uint8_t>, bool>> out;
227
0
   for(auto&& ext : m_extension_info)
228
0
      {
229
0
      out.emplace(ext.first,
230
0
                  std::make_pair(ext.second.bits(),
231
0
                                 ext.second.is_critical()));
232
0
      }
233
0
   return out;
234
0
   }
235
236
/*
237
* Encode an Extensions list
238
*/
239
void Extensions::encode_into(DER_Encoder& to_object) const
240
0
   {
241
0
   for(auto ext_info : m_extension_info)
242
0
      {
243
0
      const OID& oid = ext_info.first;
244
0
      const bool should_encode = ext_info.second.obj().should_encode();
245
246
0
      if(should_encode)
247
0
         {
248
0
         const bool is_critical = ext_info.second.is_critical();
249
0
         const std::vector<uint8_t>& ext_value = ext_info.second.bits();
250
251
0
         to_object.start_sequence()
252
0
               .encode(oid)
253
0
               .encode_optional(is_critical, false)
254
0
               .encode(ext_value, ASN1_Type::OctetString)
255
0
            .end_cons();
256
0
         }
257
0
      }
258
0
   }
259
260
/*
261
* Decode a list of Extensions
262
*/
263
void Extensions::decode_from(BER_Decoder& from_source)
264
8.73k
   {
265
8.73k
   m_extension_oids.clear();
266
8.73k
   m_extension_info.clear();
267
268
8.73k
   BER_Decoder sequence = from_source.start_sequence();
269
270
64.4k
   while(sequence.more_items())
271
55.7k
      {
272
55.7k
      OID oid;
273
55.7k
      bool critical;
274
55.7k
      std::vector<uint8_t> bits;
275
276
55.7k
      sequence.start_sequence()
277
55.7k
         .decode(oid)
278
55.7k
         .decode_optional(critical, ASN1_Type::Boolean, ASN1_Class::Universal, false)
279
55.7k
         .decode(bits, ASN1_Type::OctetString)
280
55.7k
      .end_cons();
281
282
55.7k
      std::unique_ptr<Certificate_Extension> obj = create_extn_obj(oid, critical, bits);
283
55.7k
      Extensions_Info info(critical, bits, std::move(obj));
284
285
55.7k
      m_extension_oids.push_back(oid);
286
55.7k
      m_extension_info.emplace(oid, info);
287
55.7k
      }
288
8.73k
   sequence.verify_end();
289
8.73k
   }
290
291
namespace Cert_Extension {
292
293
/*
294
* Checked accessor for the path_limit member
295
*/
296
size_t Basic_Constraints::get_path_limit() const
297
18
   {
298
18
   if(!m_is_ca)
299
0
      throw Invalid_State("Basic_Constraints::get_path_limit: Not a CA");
300
18
   return m_path_limit;
301
18
   }
302
303
/*
304
* Encode the extension
305
*/
306
std::vector<uint8_t> Basic_Constraints::encode_inner() const
307
0
   {
308
0
   std::vector<uint8_t> output;
309
0
   DER_Encoder(output)
310
0
      .start_sequence()
311
0
      .encode_if(m_is_ca,
312
0
                 DER_Encoder()
313
0
                    .encode(m_is_ca)
314
0
                    .encode_optional(m_path_limit, NO_CERT_PATH_LIMIT)
315
0
         )
316
0
      .end_cons();
317
0
   return output;
318
0
   }
319
320
/*
321
* Decode the extension
322
*/
323
void Basic_Constraints::decode_inner(const std::vector<uint8_t>& in)
324
2.33k
   {
325
2.33k
   BER_Decoder(in)
326
2.33k
      .start_sequence()
327
2.33k
         .decode_optional(m_is_ca, ASN1_Type::Boolean, ASN1_Class::Universal, false)
328
2.33k
         .decode_optional(m_path_limit, ASN1_Type::Integer, ASN1_Class::Universal, NO_CERT_PATH_LIMIT)
329
2.33k
      .end_cons();
330
331
2.33k
   if(m_is_ca == false)
332
437
      m_path_limit = 0;
333
2.33k
   }
334
335
/*
336
* Encode the extension
337
*/
338
std::vector<uint8_t> Key_Usage::encode_inner() const
339
0
   {
340
0
   if(m_constraints == NO_CONSTRAINTS)
341
0
      throw Encoding_Error("Cannot encode zero usage constraints");
342
343
0
   const size_t unused_bits = ctz(static_cast<uint32_t>(m_constraints));
344
345
0
   std::vector<uint8_t> der;
346
0
   der.push_back(static_cast<uint8_t>(ASN1_Type::BitString));
347
0
   der.push_back(2 + ((unused_bits < 8) ? 1 : 0));
348
0
   der.push_back(unused_bits % 8);
349
0
   der.push_back((m_constraints >> 8) & 0xFF);
350
0
   if(m_constraints & 0xFF)
351
0
      der.push_back(m_constraints & 0xFF);
352
353
0
   return der;
354
0
   }
355
356
/*
357
* Decode the extension
358
*/
359
void Key_Usage::decode_inner(const std::vector<uint8_t>& in)
360
1.92k
   {
361
1.92k
   BER_Decoder ber(in);
362
363
1.92k
   BER_Object obj = ber.get_next_object();
364
365
1.92k
   obj.assert_is_a(ASN1_Type::BitString, ASN1_Class::Universal, "usage constraint");
366
367
1.92k
   if(obj.length() != 2 && obj.length() != 3)
368
211
      throw BER_Decoding_Error("Bad size for BITSTRING in usage constraint");
369
370
1.71k
   uint16_t usage = 0;
371
372
1.71k
      const uint8_t* bits = obj.bits();
373
374
1.71k
   if(bits[0] >= 8)
375
202
      throw BER_Decoding_Error("Invalid unused bits in usage constraint");
376
377
1.51k
   const uint8_t mask = static_cast<uint8_t>(0xFF << bits[0]);
378
379
1.51k
   if(obj.length() == 2)
380
225
      {
381
225
      usage = make_uint16(bits[1] & mask, 0);
382
225
      }
383
1.28k
   else if(obj.length() == 3)
384
64
      {
385
64
      usage = make_uint16(bits[1], bits[2] & mask);
386
64
      }
387
388
1.51k
   m_constraints = Key_Constraints(usage);
389
1.51k
   }
390
391
/*
392
* Encode the extension
393
*/
394
std::vector<uint8_t> Subject_Key_ID::encode_inner() const
395
0
   {
396
0
   std::vector<uint8_t> output;
397
0
   DER_Encoder(output).encode(m_key_id, ASN1_Type::OctetString);
398
0
   return output;
399
0
   }
400
401
/*
402
* Decode the extension
403
*/
404
void Subject_Key_ID::decode_inner(const std::vector<uint8_t>& in)
405
1.58k
   {
406
1.58k
   BER_Decoder(in).decode(m_key_id, ASN1_Type::OctetString).verify_end();
407
1.58k
   }
408
409
/*
410
* Subject_Key_ID Constructor
411
*/
412
Subject_Key_ID::Subject_Key_ID(const std::vector<uint8_t>& pub_key, const std::string& hash_name)
413
0
   {
414
0
   std::unique_ptr<HashFunction> hash(HashFunction::create_or_throw(hash_name));
415
416
0
   m_key_id.resize(hash->output_length());
417
418
0
   hash->update(pub_key);
419
0
   hash->final(m_key_id.data());
420
421
   // Truncate longer hashes, 192 bits here seems plenty
422
0
   const size_t max_skid_len = (192 / 8);
423
0
   if(m_key_id.size() > max_skid_len)
424
0
      m_key_id.resize(max_skid_len);
425
0
   }
426
427
/*
428
* Encode the extension
429
*/
430
std::vector<uint8_t> Authority_Key_ID::encode_inner() const
431
0
   {
432
0
   std::vector<uint8_t> output;
433
0
   DER_Encoder(output)
434
0
      .start_sequence()
435
0
         .encode(m_key_id, ASN1_Type::OctetString, ASN1_Type(0), ASN1_Class::ContextSpecific)
436
0
      .end_cons();
437
0
   return output;
438
0
   }
439
440
/*
441
* Decode the extension
442
*/
443
void Authority_Key_ID::decode_inner(const std::vector<uint8_t>& in)
444
1.06k
   {
445
1.06k
   BER_Decoder(in)
446
1.06k
      .start_sequence()
447
1.06k
      .decode_optional_string(m_key_id, ASN1_Type::OctetString, 0);
448
1.06k
   }
449
450
/*
451
* Encode the extension
452
*/
453
std::vector<uint8_t> Subject_Alternative_Name::encode_inner() const
454
0
   {
455
0
   std::vector<uint8_t> output;
456
0
   DER_Encoder(output).encode(m_alt_name);
457
0
   return output;
458
0
   }
459
460
/*
461
* Encode the extension
462
*/
463
std::vector<uint8_t> Issuer_Alternative_Name::encode_inner() const
464
0
   {
465
0
   std::vector<uint8_t> output;
466
0
   DER_Encoder(output).encode(m_alt_name);
467
0
   return output;
468
0
   }
469
470
/*
471
* Decode the extension
472
*/
473
void Subject_Alternative_Name::decode_inner(const std::vector<uint8_t>& in)
474
2.77k
   {
475
2.77k
   BER_Decoder(in).decode(m_alt_name);
476
2.77k
   }
477
478
/*
479
* Decode the extension
480
*/
481
void Issuer_Alternative_Name::decode_inner(const std::vector<uint8_t>& in)
482
2.42k
   {
483
2.42k
   BER_Decoder(in).decode(m_alt_name);
484
2.42k
   }
485
486
/*
487
* Encode the extension
488
*/
489
std::vector<uint8_t> Extended_Key_Usage::encode_inner() const
490
0
   {
491
0
   std::vector<uint8_t> output;
492
0
   DER_Encoder(output)
493
0
      .start_sequence()
494
0
         .encode_list(m_oids)
495
0
      .end_cons();
496
0
   return output;
497
0
   }
498
499
/*
500
* Decode the extension
501
*/
502
void Extended_Key_Usage::decode_inner(const std::vector<uint8_t>& in)
503
1.86k
   {
504
1.86k
   BER_Decoder(in).decode_list(m_oids);
505
1.86k
   }
506
507
/*
508
* Encode the extension
509
*/
510
std::vector<uint8_t> Name_Constraints::encode_inner() const
511
0
   {
512
0
   throw Not_Implemented("Name_Constraints encoding");
513
0
   }
514
515
516
/*
517
* Decode the extension
518
*/
519
void Name_Constraints::decode_inner(const std::vector<uint8_t>& in)
520
4.01k
   {
521
4.01k
   std::vector<GeneralSubtree> permit, exclude;
522
4.01k
   BER_Decoder ber(in);
523
4.01k
   BER_Decoder ext = ber.start_sequence();
524
4.01k
   BER_Object per = ext.get_next_object();
525
526
4.01k
   ext.push_back(per);
527
4.01k
   if(per.is_a(0, ASN1_Class::Constructed | ASN1_Class::ContextSpecific))
528
1.25k
      {
529
1.25k
      ext.decode_list(permit, ASN1_Type(0), ASN1_Class::Constructed | ASN1_Class::ContextSpecific);
530
1.25k
      if(permit.empty())
531
5
         throw Encoding_Error("Empty Name Contraint list");
532
1.25k
      }
533
534
4.00k
   BER_Object exc = ext.get_next_object();
535
4.00k
   ext.push_back(exc);
536
4.00k
   if(per.is_a(1, ASN1_Class::Constructed | ASN1_Class::ContextSpecific))
537
1.58k
      {
538
1.58k
      ext.decode_list(exclude, ASN1_Type(1), ASN1_Class::Constructed | ASN1_Class::ContextSpecific);
539
1.58k
      if(exclude.empty())
540
6
         throw Encoding_Error("Empty Name Contraint list");
541
1.58k
      }
542
543
4.00k
   ext.end_cons();
544
545
4.00k
   if(permit.empty() && exclude.empty())
546
31
      throw Encoding_Error("Empty Name Contraint extension");
547
548
3.97k
   m_name_constraints = NameConstraints(std::move(permit),std::move(exclude));
549
3.97k
   }
550
551
void Name_Constraints::validate(const X509_Certificate& subject, const X509_Certificate& issuer,
552
      const std::vector<X509_Certificate>& cert_path,
553
      std::vector<std::set<Certificate_Status_Code>>& cert_status,
554
      size_t pos)
555
0
   {
556
0
   if(!m_name_constraints.permitted().empty() || !m_name_constraints.excluded().empty())
557
0
      {
558
0
      if(!subject.is_CA_cert())
559
0
         {
560
0
         cert_status.at(pos).insert(Certificate_Status_Code::NAME_CONSTRAINT_ERROR);
561
0
         }
562
563
0
      const bool issuer_name_constraint_critical =
564
0
         issuer.is_critical("X509v3.NameConstraints");
565
566
      // Check that all subordinate certs pass the name constraint
567
0
      for(size_t j = 0; j < pos; ++j)
568
0
         {
569
0
         bool permitted = m_name_constraints.permitted().empty();
570
0
         bool failed = false;
571
572
0
         for(auto c: m_name_constraints.permitted())
573
0
            {
574
0
            switch(c.base().matches(cert_path.at(j)))
575
0
               {
576
0
               case GeneralName::MatchResult::NotFound:
577
0
               case GeneralName::MatchResult::All:
578
0
                  permitted = true;
579
0
                  break;
580
0
               case GeneralName::MatchResult::UnknownType:
581
0
                  failed = issuer_name_constraint_critical;
582
0
                  permitted = true;
583
0
                  break;
584
0
               default:
585
0
                  break;
586
0
               }
587
0
            }
588
589
0
         for(auto c: m_name_constraints.excluded())
590
0
            {
591
0
            switch(c.base().matches(cert_path.at(j)))
592
0
               {
593
0
               case GeneralName::MatchResult::All:
594
0
               case GeneralName::MatchResult::Some:
595
0
                  failed = true;
596
0
                  break;
597
0
               case GeneralName::MatchResult::UnknownType:
598
0
                  failed = issuer_name_constraint_critical;
599
0
                  break;
600
0
               default:
601
0
                  break;
602
0
               }
603
0
            }
604
605
0
         if(failed || !permitted)
606
0
            {
607
0
            cert_status.at(j).insert(Certificate_Status_Code::NAME_CONSTRAINT_ERROR);
608
0
            }
609
0
         }
610
0
      }
611
0
   }
612
613
namespace {
614
615
/*
616
* A policy specifier
617
*/
618
class Policy_Information final : public ASN1_Object
619
   {
620
   public:
621
1.30k
      Policy_Information() = default;
622
0
      explicit Policy_Information(const OID& oid) : m_oid(oid) {}
623
624
523
      const OID& oid() const { return m_oid; }
625
626
      void encode_into(DER_Encoder& codec) const override
627
0
         {
628
0
         codec.start_sequence()
629
0
            .encode(m_oid)
630
0
            .end_cons();
631
0
         }
632
633
      void decode_from(BER_Decoder& codec) override
634
1.30k
         {
635
1.30k
         codec.start_sequence()
636
1.30k
            .decode(m_oid)
637
1.30k
            .discard_remaining()
638
1.30k
            .end_cons();
639
1.30k
         }
640
641
   private:
642
      OID m_oid;
643
   };
644
645
}
646
647
/*
648
* Encode the extension
649
*/
650
std::vector<uint8_t> Certificate_Policies::encode_inner() const
651
0
   {
652
0
   std::vector<Policy_Information> policies;
653
654
0
   for(size_t i = 0; i != m_oids.size(); ++i)
655
0
      policies.push_back(Policy_Information(m_oids[i]));
656
657
0
   std::vector<uint8_t> output;
658
0
   DER_Encoder(output)
659
0
      .start_sequence()
660
0
         .encode_list(policies)
661
0
      .end_cons();
662
0
   return output;
663
0
   }
664
665
/*
666
* Decode the extension
667
*/
668
void Certificate_Policies::decode_inner(const std::vector<uint8_t>& in)
669
2.82k
   {
670
2.82k
   std::vector<Policy_Information> policies;
671
672
2.82k
   BER_Decoder(in).decode_list(policies);
673
2.82k
   m_oids.clear();
674
3.34k
   for(size_t i = 0; i != policies.size(); ++i)
675
523
      m_oids.push_back(policies[i].oid());
676
2.82k
   }
677
678
void Certificate_Policies::validate(
679
   const X509_Certificate& /*subject*/,
680
   const X509_Certificate& /*issuer*/,
681
   const std::vector<X509_Certificate>& /*cert_path*/,
682
   std::vector<std::set<Certificate_Status_Code>>& cert_status,
683
   size_t pos)
684
0
   {
685
0
   std::set<OID> oid_set(m_oids.begin(), m_oids.end());
686
0
   if(oid_set.size() != m_oids.size())
687
0
      {
688
0
      cert_status.at(pos).insert(Certificate_Status_Code::DUPLICATE_CERT_POLICY);
689
0
      }
690
0
   }
691
692
std::vector<uint8_t> Authority_Information_Access::encode_inner() const
693
0
   {
694
0
   ASN1_String url(m_ocsp_responder, ASN1_Type::Ia5String);
695
696
0
   std::vector<uint8_t> output;
697
0
   DER_Encoder(output)
698
0
      .start_sequence()
699
0
      .start_sequence()
700
0
      .encode(OID::from_string("PKIX.OCSP"))
701
0
      .add_object(ASN1_Type(6), ASN1_Class::ContextSpecific, url.value())
702
0
      .end_cons()
703
0
      .end_cons();
704
0
   return output;
705
0
   }
706
707
void Authority_Information_Access::decode_inner(const std::vector<uint8_t>& in)
708
631
   {
709
631
   BER_Decoder ber = BER_Decoder(in).start_sequence();
710
711
2.07k
   while(ber.more_items())
712
1.44k
      {
713
1.44k
      OID oid;
714
715
1.44k
      BER_Decoder info = ber.start_sequence();
716
717
1.44k
      info.decode(oid);
718
719
1.44k
      if(oid == OID::from_string("PKIX.OCSP"))
720
203
         {
721
203
         BER_Object name = info.get_next_object();
722
723
203
         if(name.is_a(6, ASN1_Class::ContextSpecific))
724
96
            {
725
96
            m_ocsp_responder = ASN1::to_string(name);
726
96
            }
727
728
203
         }
729
1.44k
      if(oid == OID::from_string("PKIX.CertificateAuthorityIssuers"))
730
245
         {
731
245
         BER_Object name = info.get_next_object();
732
733
245
         if(name.is_a(6, ASN1_Class::ContextSpecific))
734
149
            {
735
149
            m_ca_issuers.push_back(ASN1::to_string(name));
736
149
            }
737
245
         }
738
1.44k
      }
739
631
   }
740
741
/*
742
* Checked accessor for the crl_number member
743
*/
744
size_t CRL_Number::get_crl_number() const
745
9
   {
746
9
   if(!m_has_value)
747
0
      throw Invalid_State("CRL_Number::get_crl_number: Not set");
748
9
   return m_crl_number;
749
9
   }
750
751
/*
752
* Copy a CRL_Number extension
753
*/
754
std::unique_ptr<Certificate_Extension> CRL_Number::copy() const
755
0
   {
756
0
   if(!m_has_value)
757
0
      throw Invalid_State("CRL_Number::copy: Not set");
758
0
   return std::make_unique<CRL_Number>(m_crl_number);
759
0
   }
760
761
/*
762
* Encode the extension
763
*/
764
std::vector<uint8_t> CRL_Number::encode_inner() const
765
0
   {
766
0
   std::vector<uint8_t> output;
767
0
   DER_Encoder(output).encode(m_crl_number);
768
0
   return output;
769
0
   }
770
771
/*
772
* Decode the extension
773
*/
774
void CRL_Number::decode_inner(const std::vector<uint8_t>& in)
775
1.87k
   {
776
1.87k
   BER_Decoder(in).decode(m_crl_number);
777
1.87k
   m_has_value = true;
778
1.87k
   }
779
780
/*
781
* Encode the extension
782
*/
783
std::vector<uint8_t> CRL_ReasonCode::encode_inner() const
784
0
   {
785
0
   std::vector<uint8_t> output;
786
0
   DER_Encoder(output).encode(static_cast<size_t>(m_reason), ASN1_Type::Enumerated, ASN1_Class::Universal);
787
0
   return output;
788
0
   }
789
790
/*
791
* Decode the extension
792
*/
793
void CRL_ReasonCode::decode_inner(const std::vector<uint8_t>& in)
794
3.13k
   {
795
3.13k
   size_t reason_code = 0;
796
3.13k
   BER_Decoder(in).decode(reason_code, ASN1_Type::Enumerated, ASN1_Class::Universal);
797
3.13k
   m_reason = static_cast<CRL_Code>(reason_code);
798
3.13k
   }
799
800
std::vector<uint8_t> CRL_Distribution_Points::encode_inner() const
801
0
   {
802
0
   throw Not_Implemented("CRL_Distribution_Points encoding");
803
0
   }
804
805
void CRL_Distribution_Points::decode_inner(const std::vector<uint8_t>& buf)
806
2.30k
   {
807
2.30k
   BER_Decoder(buf)
808
2.30k
      .decode_list(m_distribution_points)
809
2.30k
      .verify_end();
810
811
2.30k
   std::stringstream ss;
812
813
2.99k
   for(size_t i = 0; i != m_distribution_points.size(); ++i)
814
693
      {
815
693
      auto contents = m_distribution_points[i].point().contents();
816
817
693
      for(const auto& pair : contents)
818
4.33k
         {
819
4.33k
         ss << pair.first << ": " << pair.second << " ";
820
4.33k
         }
821
693
      }
822
823
2.30k
   m_crl_distribution_urls.push_back(ss.str());
824
2.30k
   }
825
826
void CRL_Distribution_Points::Distribution_Point::encode_into(class DER_Encoder&) const
827
0
   {
828
0
   throw Not_Implemented("CRL_Distribution_Points encoding");
829
0
   }
830
831
void CRL_Distribution_Points::Distribution_Point::decode_from(class BER_Decoder& ber)
832
3.63k
   {
833
3.63k
   ber.start_sequence()
834
3.63k
      .start_context_specific(0)
835
3.63k
        .decode_optional_implicit(m_point, ASN1_Type(0),
836
3.63k
                                  ASN1_Class::ContextSpecific | ASN1_Class::Constructed,
837
3.63k
                                  ASN1_Type::Sequence, ASN1_Class::Constructed)
838
3.63k
      .end_cons().end_cons();
839
3.63k
   }
840
841
std::vector<uint8_t> CRL_Issuing_Distribution_Point::encode_inner() const
842
0
   {
843
0
   throw Not_Implemented("CRL_Issuing_Distribution_Point encoding");
844
0
   }
845
846
void CRL_Issuing_Distribution_Point::decode_inner(const std::vector<uint8_t>& buf)
847
696
   {
848
696
   BER_Decoder(buf).decode(m_distribution_point).verify_end();
849
696
   }
850
851
std::vector<uint8_t> Unknown_Extension::encode_inner() const
852
0
   {
853
0
   return m_bytes;
854
0
   }
855
856
void Unknown_Extension::decode_inner(const std::vector<uint8_t>& bytes)
857
45.8k
   {
858
   // Just treat as an opaque blob at this level
859
45.8k
   m_bytes = bytes;
860
45.8k
   }
861
862
}
863
864
}