Botan  1.11.15
src/lib/tls/tls_policy.h
Go to the documentation of this file.
00001 /*
00002 * Hooks for application level policies on TLS connections
00003 * (C) 2004-2006,2013 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #ifndef BOTAN_TLS_POLICY_H__
00009 #define BOTAN_TLS_POLICY_H__
00010 
00011 #include <botan/tls_version.h>
00012 #include <botan/tls_ciphersuite.h>
00013 #include <botan/x509cert.h>
00014 #include <botan/dl_group.h>
00015 #include <vector>
00016 
00017 namespace Botan {
00018 
00019 namespace TLS {
00020 
00021 /**
00022 * TLS Policy Base Class
00023 * Inherit and overload as desired to suit local policy concerns
00024 */
00025 class BOTAN_DLL Policy
00026    {
00027    public:
00028 
00029       /**
00030       * Returns a list of ciphers we are willing to negotiate, in
00031       * order of preference.
00032       */
00033       virtual std::vector<std::string> allowed_ciphers() const;
00034 
00035       /**
00036       * Returns a list of hash algorithms we are willing to use for
00037       * signatures, in order of preference.
00038       */
00039       virtual std::vector<std::string> allowed_signature_hashes() const;
00040 
00041       /**
00042       * Returns a list of MAC algorithms we are willing to use.
00043       */
00044       virtual std::vector<std::string> allowed_macs() const;
00045 
00046       /**
00047       * Returns a list of key exchange algorithms we are willing to
00048       * use, in order of preference. Allowed values: DH, empty string
00049       * (representing RSA using server certificate key)
00050       */
00051       virtual std::vector<std::string> allowed_key_exchange_methods() const;
00052 
00053       /**
00054       * Returns a list of signature algorithms we are willing to
00055       * use, in order of preference. Allowed values RSA and DSA.
00056       */
00057       virtual std::vector<std::string> allowed_signature_methods() const;
00058 
00059       /**
00060       * Return list of ECC curves we are willing to use in order of preference
00061       */
00062       virtual std::vector<std::string> allowed_ecc_curves() const;
00063 
00064       /**
00065       * Returns a list of compression algorithms we are willing to use,
00066       * in order of preference. Allowed values any value of
00067       * Compression_Method.
00068       *
00069       * @note Compression is not currently supported
00070       */
00071       virtual std::vector<byte> compression() const;
00072 
00073       /**
00074       * Choose an elliptic curve to use
00075       */
00076       virtual std::string choose_curve(const std::vector<std::string>& curve_names) const;
00077 
00078       /**
00079       * Attempt to negotiate the use of the heartbeat extension
00080       */
00081       virtual bool negotiate_heartbeat_support() const;
00082 
00083       /**
00084       * Allow renegotiation even if the counterparty doesn't
00085       * support the secure renegotiation extension.
00086       *
00087       * @warning Changing this to true exposes you to injected
00088       * plaintext attacks. Read RFC 5746 for background.
00089       */
00090       virtual bool allow_insecure_renegotiation() const;
00091 
00092       /**
00093       * The protocol dictates that the first 32 bits of the random
00094       * field are the current time in seconds. However this allows
00095       * client fingerprinting attacks. Set to false to disable, in
00096       * which case random bytes will be used instead.
00097       */
00098       virtual bool include_time_in_hello_random() const;
00099 
00100       /**
00101       * Allow servers to initiate a new handshake
00102       */
00103       virtual bool allow_server_initiated_renegotiation() const;
00104 
00105       virtual std::string dh_group() const;
00106 
00107       /**
00108       * Return the minimum DH group size we're willing to use
00109       */
00110       virtual size_t minimum_dh_group_size() const;
00111 
00112       /**
00113       * If this function returns false, unknown SRP/PSK identifiers
00114       * will be rejected with an unknown_psk_identifier alert as soon
00115       * as the non-existence is identified. Otherwise, a false
00116       * identifier value will be used and the protocol allowed to
00117       * proceed, causing the handshake to eventually fail without
00118       * revealing that the username does not exist on this system.
00119       */
00120       virtual bool hide_unknown_users() const;
00121 
00122       /**
00123       * Return the allowed lifetime of a session ticket. If 0, session
00124       * tickets do not expire until the session ticket key rolls over.
00125       * Expired session tickets cannot be used to resume a session.
00126       */
00127       virtual u32bit session_ticket_lifetime() const;
00128 
00129       /**
00130       * If this returns a non-empty vector, and DTLS is negotiated,
00131       * then we will also attempt to negotiate the SRTP extension from
00132       * RFC 5764 using the returned values as the profile ids.
00133       */
00134       virtual std::vector<u16bit> srtp_profiles() const;
00135 
00136       /**
00137       * @return true if and only if we are willing to accept this version
00138       * Default accepts TLS v1.0 and later or DTLS v1.2 or later.
00139       */
00140       virtual bool acceptable_protocol_version(Protocol_Version version) const;
00141 
00142       /**
00143       * Returns the more recent protocol version we are willing to
00144       * use, for either TLS or DTLS depending on datagram param.
00145       * Shouldn't ever need to override this unless you want to allow
00146       * a user to disable use of TLS v1.2 (which is *not recommended*)
00147       */
00148       virtual Protocol_Version latest_supported_version(bool datagram) const;
00149 
00150       /**
00151       * When offering this version, should we send a fallback SCSV?
00152       * Default returns true iff version is not the latest version the
00153       * policy allows, exists to allow override in case of interop problems.
00154       */
00155       virtual bool send_fallback_scsv(Protocol_Version version) const;
00156 
00157       /**
00158       * Allows policy to reject any ciphersuites which are undesirable
00159       * for whatever reason without having to reimplement ciphersuite_list
00160       */
00161       virtual bool acceptable_ciphersuite(const Ciphersuite& suite) const;
00162 
00163       /**
00164       * @return true if servers should choose the ciphersuite matching
00165       *         their highest preference, rather than the clients.
00166       *         Has no effect on client side.
00167       */
00168       virtual bool server_uses_own_ciphersuite_preferences() const;
00169 
00170       /**
00171       * Return allowed ciphersuites, in order of preference
00172       */
00173       virtual std::vector<u16bit> ciphersuite_list(Protocol_Version version,
00174                                                    bool have_srp) const;
00175 
00176       virtual void print(std::ostream& o) const;
00177 
00178       virtual ~Policy() {}
00179    };
00180 
00181 /**
00182 * NSA Suite B 128-bit security level (see @rfc 6460)
00183 */
00184 class BOTAN_DLL NSA_Suite_B_128 : public Policy
00185    {
00186    public:
00187       std::vector<std::string> allowed_ciphers() const override
00188          { return std::vector<std::string>({"AES-128/GCM"}); }
00189 
00190       std::vector<std::string> allowed_signature_hashes() const override
00191          { return std::vector<std::string>({"SHA-256"}); }
00192 
00193       std::vector<std::string> allowed_macs() const override
00194          { return std::vector<std::string>({"AEAD"}); }
00195 
00196       std::vector<std::string> allowed_key_exchange_methods() const override
00197          { return std::vector<std::string>({"ECDH"}); }
00198 
00199       std::vector<std::string> allowed_signature_methods() const override
00200          { return std::vector<std::string>({"ECDSA"}); }
00201 
00202       std::vector<std::string> allowed_ecc_curves() const override
00203          { return std::vector<std::string>({"secp256r1"}); }
00204 
00205       bool acceptable_protocol_version(Protocol_Version version) const override
00206          { return version == Protocol_Version::TLS_V12; }
00207    };
00208 
00209 /**
00210 * Policy for DTLS. We require DTLS v1.2 and an AEAD mode
00211 */
00212 class BOTAN_DLL Datagram_Policy : public Policy
00213    {
00214    public:
00215       std::vector<std::string> allowed_macs() const override
00216          { return std::vector<std::string>({"AEAD"}); }
00217 
00218       bool acceptable_protocol_version(Protocol_Version version) const override
00219          { return version == Protocol_Version::DTLS_V12; }
00220    };
00221 
00222 /*
00223 * This policy requires a secure version of TLS and disables all insecure
00224 * algorithms. It is compatible with other botan TLSes (including those using the
00225 * default policy) and with many other recent implementations. It is a great idea
00226 * to use if you control both sides of the protocol and don't have to worry
00227 * about ancient and/or bizarre TLS implementations.
00228 */
00229 class BOTAN_DLL Strict_Policy : public Policy
00230    {
00231    public:
00232       std::vector<std::string> allowed_ciphers() const override;
00233 
00234       std::vector<std::string> allowed_signature_hashes() const override;
00235 
00236       std::vector<std::string> allowed_macs() const override;
00237 
00238       std::vector<std::string> allowed_key_exchange_methods() const override;
00239 
00240       bool acceptable_protocol_version(Protocol_Version version) const override;
00241    };
00242 
00243 class BOTAN_DLL Text_Policy : public Policy
00244    {
00245    public:
00246 
00247       std::vector<std::string> allowed_ciphers() const override
00248          { return get_list("ciphers", Policy::allowed_ciphers()); }
00249 
00250       std::vector<std::string> allowed_signature_hashes() const override
00251          { return get_list("signature_hashes", Policy::allowed_signature_hashes()); }
00252 
00253       std::vector<std::string> allowed_macs() const override
00254          { return get_list("macs", Policy::allowed_macs()); }
00255 
00256       std::vector<std::string> allowed_key_exchange_methods() const override
00257          { return get_list("key_exchange_methods", Policy::allowed_key_exchange_methods()); }
00258 
00259       std::vector<std::string> allowed_signature_methods() const override
00260          { return get_list("signature_methods", Policy::allowed_signature_methods()); }
00261 
00262       std::vector<std::string> allowed_ecc_curves() const override
00263          { return get_list("ecc_curves", Policy::allowed_ecc_curves()); }
00264 
00265       bool negotiate_heartbeat_support() const override
00266          { return get_bool("negotiate_heartbeat_support", Policy::negotiate_heartbeat_support()); }
00267 
00268       bool allow_insecure_renegotiation() const override
00269          { return get_bool("allow_insecure_renegotiation", Policy::allow_insecure_renegotiation()); }
00270 
00271       bool include_time_in_hello_random() const override
00272          { return get_bool("include_time_in_hello_random", Policy::include_time_in_hello_random()); }
00273 
00274       bool allow_server_initiated_renegotiation() const override
00275          { return get_bool("allow_server_initiated_renegotiation", Policy::allow_server_initiated_renegotiation()); }
00276 
00277       bool server_uses_own_ciphersuite_preferences() const override
00278          { return get_bool("server_uses_own_ciphersuite_preferences", Policy::server_uses_own_ciphersuite_preferences()); }
00279 
00280       std::string dh_group() const override
00281          { return get_str("dh_group", Policy::dh_group()); }
00282 
00283       size_t minimum_dh_group_size() const override
00284          { return get_len("minimum_dh_group_size", Policy::minimum_dh_group_size()); }
00285 
00286       bool hide_unknown_users() const override
00287          { return get_bool("hide_unknown_users", Policy::hide_unknown_users()); }
00288 
00289       u32bit session_ticket_lifetime() const override
00290          { return get_len("session_ticket_lifetime", Policy::session_ticket_lifetime()); }
00291 
00292       std::vector<u16bit> srtp_profiles() const override
00293          {
00294          std::vector<u16bit> r;
00295          for(auto&& p : get_list("srtp_profiles", std::vector<std::string>()))
00296             {
00297             r.push_back(to_u32bit(p));
00298             }
00299          return r;
00300          }
00301 
00302       Text_Policy(std::istream& in)
00303          {
00304          m_kv = read_cfg(in);
00305          }
00306 
00307    private:
00308 
00309       std::vector<std::string> get_list(const std::string& key,
00310                                         const std::vector<std::string>& def) const
00311          {
00312          const std::string v = get_str(key);
00313 
00314          if(v == "")
00315             return def;
00316 
00317          return split_on(v, ' ');
00318          }
00319 
00320       size_t get_len(const std::string& key, size_t def) const
00321          {
00322          const std::string v = get_str(key);
00323 
00324          if(v == "")
00325             return def;
00326 
00327          return to_u32bit(v);
00328          }
00329 
00330       bool get_bool(const std::string& key, bool def) const
00331          {
00332          const std::string v = get_str(key);
00333 
00334          if(v == "")
00335             return def;
00336 
00337          if(v == "true" || v == "True")
00338             return true;
00339          else if(v == "false" || v == "False")
00340             return false;
00341          else
00342             throw std::runtime_error("Invalid boolean '" + v + "'");
00343          }
00344 
00345       std::string get_str(const std::string& key, const std::string& def = "") const
00346          {
00347          auto i = m_kv.find(key);
00348          if(i == m_kv.end())
00349             return def;
00350 
00351          return i->second;
00352          }
00353 
00354       std::map<std::string, std::string> m_kv;
00355    };
00356 
00357 }
00358 
00359 }
00360 
00361 #endif