11#include <botan/tls_policy.h>
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/stl_util.h>
28 std::vector<Signature_Scheme> schemes;
34 if(sig_allowed && hash_allowed) {
35 schemes.push_back(scheme);
123 const std::vector<Group_Params>& offered_by_peer)
const {
124 if(supported_by_peer.empty()) {
125 return Group_Params::NONE;
131 for(
auto share : offered_by_peer) {
132 if(share.is_post_quantum() &&
value_exists(our_groups, share)) {
138 for(
auto share : supported_by_peer) {
139 if(share.is_post_quantum() &&
value_exists(our_groups, share)) {
146 for(
auto g : offered_by_peer) {
154 for(
auto g : our_groups) {
160 return Group_Params::NONE;
168 if(g.is_dh_named_group()) {
173 return Group_Params::FFDHE_2048;
179#if defined(BOTAN_HAS_X25519)
180 Group_Params::X25519,
183 Group_Params::SECP256R1,
185#if defined(BOTAN_HAS_ML_KEM) && defined(BOTAN_HAS_TLS_13_PQC)
187#if defined(BOTAN_HAS_X25519)
195#if defined(BOTAN_HAS_X448)
199 Group_Params::SECP384R1,
200 Group_Params::SECP521R1,
202 Group_Params::BRAINPOOL256R1,
203 Group_Params::BRAINPOOL384R1,
204 Group_Params::BRAINPOOL512R1,
206 Group_Params::FFDHE_2048,
207 Group_Params::FFDHE_3072,
214 std::vector<Group_Params> groups_to_offer;
217 BOTAN_ASSERT(!supported_groups.empty(),
"Policy allows at least one key exchange group");
225 if(group.is_pure_ecc_group()) {
226 groups_to_offer.push_back(group);
235 if(groups_to_offer.empty()) {
236 groups_to_offer.push_back(supported_groups.front());
239 return groups_to_offer;
276 const std::string algo_name = public_key.
algo_name();
278 const size_t keylength = public_key.
key_length();
279 size_t expected_keylength = 0;
281 if(algo_name ==
"RSA") {
283 }
else if(algo_name ==
"DH") {
285 }
else if(algo_name ==
"ECDH" || algo_name ==
"X25519" || algo_name ==
"X448") {
287 }
else if(algo_name ==
"ECDSA") {
292 if(keylength < expected_keylength) {
294 "Peer sent " + std::to_string(keylength) +
" bit " + algo_name +
296 ", policy requires at least " +
297 std::to_string(expected_keylength));
306 return std::chrono::days(1);
318#if defined(BOTAN_HAS_TLS_13)
319 if(version == Protocol_Version::TLS_V13 &&
allow_tls13()) {
324#if defined(BOTAN_HAS_TLS_12)
325 if(version == Protocol_Version::TLS_V12 &&
allow_tls12()) {
329 if(version == Protocol_Version::DTLS_V12 &&
allow_dtls12()) {
340 return Protocol_Version::DTLS_V12;
342 throw Invalid_State(
"Policy forbids all available DTLS version");
344#if defined(BOTAN_HAS_TLS_13)
346 return Protocol_Version::TLS_V13;
350 return Protocol_Version::TLS_V12;
352 throw Invalid_State(
"Policy forbids all available TLS version");
374#if defined(BOTAN_HAS_TLS_12)
382#if defined(BOTAN_HAS_TLS_13)
390#if defined(BOTAN_HAS_TLS_12)
476 return 1280 - 40 - 8;
480 return std::vector<uint16_t>();
485class Ciphersuite_Preference_Ordering final {
487 Ciphersuite_Preference_Ordering(
const std::vector<std::string>& ciphers,
488 const std::vector<std::string>& macs,
489 const std::vector<std::string>& kex,
490 const std::vector<std::string>& sigs) :
491 m_ciphers(ciphers), m_macs(macs), m_kex(kex), m_sigs(sigs) {}
493 bool operator()(
const Ciphersuite& a,
const Ciphersuite& b)
const {
494 if(a.kex_method() != b.kex_method()) {
495 for(
const auto& i : m_kex) {
496 if(a.kex_algo() == i) {
499 if(b.kex_algo() == i) {
505 if(a.cipher_algo() != b.cipher_algo()) {
506 for(
const auto& m_cipher : m_ciphers) {
507 if(a.cipher_algo() == m_cipher) {
510 if(b.cipher_algo() == m_cipher) {
516 if(a.cipher_keylen() != b.cipher_keylen()) {
517 if(a.cipher_keylen() < b.cipher_keylen()) {
520 if(a.cipher_keylen() > b.cipher_keylen()) {
525 if(a.auth_method() != b.auth_method()) {
526 for(
const auto& m_sig : m_sigs) {
527 if(a.sig_algo() == m_sig) {
530 if(b.sig_algo() == m_sig) {
536 if(a.mac_algo() != b.mac_algo()) {
537 for(
const auto& m_mac : m_macs) {
538 if(a.mac_algo() == m_mac) {
541 if(b.mac_algo() == m_mac) {
551 std::vector<std::string> m_ciphers, m_macs, m_kex, m_sigs;
562 std::vector<Ciphersuite> ciphersuites;
571 if(!suite.usable_in_version(version)) {
604 ciphersuites.push_back(suite);
607 if(ciphersuites.empty()) {
608 throw Invalid_State(
"Policy does not allow any available cipher suite");
611 Ciphersuite_Preference_Ordering order(ciphers, macs, kex, sigs);
612 std::sort(ciphersuites.begin(), ciphersuites.end(), order);
614 std::vector<uint16_t> ciphersuite_codes;
615 ciphersuite_codes.reserve(ciphersuites.size());
616 for(
auto i : ciphersuites) {
617 ciphersuite_codes.push_back(i.ciphersuite_code());
619 return ciphersuite_codes;
624void print_vec(std::ostream& o,
const char* key,
const std::vector<std::string>& v) {
626 for(
size_t i = 0; i != v.size(); ++i) {
628 if(i != v.size() - 1) {
635void print_vec(std::ostream& o,
const char* key,
const std::vector<Group_Params>& params) {
637 std::vector<std::string> names;
638 for(
auto p : params) {
639 if(
auto name = p.to_string()) {
640 names.push_back(name.value());
646 for(
size_t i = 0; i != names.size(); ++i) {
648 if(i != names.size() - 1) {
655void print_vec(std::ostream& o,
const char* key,
const std::vector<Certificate_Type>& types) {
657 for(
size_t i = 0; i != types.size(); ++i) {
659 if(i != types.size() - 1) {
666void print_bool(std::ostream& o,
const char* key,
bool b) {
667 o << key <<
" = " << (b ?
"true" :
"false") <<
'\n';
684 if(groups_to_offer.empty()) {
685 print_vec(o,
"key_exchange_groups_to_offer", {std::string(
"none")});
687 print_vec(o,
"key_exchange_groups_to_offer", groups_to_offer);
714 std::ostringstream oss;
720 return {
"AES-256/GCM",
"AES-128/GCM",
"ChaCha20Poly1305"};
724 return {
"SHA-512",
"SHA-384"};
#define BOTAN_ASSERT(expr, assertion_made)
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
bool is_pre_tls_13() 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 certificate_type_to_string(Certificate_Type type)
@ HYBRID_X25519_ML_KEM_768
@ HYBRID_SECP256R1_ML_KEM_768
@ HYBRID_SECP384R1_ML_KEM_1024
bool value_exists(const std::vector< T > &vec, const OT &val)