Coverage Report

Created: 2022-06-23 06:44

/src/botan/src/lib/x509/x509cert.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* X.509 Certificates
3
* (C) 1999-2010,2015,2017 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/x509cert.h>
10
#include <botan/x509_key.h>
11
#include <botan/pk_keys.h>
12
#include <botan/x509_ext.h>
13
#include <botan/ber_dec.h>
14
#include <botan/internal/parsing.h>
15
#include <botan/bigint.h>
16
#include <botan/oids.h>
17
#include <botan/hash.h>
18
#include <botan/hex.h>
19
#include <algorithm>
20
#include <sstream>
21
22
namespace Botan {
23
24
struct X509_Certificate_Data
25
   {
26
   std::vector<uint8_t> m_serial;
27
   AlgorithmIdentifier m_sig_algo_inner;
28
   X509_DN m_issuer_dn;
29
   X509_DN m_subject_dn;
30
   std::vector<uint8_t> m_issuer_dn_bits;
31
   std::vector<uint8_t> m_subject_dn_bits;
32
   X509_Time m_not_before;
33
   X509_Time m_not_after;
34
   std::vector<uint8_t> m_subject_public_key_bits;
35
   std::vector<uint8_t> m_subject_public_key_bits_seq;
36
   std::vector<uint8_t> m_subject_public_key_bitstring;
37
   std::vector<uint8_t> m_subject_public_key_bitstring_sha1;
38
   AlgorithmIdentifier m_subject_public_key_algid;
39
40
   std::vector<uint8_t> m_v2_issuer_key_id;
41
   std::vector<uint8_t> m_v2_subject_key_id;
42
   Extensions m_v3_extensions;
43
44
   std::vector<OID> m_extended_key_usage;
45
   std::vector<uint8_t> m_authority_key_id;
46
   std::vector<uint8_t> m_subject_key_id;
47
   std::vector<OID> m_cert_policies;
48
49
   std::vector<std::string> m_crl_distribution_points;
50
   std::string m_ocsp_responder;
51
   std::vector<std::string> m_ca_issuers;
52
53
   std::vector<uint8_t> m_issuer_dn_bits_sha256;
54
   std::vector<uint8_t> m_subject_dn_bits_sha256;
55
56
   std::string m_fingerprint_sha1;
57
   std::string m_fingerprint_sha256;
58
59
   AlternativeName m_subject_alt_name;
60
   AlternativeName m_issuer_alt_name;
61
   NameConstraints m_name_constraints;
62
63
   size_t m_version = 0;
64
   size_t m_path_len_constraint = 0;
65
   Key_Constraints m_key_constraints = NO_CONSTRAINTS;
66
   bool m_self_signed = false;
67
   bool m_is_ca_certificate = false;
68
   bool m_serial_negative = false;
69
   };
70
71
std::string X509_Certificate::PEM_label() const
72
8.58k
   {
73
8.58k
   return "CERTIFICATE";
74
8.58k
   }
75
76
std::vector<std::string> X509_Certificate::alternate_PEM_labels() const
77
153
   {
78
153
   return { "X509 CERTIFICATE" };
79
153
   }
80
81
X509_Certificate::X509_Certificate(DataSource& src)
82
10.3k
   {
83
10.3k
   load_data(src);
84
10.3k
   }
85
86
X509_Certificate::X509_Certificate(const std::vector<uint8_t>& vec)
87
0
   {
88
0
   DataSource_Memory src(vec.data(), vec.size());
89
0
   load_data(src);
90
0
   }
91
92
X509_Certificate::X509_Certificate(const uint8_t data[], size_t len)
93
4.09k
   {
94
4.09k
   DataSource_Memory src(data, len);
95
4.09k
   load_data(src);
96
4.09k
   }
97
98
#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
99
X509_Certificate::X509_Certificate(const std::string& fsname)
100
0
   {
101
0
   DataSource_Stream src(fsname, true);
102
0
   load_data(src);
103
0
   }
104
#endif
105
106
namespace {
107
108
std::unique_ptr<X509_Certificate_Data> parse_x509_cert_body(const X509_Object& obj)
109
12.2k
   {
110
12.2k
   auto data = std::make_unique<X509_Certificate_Data>();
111
112
12.2k
   BigInt serial_bn;
113
12.2k
   BER_Object public_key;
114
12.2k
   BER_Object v3_exts_data;
115
116
12.2k
   BER_Decoder(obj.signed_body())
117
12.2k
      .decode_optional(data->m_version, ASN1_Type(0), ASN1_Class::Constructed | ASN1_Class::ContextSpecific)
118
12.2k
      .decode(serial_bn)
119
12.2k
      .decode(data->m_sig_algo_inner)
120
12.2k
      .decode(data->m_issuer_dn)
121
12.2k
      .start_sequence()
122
12.2k
         .decode(data->m_not_before)
123
12.2k
         .decode(data->m_not_after)
124
12.2k
      .end_cons()
125
12.2k
      .decode(data->m_subject_dn)
126
12.2k
      .get_next(public_key)
127
12.2k
      .decode_optional_string(data->m_v2_issuer_key_id, ASN1_Type::BitString, 1)
128
12.2k
      .decode_optional_string(data->m_v2_subject_key_id, ASN1_Type::BitString, 2)
129
12.2k
      .get_next(v3_exts_data)
130
12.2k
      .verify_end("TBSCertificate has extra data after extensions block");
131
132
12.2k
   if(data->m_version > 2)
133
14
      throw Decoding_Error("Unknown X.509 cert version " + std::to_string(data->m_version));
134
12.2k
   if(obj.signature_algorithm() != data->m_sig_algo_inner)
135
87
      throw Decoding_Error("X.509 Certificate had differing algorithm identifers in inner and outer ID fields");
136
137
12.1k
   public_key.assert_is_a(ASN1_Type::Sequence, ASN1_Class::Constructed, "X.509 certificate public key");
138
139
   // crude method to save the serial's sign; will get lost during decoding, otherwise
140
12.1k
   data->m_serial_negative = serial_bn.is_negative();
141
142
   // for general sanity convert wire version (0 based) to standards version (v1 .. v3)
143
12.1k
   data->m_version += 1;
144
145
12.1k
   data->m_serial = BigInt::encode(serial_bn);
146
12.1k
   data->m_subject_dn_bits = ASN1::put_in_sequence(data->m_subject_dn.get_bits());
147
12.1k
   data->m_issuer_dn_bits = ASN1::put_in_sequence(data->m_issuer_dn.get_bits());
148
149
   // validate_public_key_params(public_key.value);
150
12.1k
   AlgorithmIdentifier public_key_alg_id;
151
12.1k
   BER_Decoder(public_key).decode(public_key_alg_id).discard_remaining();
152
153
12.1k
   const std::vector<std::string> public_key_info =
154
12.1k
      split_on(OIDS::oid2str_or_empty(public_key_alg_id.get_oid()), '/');
155
156
12.1k
   if(!public_key_info.empty() && public_key_info[0] == "RSA")
157
6.82k
      {
158
      // RFC4055: If PublicKeyAlgo = PSS or OAEP: limit the use of the public key exclusively to either RSASSA - PSS or RSAES - OAEP
159
6.82k
      if(public_key_info.size() >= 2)
160
2.02k
         {
161
2.02k
         if(public_key_info[1] == "EMSA4")
162
13
            {
163
            /*
164
            When the RSA private key owner wishes to limit the use of the public
165
            key exclusively to RSASSA-PSS, then the id-RSASSA-PSS object
166
            identifier MUST be used in the algorithm field within the subject
167
            public key information, and, if present, the parameters field MUST
168
            contain RSASSA-PSS-params.
169
170
            All parameters in the signature structure algorithm identifier MUST
171
            match the parameters in the key structure algorithm identifier
172
            except the saltLength field. The saltLength field in the signature parameters
173
            MUST be greater or equal to that in the key parameters field.
174
175
            ToDo: Allow salt length to be greater
176
            */
177
13
            if(public_key_alg_id != obj.signature_algorithm())
178
2
               {
179
2
               throw Decoding_Error("Algorithm identifier mismatch");
180
2
               }
181
13
            }
182
2.02k
         }
183
4.79k
      else
184
4.79k
         {
185
         // oid = rsaEncryption -> parameters field MUST contain NULL
186
4.79k
         if(public_key_alg_id != AlgorithmIdentifier(public_key_alg_id.get_oid(), AlgorithmIdentifier::USE_NULL_PARAM))
187
18
            {
188
18
            throw Decoding_Error("RSA algorithm parameters field MUST contain NULL");
189
18
            }
190
4.79k
         }
191
6.82k
      }
192
193
12.1k
   data->m_subject_public_key_bits.assign(public_key.bits(), public_key.bits() + public_key.length());
194
195
12.1k
   data->m_subject_public_key_bits_seq = ASN1::put_in_sequence(data->m_subject_public_key_bits);
196
197
12.1k
   BER_Decoder(data->m_subject_public_key_bits)
198
12.1k
      .decode(data->m_subject_public_key_algid)
199
12.1k
      .decode(data->m_subject_public_key_bitstring, ASN1_Type::BitString);
200
201
12.1k
   if(v3_exts_data.is_a(3, ASN1_Class::Constructed | ASN1_Class::ContextSpecific))
202
2.75k
      {
203
      // Path validation will reject a v1/v2 cert with v3 extensions
204
2.75k
      BER_Decoder(v3_exts_data).decode(data->m_v3_extensions).verify_end();
205
2.75k
      }
206
9.40k
   else if(v3_exts_data.is_set())
207
69
      {
208
69
          throw BER_Bad_Tag("Unknown tag in X.509 cert", v3_exts_data.tagging());
209
69
      }
210
211
   // Now cache some fields from the extensions
212
12.0k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Key_Usage>())
213
65
      {
214
65
      data->m_key_constraints = ext->get_constraints();
215
      /*
216
      RFC 5280: When the keyUsage extension appears in a certificate,
217
      at least one of the bits MUST be set to 1.
218
      */
219
65
      if(data->m_key_constraints == NO_CONSTRAINTS)
220
4
         {
221
4
         throw Decoding_Error("Certificate has invalid encoding for KeyUsage");
222
4
         }
223
65
      }
224
12.0k
   else
225
12.0k
      {
226
12.0k
      data->m_key_constraints = NO_CONSTRAINTS;
227
12.0k
      }
228
229
12.0k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Subject_Key_ID>())
230
45
      {
231
45
      data->m_subject_key_id = ext->get_key_id();
232
45
      }
233
234
12.0k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Authority_Key_ID>())
235
93
      {
236
93
      data->m_authority_key_id = ext->get_key_id();
237
93
      }
