Coverage Report

Created: 2023-01-25 06:35

/src/botan/src/lib/tls/tls_policy.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Policies for TLS
3
* (C) 2004-2010,2012,2015,2016 Jack Lloyd
4
*     2016 Christian Mainka
5
*     2017 Harry Reimann, Rohde & Schwarz Cybersecurity
6
*     2022 René Meusel, Hannes Rantzsch - neXenio GmbH
7
*
8
* Botan is released under the Simplified BSD License (see license.txt)
9
*/
10
11
#include <botan/tls_policy.h>
12
#include <botan/tls_ciphersuite.h>
13
#include <botan/tls_algos.h>
14
#include <botan/tls_exceptn.h>
15
#include <botan/internal/stl_util.h>
16
#include <botan/pk_keys.h>
17
#include <optional>
18
#include <sstream>
19
20
namespace Botan::TLS {
21
22
std::vector<Signature_Scheme> Policy::allowed_signature_schemes() const
23
2.51k
   {
24
2.51k
   std::vector<Signature_Scheme> schemes;
25
26
2.51k
   for(Signature_Scheme scheme : Signature_Scheme::all_available_schemes())
27
22.5k
      {
28
22.5k
      const bool sig_allowed = allowed_signature_method(scheme.algorithm_name());
29
22.5k
      const bool hash_allowed = allowed_signature_hash(scheme.hash_function_name());
30
31
22.5k
      if(sig_allowed && hash_allowed)
32
22.5k
         {
33
22.5k
         schemes.push_back(scheme);
34
22.5k
         }
35
22.5k
      }
36
37
2.51k
   return schemes;
38
2.51k
   }
39
40
std::vector<Signature_Scheme> Policy::acceptable_signature_schemes() const
41
2.39k
   {
42
2.39k
   return this->allowed_signature_schemes();
43
2.39k
   }
44
45
std::vector<std::string> Policy::allowed_ciphers() const
46
0
   {
47
0
   return {
48
      //"AES-256/OCB(12)",
49
0
      "ChaCha20Poly1305",
50
0
      "AES-256/GCM",
51
0
      "AES-128/GCM",
52
      //"AES-256/CCM",
53
      //"AES-128/CCM",
54
      //"AES-256/CCM(8)",
55
      //"AES-128/CCM(8)",
56
      //"Camellia-256/GCM",
57
      //"Camellia-128/GCM",
58
      //"ARIA-256/GCM",
59
      //"ARIA-128/GCM",
60
      //"AES-256",
61
      //"AES-128",
62
      //"3DES",
63
0
      };
64
0
   }
65
66
std::vector<std::string> Policy::allowed_signature_hashes() const
67
23.9k
   {
68
23.9k
   return {
69
23.9k
      "SHA-512",
70
23.9k
      "SHA-384",
71
23.9k
      "SHA-256",
72
23.9k
      };
73
23.9k
   }
74
75
std::vector<std::string> Policy::allowed_macs() const
76
0
   {
77
   /*
78
   SHA-256 is preferred because the Lucky13 countermeasure works
79
   somewhat better for SHA-256 vs SHA-384:
80
   https://github.com/randombit/botan/pull/675
81
   */
82
0
   return {
83
0
      "AEAD",
84
0
      "SHA-256",
85
0
      "SHA-384",
86
0
      "SHA-1",
87
0
      };
88
0
   }
89
90
std::vector<std::string> Policy::allowed_key_exchange_methods() const
91
0
   {
92
0
   return {
93
      //"ECDHE_PSK",
94
      //"PSK",
95
0
      "ECDH",
96
0
      "DH",
97
      //"RSA",
98
0
      };
99
0
   }
100
101
std::vector<std::string> Policy::allowed_signature_methods() const
102
22.5k
   {
103
22.5k
   return {
104
22.5k
      "ECDSA",
105
22.5k
      "RSA",
106
      //"IMPLICIT",
107
22.5k
      };
108
22.5k
   }
109
110
bool Policy::allowed_signature_method(const std::string& sig_method) const
111
22.5k
   {
112
22.5k
   return value_exists(allowed_signature_methods(), sig_method);
113
22.5k
   }
114
115
bool Policy::allowed_signature_hash(const std::string& sig_hash) const
116
23.9k
   {
117
23.9k
   return value_exists(allowed_signature_hashes(), sig_hash);
118
23.9k
   }
119
120
bool Policy::use_ecc_point_compression() const
121
5.16k
   {
122
5.16k
   return false;
123
5.16k
   }
124
125
Group_Params Policy::choose_key_exchange_group(const std::vector<Group_Params>& supported_by_peer,
126
                                               const std::vector<Group_Params>& offered_by_peer) const
127
59.7k
   {
128
59.7k
   if(supported_by_peer.empty())
129
1.21k
      return Group_Params::NONE;
130
131
58.5k
   const std::vector<Group_Params> our_groups = key_exchange_groups();
132
133
   // Prefer groups that were offered by the peer for the sake of saving
134
   // an additional round trip. For TLS 1.2, this won't be used.
135
58.5k
   for(auto g : offered_by_peer)
136
0
      {
137
0
      if(value_exists(our_groups, g))
138
0
         return g;
139
0
      }
140
141
   // If no pre-offered groups fit our supported set, we prioritize our
142
   // own preference.
143
58.5k
   for(auto g : our_groups)
144
300k
      {
145
300k
      if(value_exists(supported_by_peer, g))
146
58.3k
         return g;
147
300k
      }
148
149
167
   return Group_Params::NONE;
150
58.5k
   }
151
152
Group_Params Policy::default_dh_group() const
153
0
   {
154
   /*
155
   * Return the first listed or just default to 2048
156
   */
157
0
   for(auto g : key_exchange_groups())
158
0
      {
159
0
      if(group_param_is_dh(g))
160
0
         return g;
161
0
      }
162
163
0
   return Group_Params::FFDHE_2048;
164
0
   }
165
166
std::vector<Group_Params> Policy::key_exchange_groups() const
167
60.9k
   {
168
   // Default list is ordered by performance
169
60.9k
   return {
170
171
60.9k
#if defined(BOTAN_HAS_CURVE_25519)
172
60.9k
      Group_Params::X25519,
173
60.9k
#endif
174
175
60.9k
      Group_Params::SECP256R1,
176
60.9k
      Group_Params::BRAINPOOL256R1,
177
60.9k
      Group_Params::SECP384R1,
178
60.9k
      Group_Params::BRAINPOOL384R1,
179
60.9k
      Group_Params::SECP521R1,
180
60.9k
      Group_Params::BRAINPOOL512R1,
181
182
60.9k
      Group_Params::FFDHE_2048,
183
60.9k
      Group_Params::FFDHE_3072,
184
60.9k
      Group_Params::FFDHE_4096,
185
60.9k
      Group_Params::FFDHE_6144,
186
60.9k
      Group_Params::FFDHE_8192,
187
60.9k
      };
188
60.9k
   }
189
190
std::vector<Group_Params> Policy::key_exchange_groups_to_offer() const
191
0
   {
192
   // by default, we offer a key share for the most-preferred group, only
193
0
   std::vector<Group_Params> groups_to_offer;
194
0
   const auto supported_groups = key_exchange_groups();
195
0
   if (!supported_groups.empty())
196
0
      groups_to_offer.push_back(supported_groups.front());
197
0
   return groups_to_offer;
198
0
   }
199
200
size_t Policy::minimum_dh_group_size() const
201
0
   {
202
0
   return 2048;
203
0
   }
204
205
size_t Policy::minimum_ecdsa_group_size() const
206
0
   {
207
   // Here we are at the mercy of whatever the CA signed, but most certs should be 256 bit by now
208
0
   return 256;
209
0
   }
210
211
size_t Policy::minimum_ecdh_group_size() const
212
0
   {
213
   // x25519 is smallest curve currently supported for TLS key exchange
214
0
   return 255;
215
0
   }
216
217
size_t Policy::minimum_signature_strength() const
218
0
   {
219
0
   return 110;
220
0
   }
221
222
bool Policy::require_cert_revocation_info() const
223
0
   {
224
0
   return true;
225
0
   }
226
227
size_t Policy::minimum_rsa_bits() const
228
0
   {
229
   /* Default assumption is all end-entity certificates should
230
      be at least 2048 bits these days.
231
232
      If you are connecting to arbitrary servers on the Internet
233
      (ie as a web browser or SMTP client) you'll probably have to reduce this
234
      to 1024 bits, or perhaps even lower.
235
   */
236
0
   return 2048;
237
0
   }
238
239
void Policy::check_peer_key_acceptable(const Public_Key& public_key) const
240
0
   {
241
0
   const std::string algo_name = public_key.algo_name();
242
243
0
   const size_t keylength = public_key.key_length();
244
0
   size_t expected_keylength = 0;
245
246
0
   if(algo_name == "RSA")
247
0
      {
248
0
      expected_keylength = minimum_rsa_bits();
249
0
      }
250
0
   else if(algo_name == "DH")
251
0
      {
252
0
      expected_keylength = minimum_dh_group_size();
253
0
      }
254
0
   else if(algo_name == "ECDH" || algo_name == "Curve25519")
255
0
      {
256
0
      expected_keylength = minimum_ecdh_group_size();
257
0
      }
258
0
   else if(algo_name == "ECDSA")
259
0
      {
260
0
      expected_keylength = minimum_ecdsa_group_size();
261
0
      }
262
   // else some other algo, so leave expected_keylength as zero and the check is a no-op
263
264
0
   if(keylength < expected_keylength)
265
0
      throw TLS_Exception(Alert::INSUFFICIENT_SECURITY,
266
0
                          "Peer sent " +
267
0
                           std::to_string(keylength) + " bit " + algo_name + " key"
268
0
                           ", policy requires at least " +
269
0
                           std::to_string(expected_keylength));
270
0
   }
271
272
uint32_t Policy::session_ticket_lifetime() const
273
21.3k
   {
274
21.3k
   return 86400; // ~1 day
275
21.3k
   }
276
277
bool Policy::acceptable_protocol_version(Protocol_Version version) const
278
15.7k
   {
279
15.7k
#if defined(BOTAN_HAS_TLS_13)
280
15.7k
   if(version == Protocol_Version::TLS_V13 && allow_tls13())
281
0
      return true;
282
15.7k
#endif
283
284
15.7k
#if defined(BOTAN_HAS_TLS_12)
285
15.7k
   if(version == Protocol_Version::TLS_V12 && allow_tls12())
286
9.77k
      return true;
287
288
5.93k
   if(version == Protocol_Version::DTLS_V12 && allow_dtls12())
289
952
      return true;
290
4.98k
#endif
291
292
4.98k
   return false;
293
5.93k
   }
294
295
Protocol_Version Policy::latest_supported_version(bool datagram) const
296
5.93k
   {
297
5.93k
   if(datagram)
298
952
      {
299
952
      if(acceptable_protocol_version(Protocol_Version::DTLS_V12))
300
952
         return Protocol_Version::DTLS_V12;
301
0
      throw Invalid_State("Policy forbids all available DTLS version");
302
952
      }
303
4.98k
   else
304
4.98k
      {
305
4.98k
#if defined(BOTAN_HAS_TLS_13)
306
4.98k
      if(acceptable_protocol_version(Protocol_Version::TLS_V13))
307
0
         return Protocol_Version::TLS_V13;
308
4.98k
#endif
309
4.98k
      if(acceptable_protocol_version(Protocol_Version::TLS_V12))
310
4.98k
         return Protocol_Version::TLS_V12;
311
0
      throw Invalid_State("Policy forbids all available TLS version");
312
4.98k
      }
313
5.93k
   }
314
315
bool Policy::acceptable_ciphersuite(const Ciphersuite& ciphersuite) const
316
0
   {
317
0
   return value_exists(allowed_ciphers(), ciphersuite.cipher_algo()) &&
318
0
          value_exists(allowed_macs(), ciphersuite.mac_algo());
319
0
   }
320
321
0
bool Policy::allow_client_initiated_renegotiation() const { return false; }
322
0
bool Policy::allow_server_initiated_renegotiation() const { return false; }
323
24.7k
bool Policy::allow_insecure_renegotiation() const { return false; }
324
bool Policy::allow_tls12() const
325
77.6k
   {
326
77.6k
#if defined(BOTAN_HAS_TLS_12)
327
77.6k
   return true;
328
#else
329
   return false;
330
#endif
331
77.6k
   }
332
bool Policy::allow_tls13() const
333
0
   {
334
0
#if defined(BOTAN_HAS_TLS_13)
335
0
   return true;
336
#else
337
   return false;
338
#endif
339
0
   }
340
bool Policy::allow_dtls12() const
341
3.38k
   {
342
3.38k
#if defined(BOTAN_HAS_TLS_12)
343
3.38k
   return true;
344
#else
345
   return false;
346
#endif
347
3.38k
   }
348
44.3k
bool Policy::include_time_in_hello_random() const { return true; }
349
0
bool Policy::hide_unknown_users() const { return false; }
350
21.1k
bool Policy::server_uses_own_ciphersuite_preferences() const { return true; }
351
4.68k
bool Policy::negotiate_encrypt_then_mac() const { return true; }
352
0
std::optional<uint16_t> Policy::record_size_limit() const { return std::nullopt; }
353
3.80k
bool Policy::support_cert_status_message() const { return true; }
354
0
bool Policy::allow_resumption_for_renegotiation() const { return true; }
355
0
bool Policy::tls_13_middlebox_compatibility_mode() const { return true; }
356
44.3k
bool Policy::hash_hello_random() const { return true; }
357
0
bool Policy::only_resume_with_exact_version() const { return true; }
358
20.8k
bool Policy::require_client_certificate_authentication() const { return false; }
359
20.8k
bool Policy::request_client_certificate_authentication() const { return require_client_certificate_authentication(); }
360
0
bool Policy::abort_connection_on_undesired_renegotiation() const { return false; }
361
952
bool Policy::allow_dtls_epoch0_restart() const { return false; }
362
363
1.37k
size_t Policy::maximum_certificate_chain_size() const { return 0; }
364
365
// 1 second initial timeout, 60 second max - see RFC 6347 sec 4.2.4.1
366
799
size_t Policy::dtls_initial_timeout() const { return 1*1000; }
367
799
size_t Policy::dtls_maximum_timeout() const { return 60*1000; }
368
369
size_t Policy::dtls_default_mtu() const
370
799
   {
371
   // default MTU is IPv6 min MTU minus UDP/IP headers
372
799
   return 1280 - 40 - 8;
373
799
   }
374
375
std::vector<uint16_t> Policy::srtp_profiles() const
376
0
   {
377
0
   return std::vector<uint16_t>();
378
0
   }
379
380
namespace {
381
382
class Ciphersuite_Preference_Ordering final
383
   {
384
   public:
385
      Ciphersuite_Preference_Ordering(const std::vector<std::string>& ciphers,
386
                                      const std::vector<std::string>& macs,
387
                                      const std::vector<std::string>& kex,
388
                                      const std::vector<std::string>& sigs) :
389
0
         m_ciphers(ciphers), m_macs(macs), m_kex(kex), m_sigs(sigs) {}
390
391
      bool operator()(const Ciphersuite& a, const Ciphersuite& b) const
392
0
         {
393
0
         if(a.kex_method() != b.kex_method())
394
0
            {
395
0
            for(const auto & i : m_kex)
396
0
               {
397
0
               if(a.kex_algo() == i)
398
0
                  return true;
399
0
               if(b.kex_algo() == i)
400
0
                  return false;
401
0
               }
402
0
            }
403
404
0
         if(a.cipher_algo() != b.cipher_algo())
405
0
            {
406
0
            for(const auto & m_cipher : m_ciphers)
407
0
               {
408
0
               if(a.cipher_algo() == m_cipher)
409
0
                  return true;
410
0
               if(b.cipher_algo() == m_cipher)
411
0
                  return false;
412
0
               }
413
0
            }
414
415
0
         if(a.cipher_keylen() != b.cipher_keylen())
416
0
            {
417
0
            if(a.cipher_keylen() < b.cipher_keylen())
418
0
               return false;
419
0
            if(a.cipher_keylen() > b.cipher_keylen())
420
0
               return true;
421
0
            }
422
423
0
         if(a.auth_method() != b.auth_method())
424
0
            {
425
0
            for(const auto & m_sig : m_sigs)
426
0
               {
427
0
               if(a.sig_algo() == m_sig)
428
0
                  return true;
429
0
               if(b.sig_algo() == m_sig)
430
0
                  return false;
431
0
               }
432
0
            }
433
434
0
         if(a.mac_algo() != b.mac_algo())
435
0
            {
436
0
            for(const auto & m_mac : m_macs)
437
0
               {
438
0
               if(a.mac_algo() == m_mac)
439
0
                  return true;
440
0
               if(b.mac_algo() == m_mac)
441
0
                  return false;
442
0
               }
443
0
            }
444
445
0
         return false; // equal (?!?)
446
0
         }
447
   private:
448
      std::vector<std::string> m_ciphers, m_macs, m_kex, m_sigs;
449
   };
450
451
}
452
453
std::vector<uint16_t> Policy::ciphersuite_list(Protocol_Version version) const
454
0
   {
455
0
   const std::vector<std::string> ciphers = allowed_ciphers();
456
0
   const std::vector<std::string> macs = allowed_macs();
457
0
   const std::vector<std::string> kex = allowed_key_exchange_methods();
458
0
   const std::vector<std::string> sigs = allowed_signature_methods();
459
460
0
   std::vector<Ciphersuite> ciphersuites;
461
462
0
   for(auto&& suite : Ciphersuite::all_known_ciphersuites())
463
0
      {
464
      // Can we use it?
465
0
      if(!suite.valid())
466
0
         continue;
467
468
      // Can we use it in this version?
469
0
      if(!suite.usable_in_version(version))
470
0
         continue;
471
472
      // Is it acceptable to the policy?
473
0
      if(!this->acceptable_ciphersuite(suite))
474
0
         continue;
475
476
0
      if(!value_exists(ciphers, suite.cipher_algo()))
477
0
         continue; // unsupported cipher
478
479
      // these checks are irrelevant for TLS 1.3
480
      // TODO: consider making a method for this logic
481
0
      if(version.is_pre_tls_13())
482
0
         {
483
0
         if(!value_exists(kex, suite.kex_algo()))
484
0
            continue; // unsupported key exchange
485
486
0
         if(!value_exists(macs, suite.mac_algo()))
487
0
            continue; // unsupported MAC algo
488
489
0
         if(!value_exists(sigs, suite.sig_algo()))
490
0
            {
491
            // allow if it's an empty sig algo and we want to use PSK
492
0
            if(suite.auth_method() != Auth_Method::IMPLICIT || !suite.psk_ciphersuite())
493
0
               continue;
494
0
            }
495
0
         }
496
497
      // OK, consider it
498
0
      ciphersuites.push_back(suite);
499
0
      }
500
501
0
   if(ciphersuites.empty())
502
0
      {
503
0
      throw Invalid_State("Policy does not allow any available cipher suite");
504
0
      }
505
506
0
   Ciphersuite_Preference_Ordering order(ciphers, macs, kex, sigs);
507
0
   std::sort(ciphersuites.begin(), ciphersuites.end(), order);
508
509
0
   std::vector<uint16_t> ciphersuite_codes;
510
0
   ciphersuite_codes.reserve(ciphersuites.size());
511
0
   for(auto i : ciphersuites)
512
0
      ciphersuite_codes.push_back(i.ciphersuite_code());
513
0
   return ciphersuite_codes;
514
0
   }
515
516
namespace {
517
518
void print_vec(std::ostream& o,
519
               const char* key,
520
               const std::vector<std::string>& v)
521
0
   {
522
0
   o << key << " = ";
523
0
   for(size_t i = 0; i != v.size(); ++i)
524
0
      {
525
0
      o << v[i];
526
0
      if(i != v.size() - 1)
527
0
         o << ' ';
528
0
      }
529
0
   o << '\n';
530
0
   }
531
532
void print_vec(std::ostream& o,
533
               const char* key,
534
               const std::vector<Group_Params>& v)
535
0
   {
536
0
   o << key << " = ";
537
0
   for(size_t i = 0; i != v.size(); ++i)
538
0
      {
539
0
      o << group_param_to_string(v[i]);
540
0
      if(i != v.size() - 1)
541
0
         o << ' ';
542
0
      }
543
0
   o << '\n';
544
0
   }
545
546
void print_bool(std::ostream& o,
547
                const char* key, bool b)
548
0
   {
549
0
   o << key << " = " << (b ? "true" : "false") << '\n';
550
0
   }
551
552
}
553
554
void Policy::print(std::ostream& o) const
555
0
   {
556
0
   print_bool(o, "allow_tls12", allow_tls12());
557
0
   print_bool(o, "allow_tls13", allow_tls13());
558
0
   print_bool(o, "allow_dtls12", allow_dtls12());
559
0
   print_vec(o, "ciphers", allowed_ciphers());
560
0
   print_vec(o, "macs", allowed_macs());
561
0
   print_vec(o, "signature_hashes", allowed_signature_hashes());
562
0
   print_vec(o, "signature_methods", allowed_signature_methods());
563
0
   print_vec(o, "key_exchange_methods", allowed_key_exchange_methods());
564
0
   print_vec(o, "key_exchange_groups", key_exchange_groups());
565
0
   const auto groups_to_offer = key_exchange_groups_to_offer();
566
0
   if (groups_to_offer.empty()) {
567
0
      print_vec(o, "key_exchange_groups_to_offer", { std::string("none") });
568
0
   } else {
569
0
      print_vec(o, "key_exchange_groups_to_offer", groups_to_offer);
570
0
   }
571
0
   print_bool(o, "allow_insecure_renegotiation", allow_insecure_renegotiation());
572
0
   print_bool(o, "include_time_in_hello_random", include_time_in_hello_random());
573
0
   print_bool(o, "allow_server_initiated_renegotiation", allow_server_initiated_renegotiation());
574
0
   print_bool(o, "hide_unknown_users", hide_unknown_users());
575
0
   print_bool(o, "server_uses_own_ciphersuite_preferences", server_uses_own_ciphersuite_preferences());
576
0
   print_bool(o, "negotiate_encrypt_then_mac", negotiate_encrypt_then_mac());
577
0
   print_bool(o, "support_cert_status_message", support_cert_status_message());
578
0
   print_bool(o, "tls_13_middlebox_compatibility_mode", tls_13_middlebox_compatibility_mode());
579
0
   print_bool(o, "hash_hello_random", hash_hello_random());
580
0
   if (record_size_limit().has_value()) {
581
0
      o << "record_size_limit = " << record_size_limit().has_value() << '\n';
582
0
   }
583
0
   o << "session_ticket_lifetime = " << session_ticket_lifetime() << '\n';
584
0
   o << "minimum_dh_group_size = " << minimum_dh_group_size() << '\n';
585
0
   o << "minimum_ecdh_group_size = " << minimum_ecdh_group_size() << '\n';
586
0
   o << "minimum_rsa_bits = " << minimum_rsa_bits() << '\n';
587
0
   o << "minimum_signature_strength = " << minimum_signature_strength() << '\n';
588
0
   }
589
590
std::string Policy::to_string() const
591
0
   {
592
0
   std::ostringstream oss;
593
0
   this->print(oss);
594
0
   return oss.str();
595
0
   }
596
597
std::vector<std::string> Strict_Policy::allowed_ciphers() const
598
0
   {
599
0
   return { "ChaCha20Poly1305", "AES-256/GCM", "AES-128/GCM" };
600
0
   }
601
602
std::vector<std::string> Strict_Policy::allowed_signature_hashes() const
603
0
   {
604
0
   return { "SHA-512", "SHA-384"};
605
0
   }
606
607
std::vector<std::string> Strict_Policy::allowed_macs() const
608
0
   {
609
0
   return { "AEAD" };
610
0
   }
611
612
std::vector<std::string> Strict_Policy::allowed_key_exchange_methods() const
613
0
   {
614
0
   return { "ECDH" };
615
0
   }
616
617
}