/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 | | } |