Coverage Report

Created: 2022-09-23 06:05

/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
10.1k
   {
73
10.1k
   return "CERTIFICATE";
74
10.1k
   }
75
76
std::vector<std::string> X509_Certificate::alternate_PEM_labels() const
77
166
   {
78
166
   return { "X509 CERTIFICATE" };
79
166
   }
80
81
X509_Certificate::X509_Certificate(DataSource& src)
82
12.2k
   {
83
12.2k
   load_data(src);
84
12.2k
   }
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
5.03k
   {
94
5.03k
   DataSource_Memory src(data, len);
95
5.03k
   load_data(src);
96
5.03k
   }
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
14.9k
   {
110
14.9k
   auto data = std::make_unique<X509_Certificate_Data>();
111
112
14.9k
   BigInt serial_bn;
113
14.9k
   BER_Object public_key;
114
14.9k
   BER_Object v3_exts_data;
115
116
14.9k
   BER_Decoder(obj.signed_body())
117
14.9k
      .decode_optional(data->m_version, ASN1_Type(0), ASN1_Class::Constructed | ASN1_Class::ContextSpecific)
118
14.9k
      .decode(serial_bn)
119
14.9k
      .decode(data->m_sig_algo_inner)
120
14.9k
      .decode(data->m_issuer_dn)
121
14.9k
      .start_sequence()
122
14.9k
         .decode(data->m_not_before)
123
14.9k
         .decode(data->m_not_after)
124
14.9k
      .end_cons()
125
14.9k
      .decode(data->m_subject_dn)
126
14.9k
      .get_next(public_key)
127
14.9k
      .decode_optional_string(data->m_v2_issuer_key_id, ASN1_Type::BitString, 1)
128
14.9k
      .decode_optional_string(data->m_v2_subject_key_id, ASN1_Type::BitString, 2)
129
14.9k
      .get_next(v3_exts_data)
130
14.9k
      .verify_end("TBSCertificate has extra data after extensions block");
131
132
14.9k
   if(data->m_version > 2)
133
18
      throw Decoding_Error("Unknown X.509 cert version " + std::to_string(data->m_version));
134
14.9k
   if(obj.signature_algorithm() != data->m_sig_algo_inner)
135
85
      throw Decoding_Error("X.509 Certificate had differing algorithm identifers in inner and outer ID fields");
136
137
14.8k
   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
14.8k
   data->m_serial_negative = serial_bn.is_negative();
141
142
   // for general sanity convert wire version (0 based) to standards version (v1 .. v3)
143
14.8k
   data->m_version += 1;
144
145
14.8k
   data->m_serial = BigInt::encode(serial_bn);
146
14.8k
   data->m_subject_dn_bits = ASN1::put_in_sequence(data->m_subject_dn.get_bits());
147
14.8k
   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
14.8k
   AlgorithmIdentifier public_key_alg_id;
151
14.8k
   BER_Decoder(public_key).decode(public_key_alg_id).discard_remaining();
152
153
14.8k
   const std::vector<std::string> public_key_info =
154
14.8k
      split_on(OIDS::oid2str_or_empty(public_key_alg_id.get_oid()), '/');
155
156
14.8k
   if(!public_key_info.empty() && public_key_info[0] == "RSA")
157
8.20k
      {
158
      // RFC4055: If PublicKeyAlgo = PSS or OAEP: limit the use of the public key exclusively to either RSASSA - PSS or RSAES - OAEP
159
8.20k
      if(public_key_info.size() >= 2)
160
2.44k
         {
161
2.44k
         if(public_key_info[1] == "EMSA4")
162
14
            {
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
14
            if(public_key_alg_id != obj.signature_algorithm())
178
2
               {
179
2
               throw Decoding_Error("Algorithm identifier mismatch");
180
2
               }
181
14
            }
182
2.44k
         }
183
5.76k
      else
184
5.76k
         {
185
         // oid = rsaEncryption -> parameters field MUST contain NULL
186
5.76k
         if(public_key_alg_id != AlgorithmIdentifier(public_key_alg_id.get_oid(), AlgorithmIdentifier::USE_NULL_PARAM))
187
31
            {
188
31
            throw Decoding_Error("RSA algorithm parameters field MUST contain NULL");
189
31
            }
190
5.76k
         }
191
8.20k
      }
192
193
14.7k
   data->m_subject_public_key_bits.assign(public_key.bits(), public_key.bits() + public_key.length());
194
195
14.7k
   data->m_subject_public_key_bits_seq = ASN1::put_in_sequence(data->m_subject_public_key_bits);
196
197
14.7k
   BER_Decoder(data->m_subject_public_key_bits)
198
14.7k
      .decode(data->m_subject_public_key_algid)
199
14.7k
      .decode(data->m_subject_public_key_bitstring, ASN1_Type::BitString);
200
201
14.7k
   if(v3_exts_data.is_a(3, ASN1_Class::Constructed | ASN1_Class::ContextSpecific))
202
3.55k
      {
203
      // Path validation will reject a v1/v2 cert with v3 extensions
204
3.55k
      BER_Decoder(v3_exts_data).decode(data->m_v3_extensions).verify_end();
205
3.55k
      }
206
11.2k
   else if(v3_exts_data.is_set())
207
105
      {
208
105
          throw BER_Bad_Tag("Unknown tag in X.509 cert", v3_exts_data.tagging());
209
105
      }
210
211
   // Now cache some fields from the extensions
212
14.6k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Key_Usage>())
213
77
      {
214
77
      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
77
      if(data->m_key_constraints == NO_CONSTRAINTS)
220
5
         {
221
5
         throw Decoding_Error("Certificate has invalid encoding for KeyUsage");
222
5
         }
223
77
      }