238
239
12.0k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Name_Constraints>())
240
35
      {
241
35
      data->m_name_constraints = ext->get_name_constraints();
242
35
      }
243
244
12.0k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Basic_Constraints>())
245
88
      {
246
88
      if(ext->get_is_ca() == true)
247
62
         {
248
         /*
249
         * RFC 5280 section 4.2.1.3 requires that CAs include KeyUsage in all
250
         * intermediate CA certificates they issue. Currently we accept it being
251
         * missing, as do most other implementations. But it may be worth
252
         * removing this entirely, or alternately adding a warning level
253
         * validation failure for it.
254
         */
255
62
         if(data->m_key_constraints == NO_CONSTRAINTS ||
256
62
            (data->m_key_constraints & KEY_CERT_SIGN))
257
41
            {
258
41
            data->m_is_ca_certificate = true;
259
41
            data->m_path_len_constraint = ext->get_path_limit();
260
41
            }
261
62
         }
262
88
      }
263
264
12.0k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Issuer_Alternative_Name>())
265
235
      {
266
235
      data->m_issuer_alt_name = ext->get_alt_name();
267
235
      }
268
269
12.0k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Subject_Alternative_Name>())
270
224
      {
271
224
      data->m_subject_alt_name = ext->get_alt_name();
272
224
      }
