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