224
14.6k
   else
225
14.6k
      {
226
14.6k
      data->m_key_constraints = NO_CONSTRAINTS;
227
14.6k
      }
228
229
14.6k
   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
14.6k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Authority_Key_ID>())
235
67
      {
236
67
      data->m_authority_key_id = ext->get_key_id();
237
67
      }
238
239
14.6k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Name_Constraints>())
240
57
      {
241
57
      data->m_name_constraints = ext->get_name_constraints();
242
57
      }
243
244
14.6k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Basic_Constraints>())
245
81
      {
246
81
      if(ext->get_is_ca() == true)
247
60
         {
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
60
         if(data->m_key_constraints == NO_CONSTRAINTS ||
256
60
            (data->m_key_constraints & KEY_CERT_SIGN))
257
44
            {
258
44
            data->m_is_ca_certificate = true;
259
44
            data->m_path_len_constraint = ext->get_path_limit();
260
44
            }
261
60
         }
262
81
      }
263
264
14.6k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Issuer_Alternative_Name>())
265
409
      {
266
409
      data->m_issuer_alt_name = ext->get_alt_name();
267
409
      }
268
269
14.6k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Subject_Alternative_Name>())
270
286
      {
271
286
      data->m_subject_alt_name = ext->get_alt_name();
272
286
      }
273
274
14.6k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Extended_Key_Usage>())
275
71
      {
276
71
      data->m_extended_key_usage = ext->get_oids();
277
71
      }
278
279
14.6k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Certificate_Policies>())
280
70
      {
281
70
      data->m_cert_policies = ext->get_policy_oids();
282
70
      }
283
284
14.6k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Authority_Information_Access>())
285
24
      {
286
24
      data->m_ocsp_responder = ext->ocsp_responder();
287
24
      data->m_ca_issuers = ext->ca_issuers();
288
24
      }
289
290
14.6k
   if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::CRL_Distribution_Points>())
291
67
      {
292
67
      data->m_crl_distribution_points = ext->crl_distribution_urls();
293
67
      }
294
295
   // Check for self-signed vs self-issued certificates
296
14.6k
   if(data->m_subject_dn == data->m_issuer_dn)
297
11.2k
      {
298
11.2k
      if(data->m_subject_key_id.empty() == false && data->m_authority_key_id.empty() == false)
299
24
         {
300
24
         data->m_self_signed = (data->m_subject_key_id == data->m_authority_key_id);
301
24
         }
302
11.2k
      else
303
11.2k
         {
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
11.2k
         data->m_self_signed = true;
310
311
11.2k
         try
312
11.2k
            {
313
11.2k
            std::unique_ptr<Public_Key> pub_key(X509::load_key(data->m_subject_public_key_bits_seq));
314
315
11.2k
            Certificate_Status_Code sig_status = obj.verify_signature(*pub_key);
316
317
11.2k
            if(sig_status == Certificate_Status_Code::OK ||
318
11.2k
               sig_status == Certificate_Status_Code::SIGNATURE_ALGO_UNKNOWN)
319
5.46k
               {
320
5.46k
               data->m_self_signed = true;
321
5.46k
               }
322
5.74k
            else
323
5.74k
               {
324
5.74k
               data->m_self_signed = false;
325
5.74k
               }
326
11.2k
            }
327
11.2k
         catch(...)
328
11.2k
            {
329
            // ignore errors here to allow parsing to continue
330
2.50k
            }
331
11.2k
         }
332
11.2k
      }
333
334
14.6k
   const std::vector<uint8_t> full_encoding = obj.BER_encode();
335
336
14.6k
   std::unique_ptr<HashFunction> sha1(HashFunction::create("SHA-1"));
337
14.6k
   if(sha1)
338
12.2k
      {
339
12.2k
      sha1->update(data->m_subject_public_key_bitstring);
340
12.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
12.2k
      data->m_fingerprint_sha1 = create_hex_fingerprint(full_encoding, "SHA-1");
344
12.2k
      }
345
346
14.6k
   std::unique_ptr<HashFunction> sha256(HashFunction::create("SHA-256"));
347
14.6k
   if(sha256)
348
12.2k
      {
349
12.2k
      sha256->update(data->m_issuer_dn_bits);
350
12.2k
      data->m_issuer_dn_bits_sha256 = sha256->final_stdvec();
351
352
12.2k
      sha256->update(data->m_subject_dn_bits);
353
12.2k
      data->m_subject_dn_bits_sha256 = sha256->final_stdvec();
354
355
12.2k
      data->m_fingerprint_sha256 = create_hex_fingerprint(full_encoding, "SHA-256");
356
12.2k
      }
357
358
14.6k
   return data;
359
14.6k
   }
360
361
}
362
363
/*
364
* Decode the TBSCertificate data
365
*/
366
void X509_Certificate::force_decode()
367
14.9k
   {
368
14.9k
   m_data.reset();
369
14.9k
   m_data = parse_x509_cert_body(*this);
370
14.9k
   }
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
}