273
274
12.0k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Extended_Key_Usage>())
275
56
      {
276
56
      data->m_extended_key_usage = ext->get_oids();
277
56
      }
278
279
12.0k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Certificate_Policies>())
280
56
      {
281
56
      data->m_cert_policies = ext->get_policy_oids();
282
56
      }
283
284
12.0k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Authority_Information_Access>())
285
26
      {
286
26
      data->m_ocsp_responder = ext->ocsp_responder();
287
26
      data->m_ca_issuers = ext->ca_issuers();
288
26
      }
289
290
12.0k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::CRL_Distribution_Points>())
291
34
      {
292
34
      data->m_crl_distribution_points = ext->crl_distribution_urls();
293
34
      }
294
295
   // Check for self-signed vs self-issued certificates
296
12.0k
   if(data->m_subject_dn == data->m_issuer_dn)
297
9.25k
      {
298
9.25k
      if(data->m_subject_key_id.empty() == false && data->m_authority_key_id.empty() == false)
299
20
         {
300
20
         data->m_self_signed = (data->m_subject_key_id == data->m_authority_key_id);
301
20
         }
302
9.23k
      else
303
9.23k
         {
304
         /*
305
         If a parse error or unknown algorithm is encountered, default
306
         to assuming it is self signed. We have no way of being certain but
307
         that is usually the default case (self-issued is rare in practice).
308
         */
309
9.23k
         data->m_self_signed = true;
310
311
9.23k
         try
312
9.23k
            {
313
9.23k
            std::unique_ptr<Public_Key> pub_key(X509::load_key(data->m_subject_public_key_bits_seq));
314
315
9.23k
            Certificate_Status_Code sig_status = obj.verify_signature(*pub_key);
316
317
9.23k
            if(sig_status == Certificate_Status_Code::OK ||
318
9.23k
               sig_status == Certificate_Status_Code::SIGNATURE_ALGO_UNKNOWN)
319
4.53k
               {
320
4.53k
               data->m_self_signed = true;
321
4.53k
               }
322
4.69k
            else
323
4.69k
               {
324
4.69k
               data->m_self_signed = false;
325
4.69k
               }
326
9.23k
            }
327
9.23k
         catch(...)
328
9.23k
            {
329
            // ignore errors here to allow parsing to continue
330
2.18k
            }
331
9.23k
         }
332
9.25k
      }
