Coverage Report

Created: 2020-06-30 13:58

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