333
334
12.0k
   const std::vector<uint8_t> full_encoding = obj.BER_encode();
335
336
12.0k
   std::unique_ptr<HashFunction> sha1(HashFunction::create("SHA-1"));
337
12.0k
   if(sha1)
338
10.2k
      {
339
10.2k
      sha1->update(data->m_subject_public_key_bitstring);
340
10.2k
      data->m_subject_public_key_bitstring_sha1 = sha1->final_stdvec();
341
      // otherwise left as empty, and we will throw if subject_public_key_bitstring_sha1 is called
342
343
10.2k
      data->m_fingerprint_sha1 = create_hex_fingerprint(full_encoding, "SHA-1");
344
10.2k
      }
345
346
12.0k
   std::unique_ptr<HashFunction> sha256(HashFunction::create("SHA-256"));
347
12.0k
   if(sha256)
348
10.2k
      {
349
10.2k
      sha256->update(data->m_issuer_dn_bits);
350
10.2k
      data->m_issuer_dn_bits_sha256 = sha256->final_stdvec();
351
352
10.2k
      sha256->update(data->m_subject_dn_bits);
353
10.2k
      data->m_subject_dn_bits_sha256 = sha256->final_stdvec();
354
355
10.2k
      data->m_fingerprint_sha256 = create_hex_fingerprint(full_encoding, "SHA-256");
356
10.2k
      }
357
358
12.0k
   return data;
359
12.0k
   }
360
361
}
362
363
/*
364
* Decode the TBSCertificate data
365
*/
366
void X509_Certificate::force_decode()
367
12.2k
   {
368
12.2k
   m_data.reset();
369
12.2k
   m_data = parse_x509_cert_body(*this);
370
12.2k
   }
371
372
const X509_Certificate_Data& X509_Certificate::data() const
373
0
   {
374
0
   if(m_data == nullptr)
375
0
      {
376
0
      throw Invalid_State("X509_Certificate uninitialized");
377
0
      }
378
0
   return *m_data.get();
379
0
   }
380
381
uint32_t X509_Certificate::x509_version() const
382
0
   {
383
0
   return static_cast<uint32_t>(data().m_version);
384
0
   }
385
386
bool X509_Certificate::is_self_signed() const
387
0
   {
388
0
   return data().m_self_signed;
389
0
   }
390
391
const X509_Time& X509_Certificate::not_before() const
392
0
   {
393
0
   return data().m_not_before;
394
0
   }
395
396
const X509_Time& X509_Certificate::not_after() const
397
0
   {
398
0
   return data().m_not_after;
399
0
   }
400
401
const AlgorithmIdentifier& X509_Certificate::subject_public_key_algo() const
402
0
   {
403
0
   return data().m_subject_public_key_algid;
404
0
   }
405
406
const std::vector<uint8_t>& X509_Certificate::v2_issuer_key_id() const
407
0
   {
408
0
   return data().m_v2_issuer_key_id;
409
0
   }
410
411
const std::vector<uint8_t>& X509_Certificate::v2_subject_key_id() const
412
0
   {
413
0
   return data().m_v2_subject_key_id;
414
0
   }
415
416
const std::vector<uint8_t>& X509_Certificate::subject_public_key_bits() const
417
0
   {
418
0
   return data().m_subject_public_key_bits;
419
0
   }
420
421
const std::vector<uint8_t>& X509_Certificate::subject_public_key_info() const
422
0
   {
423
0
   return data().m_subject_public_key_bits_seq;
424
0
   }
425
426
const std::vector<uint8_t>& X509_Certificate::subject_public_key_bitstring() const
427
0
   {
428
0
   return data().m_subject_public_key_bitstring;
429
0
   }
430
431
const std::vector<uint8_t>& X509_Certificate::subject_public_key_bitstring_sha1() const
432
0
   {
433
0
   if(data().m_subject_public_key_bitstring_sha1.empty())
434
0
      throw Encoding_Error("X509_Certificate::subject_public_key_bitstring_sha1 called but SHA-1 disabled in build");
435
436
0
   return data().m_subject_public_key_bitstring_sha1;
437
0
   }
438
439
const std::vector<uint8_t>& X509_Certificate::authority_key_id() const
440
0
   {
441
0
   return data().m_authority_key_id;
442
0
   }
443
444
const std::vector<uint8_t>& X509_Certificate::subject_key_id() const
445
0
   {
446
0
   return data().m_subject_key_id;
447
0
   }
448
449
const std::vector<uint8_t>& X509_Certificate::serial_number() const
450
0
   {
451
0
   return data().m_serial;
452
0
   }
453
454
bool X509_Certificate::is_serial_negative() const
455
0
   {
456
0
   return data().m_serial_negative;
457
0
   }
458
459
460
const X509_DN& X509_Certificate::issuer_dn() const
461
0
   {
462
0
   return data().m_issuer_dn;
463
0
   }
464
465
const X509_DN& X509_Certificate::subject_dn() const
466
0
   {
467
0
   return data().m_subject_dn;
468
0
   }
469
470
const std::vector<uint8_t>& X509_Certificate::raw_issuer_dn() const
471
0
   {
472
0
   return data().m_issuer_dn_bits;
473
0
   }
474
475
const std::vector<uint8_t>& X509_Certificate::raw_subject_dn() const
476
0
   {
477
0
   return data().m_subject_dn_bits;
478
0
   }
479
480
bool X509_Certificate::is_CA_cert() const
481
0
   {
482
0
   if(data().m_version < 3 && data().m_self_signed)
483
0
      return true;
484
485
0
   return data().m_is_ca_certificate;
486
0
   }
487
488
uint32_t X509_Certificate::path_limit() const
489
0
   {
490
0
   if(data().m_version < 3 && data().m_self_signed)
491
0
      return 32; // in theory infinite, but this is more than enough
492
493
0
   return static_cast<uint32_t>(data().m_path_len_constraint);
494
0
   }
495
496
Key_Constraints X509_Certificate::constraints() const
497
0
   {
498
0
   return data().m_key_constraints;
499
0
   }
500
501
const std::vector<OID>& X509_Certificate::extended_key_usage() const
502
0
   {
503
0
   return data().m_extended_key_usage;
504
0
   }
505
506
const std::vector<OID>& X509_Certificate::certificate_policy_oids() const
507
0
   {
508
0
   return data().m_cert_policies;
509
0
   }
510
511
const NameConstraints& X509_Certificate::name_constraints() const
512
0
   {
513
0
   return data().m_name_constraints;
514
0
   }
515
516
const Extensions& X509_Certificate::v3_extensions() const
517
0
   {
518
0
   return data().m_v3_extensions;
519
0
   }
520
521
bool X509_Certificate::allowed_usage(Key_Constraints usage) const
522
0
   {
523
0
   if(constraints() == NO_CONSTRAINTS)
524
0
      return true;
525
0
   return ((constraints() & usage) == usage);
526
0
   }
527
528
bool X509_Certificate::allowed_extended_usage(const std::string& usage) const
529
0
   {
530
0
   return allowed_extended_usage(OID::from_string(usage));
531
0
   }
532
533
bool X509_Certificate::allowed_extended_usage(const OID& usage) const
534
0
   {
535
0
   const std::vector<OID>& ex = extended_key_usage();
536
0
   if(ex.empty())
537
0
      return true;
538
539
0
   if(std::find(ex.begin(), ex.end(), usage) != ex.end())
540
0
      return true;
541
542
0
   return false;
543
0
   }
544
545
bool X509_Certificate::allowed_usage(Usage_Type usage) const
546
0
   {
547
   // These follow suggestions in RFC 5280 4.2.1.12
548
549
0
   switch(usage)
550
0
      {
551
0
      case Usage_Type::UNSPECIFIED:
552
0
         return true;
553
554
0
      case Usage_Type::TLS_SERVER_AUTH:
555
0
         return (allowed_usage(KEY_AGREEMENT) || allowed_usage(KEY_ENCIPHERMENT) || allowed_usage(DIGITAL_SIGNATURE)) && allowed_extended_usage("PKIX.ServerAuth");
556
557
0
      case Usage_Type::TLS_CLIENT_AUTH:
558
0
         return (allowed_usage(DIGITAL_SIGNATURE) || allowed_usage(KEY_AGREEMENT)) && allowed_extended_usage("PKIX.ClientAuth");
559
560
0
      case Usage_Type::OCSP_RESPONDER:
561
0
         return (allowed_usage(DIGITAL_SIGNATURE) || allowed_usage(NON_REPUDIATION)) && allowed_extended_usage("PKIX.OCSPSigning");
562
563
0
      case Usage_Type::CERTIFICATE_AUTHORITY:
564
0
         return is_CA_cert();
565
566
0
      case Usage_Type::ENCRYPTION:
567
0
         return (allowed_usage(KEY_ENCIPHERMENT) || allowed_usage(DATA_ENCIPHERMENT));
568
0
      }
569
570
0
   return false;
571
0
   }
572
573
bool X509_Certificate::has_constraints(Key_Constraints constraints) const
574
0
   {
575
0
   if(this->constraints() == NO_CONSTRAINTS)
576
0
      {
577
0
      return false;
578
0
      }
579
580
0
   return ((this->constraints() & constraints) != 0);
581
0
   }
582
583
bool X509_Certificate::has_ex_constraint(const OID& usage) const
584
0
   {
585
0
   const std::vector<OID>& ex = extended_key_usage();
586
0
   return (std::find(ex.begin(), ex.end(), usage) != ex.end());
587
0
   }
588
589
/*
590
* Return if a certificate extension is marked critical
591
*/
592
bool X509_Certificate::is_critical(const std::string& ex_name) const
593
0
   {
594
0
   return v3_extensions().critical_extension_set(OID::from_string(ex_name));
595
0
   }
596
597
std::string X509_Certificate::ocsp_responder() const
598
0
   {
599
0
   return data().m_ocsp_responder;
600
0
   }
601
602
std::vector<std::string> X509_Certificate::ca_issuers() const
603
0
   {
604
0
   return data().m_ca_issuers;
605
0
   }
606
607
std::string X509_Certificate::crl_distribution_point() const
608
0
   {
609
   // just returns the first (arbitrarily)
610
0
   if(!data().m_crl_distribution_points.empty())
611
0
      return data().m_crl_distribution_points[0];
612
0
   return "";
613
0
   }
614
615
const AlternativeName& X509_Certificate::subject_alt_name() const
616
0
   {
617
0
   return data().m_subject_alt_name;
618
0
   }
619
620
const AlternativeName& X509_Certificate::issuer_alt_name() const
621
0
   {
622
0
   return data().m_issuer_alt_name;
623
0
   }
624
625
/*
626
* Return information about the subject
627
*/
628
std::vector<std::string>
629
X509_Certificate::subject_info(const std::string& req) const
630
0
   {
631
0
   if(req == "Email")
632
0
      return this->subject_info("RFC822");
633
634
0
   if(subject_dn().has_field(req))
635
0
      return subject_dn().get_attribute(req);
636
637
0
   if(subject_alt_name().has_field(req))
638
0
      return subject_alt_name().get_attribute(req);
639
640
0
   return {};
641
0
   }
642
643
/*
644
* Return information about the issuer
645
*/
646
std::vector<std::string>
647
X509_Certificate::issuer_info(const std::string& req) const
648
0
   {
649
0
   if(issuer_dn().has_field(req))
650
0
      return issuer_dn().get_attribute(req);
651
652
0
   if(issuer_alt_name().has_field(req))
653
0
      return issuer_alt_name().get_attribute(req);
654
655
0
   return {};
656
0
   }
657
658
/*
659
* Return the public key in this certificate
660
*/
661
std::unique_ptr<Public_Key> X509_Certificate::load_subject_public_key() const
662
0
   {
663
0
   try
664
0
      {
665
0
      return std::unique_ptr<Public_Key>(X509::load_key(subject_public_key_info()));
666
0
      }
667
0
   catch(std::exception& e)
668
0
      {
669
0
      throw Decoding_Error("X509_Certificate::load_subject_public_key", e);
670
0
      }
671
0
   }
672
673
Public_Key* X509_Certificate::subject_public_key() const
674
0
   {
675
0
   return load_subject_public_key().release();
676
0
   }
677
678
std::vector<uint8_t> X509_Certificate::raw_issuer_dn_sha256() const
679
0
   {
680
0
   if(data().m_issuer_dn_bits_sha256.empty())
681
0
      throw Encoding_Error("X509_Certificate::raw_issuer_dn_sha256 called but SHA-256 disabled in build");
682
0
   return data().m_issuer_dn_bits_sha256;
683
0
   }
684
685
std::vector<uint8_t> X509_Certificate::raw_subject_dn_sha256() const
686
0
   {
687
0
   if(data().m_subject_dn_bits_sha256.empty())
688
0
      throw Encoding_Error("X509_Certificate::raw_subject_dn_sha256 called but SHA-256 disabled in build");
689
0
   return data().m_subject_dn_bits_sha256;
690
0
   }
691
692
std::string X509_Certificate::fingerprint(const std::string& hash_name) const
693
0
   {
694
   /*
695
   * The SHA-1 and SHA-256 fingerprints are precomputed since these
696
   * are the most commonly used. Especially, SHA-256 fingerprints are
697
   * used for cycle detection during path construction.
698
   *
699
   * If SHA-1 or SHA-256 was missing at parsing time the vectors are
700
   * left empty in which case we fall back to create_hex_fingerprint
701
   * which will throw if the hash is unavailable.
702
   */
703
0
   if(hash_name == "SHA-256" && !data().m_fingerprint_sha256.empty())
704
0
      return data().m_fingerprint_sha256;
705
0
   else if(hash_name == "SHA-1" && !data().m_fingerprint_sha1.empty())
706
0
      return data().m_fingerprint_sha1;
707
0
   else
708
0
      return create_hex_fingerprint(this->BER_encode(), hash_name);
709
0
   }
710
711
bool X509_Certificate::matches_dns_name(const std::string& name) const
712
0
   {
713
0
   if(name.empty())
714
0
      return false;
715
716
0
   auto issued_names = subject_info("DNS");
717
718
   // Fall back to CN only if no DNS names are set (RFC 6125 sec 6.4.4)
719
0
   if(issued_names.empty())
720
0
      issued_names = subject_info("Name");
721
722
0
   for(const auto& issued_name : issued_names)
723
0
      {
724
0
      if(host_wildcard_match(issued_name, name))
725
0
         return true;
726
0
      }
727
728
0
   return false;
729
0
   }
730
731
/*
732
* Compare two certificates for equality
733
*/
734
bool X509_Certificate::operator==(const X509_Certificate& other) const
735
0
   {
736
0
   return (this->signature() == other.signature() &&
737
0
           this->signature_algorithm() == other.signature_algorithm() &&
738
0
           this->signed_body() == other.signed_body());
739
0
   }
740
741
bool X509_Certificate::operator<(const X509_Certificate& other) const
742
0
   {
743
   /* If signature values are not equal, sort by lexicographic ordering of that */
744
0
   if(this->signature() != other.signature())
745
0
      {
746
0
      return (this->signature() < other.signature());
747
0
      }
748
749
   // Then compare the signed contents
750
0
   return this->signed_body() < other.signed_body();
751
0
   }
752
753
/*
754
* X.509 Certificate Comparison
755
*/
756
bool operator!=(const X509_Certificate& cert1, const X509_Certificate& cert2)
757
0
   {
758
0
   return !(cert1 == cert2);
759
0
   }
760
761
std::string X509_Certificate::to_string() const
762
0
   {
763
0
   std::ostringstream out;
764
765
0
   out << "Version: " << this->x509_version() << "\n";
766
0
   out << "Subject: " << subject_dn() << "\n";
767
0
   out << "Issuer: " << issuer_dn() << "\n";
768
0
   out << "Issued: " << this->not_before().readable_string() << "\n";
769
0
   out << "Expires: " << this->not_after().readable_string() << "\n";
770
771
0
   out << "Constraints:\n";
772
0
   Key_Constraints constraints = this->constraints();
773
0
   if(constraints == NO_CONSTRAINTS)
774
0
      out << " None\n";
775
0
   else
776
0
      {
777
0
      if(constraints & DIGITAL_SIGNATURE)
778
0
         out << "   Digital Signature\n";
779
0
      if(constraints & NON_REPUDIATION)
780
0
         out << "   Non-Repudiation\n";
781
0
      if(constraints & KEY_ENCIPHERMENT)
782
0
         out << "   Key Encipherment\n";
783
0
      if(constraints & DATA_ENCIPHERMENT)
784
0
         out << "   Data Encipherment\n";
785
0
      if(constraints & KEY_AGREEMENT)
786
0
         out << "   Key Agreement\n";
787
0
      if(constraints & KEY_CERT_SIGN)
788
0
         out << "   Cert Sign\n";
789
0
      if(constraints & CRL_SIGN)
790
0
         out << "   CRL Sign\n";
791
0
      if(constraints & ENCIPHER_ONLY)
792
0
         out << "   Encipher Only\n";
793
0
      if(constraints & DECIPHER_ONLY)
794
0
         out << "   Decipher Only\n";
795
0
      }
796
797
0
   const std::vector<OID>& policies = this->certificate_policy_oids();
798
0
   if(!policies.empty())
799
0
      {
800
0
      out << "Policies: " << "\n";
801
0
      for(const auto& oid : policies)
802
0
         out << "   " << oid.to_string() << "\n";
803
0
      }
804
805
0
   const std::vector<OID>& ex_constraints = this->extended_key_usage();
806
0
   if(!ex_constraints.empty())
807
0
      {
808
0
      out << "Extended Constraints:\n";
809
0
      for(auto&& oid : ex_constraints)
810
0
         {
811
0
         out << "   " << oid.to_formatted_string() << "\n";
812
0
         }
813
0
      }
814
815
0
   const NameConstraints& name_constraints = this->name_constraints();
816
817
0
   if(!name_constraints.permitted().empty() || !name_constraints.excluded().empty())
818
0
      {
819
0
      out << "Name Constraints:\n";
820
821
0
      if(!name_constraints.permitted().empty())
822
0
         {
823
0
         out << "   Permit";
824
0
         for(const auto& st: name_constraints.permitted())
825
0
            {
826
0
            out << " " << st.base();
827
0
            }
828
0
         out << "\n";
829
0
         }
830
831
0
      if(!name_constraints.excluded().empty())
832
0
         {
833
0
         out << "   Exclude";
834
0
         for(const auto& st: name_constraints.excluded())
835
0
            {
836
0
            out << " " << st.base();
837
0
            }
838
0
         out << "\n";
839
0
         }
840
0
      }
841
842
0
   if(!ocsp_responder().empty())
843
0
      out << "OCSP responder " << ocsp_responder() << "\n";
844
845
0
   const std::vector<std::string> ca_issuers = this->ca_issuers();
846
0
   if(!ca_issuers.empty())
847
0
      {
848
0
      out << "CA Issuers:\n";
849
0
      for(const auto& ca_issuer : ca_issuers)
850
0
         out << "   URI: " << ca_issuer << "\n";
851
0
      }
852
853
0
   if(!crl_distribution_point().empty())
854
0
      out << "CRL " << crl_distribution_point() << "\n";
855
856
0
   out << "Signature algorithm: " << this->signature_algorithm().get_oid().to_formatted_string() << "\n";
857
858
0
   out << "Serial number: " << hex_encode(this->serial_number()) << "\n";
859
860
0
   if(!this->authority_key_id().empty())
861
0
     out << "Authority keyid: " << hex_encode(this->authority_key_id()) << "\n";
862
863
0
   if(!this->subject_key_id().empty())
864
0
     out << "Subject keyid: " << hex_encode(this->subject_key_id()) << "\n";
865
866
0
   try
867
0
      {
868
0
      std::unique_ptr<Public_Key> pubkey(this->subject_public_key());
869
0
      out << "Public Key [" << pubkey->algo_name() << "-" << pubkey->key_length() << "]\n\n";
870
0
      out << X509::PEM_encode(*pubkey);
871
0
      }
872
0
   catch(Decoding_Error&)
873
0
      {
874
0
      const AlgorithmIdentifier& alg_id = this->subject_public_key_algo();
875
0
      out << "Failed to decode key with oid " << alg_id.get_oid().to_string() << "\n";
876
0
      }
877
878
0
   return out.str();
879
0
   }
880
881
}