Botan  1.11.15
src/lib/tls/tls_policy.cpp
Go to the documentation of this file.
00001 /*
00002 * Policies for TLS
00003 * (C) 2004-2010,2012 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/tls_policy.h>
00009 #include <botan/tls_ciphersuite.h>
00010 #include <botan/tls_magic.h>
00011 #include <botan/tls_exceptn.h>
00012 #include <botan/internal/stl_util.h>
00013 
00014 namespace Botan {
00015 
00016 namespace TLS {
00017 
00018 std::vector<std::string> Policy::allowed_ciphers() const
00019    {
00020    return {
00021       //"AES-256/OCB(12)",
00022       //"AES-128/OCB(12)",
00023       "ChaCha20Poly1305",
00024       "AES-256/GCM",
00025       "AES-128/GCM",
00026       "AES-256/CCM",
00027       "AES-128/CCM",
00028       "AES-256/CCM(8)",
00029       "AES-128/CCM(8)",
00030       //"Camellia-256/GCM",
00031       //"Camellia-128/GCM",
00032       "AES-256",
00033       "AES-128",
00034       //"Camellia-256",
00035       //"Camellia-128",
00036       //"SEED"
00037       //"3DES",
00038       //"RC4",
00039       };
00040    }
00041 
00042 std::vector<std::string> Policy::allowed_signature_hashes() const
00043    {
00044    return {
00045       "SHA-512",
00046       "SHA-384",
00047       "SHA-256",
00048       "SHA-224",
00049       //"SHA-1",
00050       //"MD5",
00051       };
00052    }
00053 
00054 std::vector<std::string> Policy::allowed_macs() const
00055    {
00056    return {
00057       "AEAD",
00058       "SHA-384",
00059       "SHA-256",
00060       "SHA-1",
00061       //"MD5",
00062       };
00063    }
00064 
00065 std::vector<std::string> Policy::allowed_key_exchange_methods() const
00066    {
00067    return {
00068       "SRP_SHA",
00069       //"ECDHE_PSK",
00070       //"DHE_PSK",
00071       //"PSK",
00072       "ECDH",
00073       "DH",
00074       "RSA",
00075       };
00076    }
00077 
00078 std::vector<std::string> Policy::allowed_signature_methods() const
00079    {
00080    return {
00081       "ECDSA",
00082       "RSA",
00083       "DSA",
00084       //""
00085       };
00086    }
00087 
00088 std::vector<std::string> Policy::allowed_ecc_curves() const
00089    {
00090    return {
00091       "brainpool512r1",
00092       "secp521r1",
00093       "brainpool384r1",
00094       "secp384r1",
00095       "brainpool256r1",
00096       "secp256r1",
00097       //"secp256k1",
00098       //"secp224r1",
00099       //"secp224k1",
00100       //"secp192r1",
00101       //"secp192k1",
00102       //"secp160r2",
00103       //"secp160r1",
00104       //"secp160k1",
00105       };
00106    }
00107 
00108 /*
00109 * Choose an ECC curve to use
00110 */
00111 std::string Policy::choose_curve(const std::vector<std::string>& curve_names) const
00112    {
00113    const std::vector<std::string> our_curves = allowed_ecc_curves();
00114 
00115    for(size_t i = 0; i != our_curves.size(); ++i)
00116       if(value_exists(curve_names, our_curves[i]))
00117          return our_curves[i];
00118 
00119    return ""; // no shared curve
00120    }
00121 
00122 std::string Policy::dh_group() const
00123    {
00124    return "modp/ietf/2048";
00125    }
00126 
00127 size_t Policy::minimum_dh_group_size() const
00128    {
00129    return 1024;
00130    }
00131 
00132 /*
00133 * Return allowed compression algorithms
00134 */
00135 std::vector<byte> Policy::compression() const
00136    {
00137    return std::vector<byte>{ NO_COMPRESSION };
00138    }
00139 
00140 u32bit Policy::session_ticket_lifetime() const
00141    {
00142    return 86400; // ~1 day
00143    }
00144 
00145 bool Policy::send_fallback_scsv(Protocol_Version version) const
00146    {
00147    return version != latest_supported_version(version.is_datagram_protocol());
00148    }
00149 
00150 bool Policy::acceptable_protocol_version(Protocol_Version version) const
00151    {
00152    if(version.is_datagram_protocol())
00153       return (version >= Protocol_Version::DTLS_V12);
00154    else
00155       return (version >= Protocol_Version::TLS_V10);
00156    }
00157 
00158 Protocol_Version Policy::latest_supported_version(bool datagram) const
00159    {
00160    if(datagram)
00161       return Protocol_Version::latest_dtls_version();
00162    else
00163       return Protocol_Version::latest_tls_version();
00164    }
00165 
00166 bool Policy::acceptable_ciphersuite(const Ciphersuite&) const
00167    {
00168    return true;
00169    }
00170 
00171 bool Policy::negotiate_heartbeat_support() const { return false; }
00172 bool Policy::allow_server_initiated_renegotiation() const { return false; }
00173 bool Policy::allow_insecure_renegotiation() const { return false; }
00174 bool Policy::include_time_in_hello_random() const { return true; }
00175 bool Policy::hide_unknown_users() const { return false; }
00176 bool Policy::server_uses_own_ciphersuite_preferences() const { return true; }
00177 
00178 std::vector<u16bit> Policy::srtp_profiles() const
00179    {
00180    return std::vector<u16bit>();
00181    }
00182 
00183 namespace {
00184 
00185 class Ciphersuite_Preference_Ordering
00186    {
00187    public:
00188       Ciphersuite_Preference_Ordering(const std::vector<std::string>& ciphers,
00189                                       const std::vector<std::string>& macs,
00190                                       const std::vector<std::string>& kex,
00191                                       const std::vector<std::string>& sigs) :
00192          m_ciphers(ciphers), m_macs(macs), m_kex(kex), m_sigs(sigs) {}
00193 
00194       bool operator()(const Ciphersuite& a, const Ciphersuite& b) const
00195          {
00196          if(a.kex_algo() != b.kex_algo())
00197             {
00198             for(size_t i = 0; i != m_kex.size(); ++i)
00199                {
00200                if(a.kex_algo() == m_kex[i])
00201                   return true;
00202                if(b.kex_algo() == m_kex[i])
00203                   return false;
00204                }
00205             }
00206 
00207          if(a.cipher_algo() != b.cipher_algo())
00208             {
00209             for(size_t i = 0; i != m_ciphers.size(); ++i)
00210                {
00211                if(a.cipher_algo() == m_ciphers[i])
00212                   return true;
00213                if(b.cipher_algo() == m_ciphers[i])
00214                   return false;
00215                }
00216             }
00217 
00218          if(a.cipher_keylen() != b.cipher_keylen())
00219             {
00220             if(a.cipher_keylen() < b.cipher_keylen())
00221                return false;
00222             if(a.cipher_keylen() > b.cipher_keylen())
00223                return true;
00224             }
00225 
00226          if(a.sig_algo() != b.sig_algo())
00227             {
00228             for(size_t i = 0; i != m_sigs.size(); ++i)
00229                {
00230                if(a.sig_algo() == m_sigs[i])
00231                   return true;
00232                if(b.sig_algo() == m_sigs[i])
00233                   return false;
00234                }
00235             }
00236 
00237          if(a.mac_algo() != b.mac_algo())
00238             {
00239             for(size_t i = 0; i != m_macs.size(); ++i)
00240                {
00241                if(a.mac_algo() == m_macs[i])
00242                   return true;
00243                if(b.mac_algo() == m_macs[i])
00244                   return false;
00245                }
00246             }
00247 
00248          return false; // equal (?!?)
00249          }
00250    private:
00251       std::vector<std::string> m_ciphers, m_macs, m_kex, m_sigs;
00252    };
00253 
00254 }
00255 
00256 std::vector<u16bit> Policy::ciphersuite_list(Protocol_Version version,
00257                                              bool have_srp) const
00258    {
00259    const std::vector<std::string> ciphers = allowed_ciphers();
00260    const std::vector<std::string> macs = allowed_macs();
00261    const std::vector<std::string> kex = allowed_key_exchange_methods();
00262    const std::vector<std::string> sigs = allowed_signature_methods();
00263 
00264    Ciphersuite_Preference_Ordering order(ciphers, macs, kex, sigs);
00265 
00266    std::set<Ciphersuite, Ciphersuite_Preference_Ordering> ciphersuites(order);
00267 
00268    for(auto&& suite : Ciphersuite::all_known_ciphersuites())
00269       {
00270       if(!acceptable_ciphersuite(suite))
00271          continue;
00272 
00273       if(!have_srp && suite.kex_algo() == "SRP_SHA")
00274          continue;
00275 
00276       if(version.is_datagram_protocol() && suite.cipher_algo() == "RC4")
00277          continue;
00278 
00279       if(!version.supports_aead_modes() && suite.mac_algo() == "AEAD")
00280          continue;
00281 
00282       if(!value_exists(kex, suite.kex_algo()))
00283          continue; // unsupported key exchange
00284 
00285       if(!value_exists(ciphers, suite.cipher_algo()))
00286          continue; // unsupported cipher
00287 
00288       if(!value_exists(macs, suite.mac_algo()))
00289          continue; // unsupported MAC algo
00290 
00291       if(!value_exists(sigs, suite.sig_algo()))
00292          {
00293          // allow if it's an empty sig algo and we want to use PSK
00294          if(suite.sig_algo() != "" || !suite.psk_ciphersuite())
00295             continue;
00296          }
00297 
00298       // OK, allow it:
00299       ciphersuites.insert(suite);
00300       }
00301 
00302    if(ciphersuites.empty())
00303       throw std::logic_error("Policy does not allow any available cipher suite");
00304 
00305    std::vector<u16bit> ciphersuite_codes;
00306    for(auto i : ciphersuites)
00307       ciphersuite_codes.push_back(i.ciphersuite_code());
00308    return ciphersuite_codes;
00309    }
00310 
00311 namespace {
00312 
00313 void print_vec(std::ostream& o,
00314                const char* key,
00315                const std::vector<std::string>& v)
00316    {
00317    o << key << " = ";
00318    for(size_t i = 0; i != v.size(); ++i)
00319       {
00320       o << v[i];
00321       if(i != v.size() - 1)
00322          o << ' ';
00323       }
00324    o << '\n';
00325    }
00326 
00327 void print_bool(std::ostream& o,
00328                 const char* key, bool b)
00329    {
00330    o << key << " = " << (b ? "true" : "false") << '\n';
00331    }
00332 
00333 }
00334 
00335 void Policy::print(std::ostream& o) const
00336    {
00337    print_vec(o, "ciphers", allowed_ciphers());
00338    print_vec(o, "macs", allowed_macs());
00339    print_vec(o, "signature_hashes", allowed_signature_hashes());
00340    print_vec(o, "signature_methods", allowed_signature_methods());
00341    print_vec(o, "key_exchange_methods", allowed_key_exchange_methods());
00342    print_vec(o, "ecc_curves", allowed_ecc_curves());
00343 
00344    print_bool(o, "negotiate_heartbeat_support", negotiate_heartbeat_support());
00345    print_bool(o, "allow_insecure_renegotiation", allow_insecure_renegotiation());
00346    print_bool(o, "include_time_in_hello_random", include_time_in_hello_random());
00347    print_bool(o, "allow_server_initiated_renegotiation", allow_server_initiated_renegotiation());
00348    print_bool(o, "hide_unknown_users", hide_unknown_users());
00349    print_bool(o, "server_uses_own_ciphersuite_preferences", server_uses_own_ciphersuite_preferences());
00350    o << "session_ticket_lifetime = " << session_ticket_lifetime() << '\n';
00351    o << "dh_group = " << dh_group() << '\n';
00352    o << "minimum_dh_group_size = " << minimum_dh_group_size() << '\n';
00353    }
00354 
00355 std::vector<std::string> Strict_Policy::allowed_ciphers() const
00356    {
00357    return { "ChaCha20Poly1305", "AES-256/GCM", "AES-128/GCM" };
00358    }
00359 
00360 std::vector<std::string> Strict_Policy::allowed_signature_hashes() const
00361    {
00362    return { "SHA-512", "SHA-384"};
00363    }
00364 
00365 std::vector<std::string> Strict_Policy::allowed_macs() const
00366    {
00367    return { "AEAD" };
00368    }
00369 
00370 std::vector<std::string> Strict_Policy::allowed_key_exchange_methods() const
00371    {
00372    return { "ECDH" };
00373    }
00374 
00375 bool Strict_Policy::acceptable_protocol_version(Protocol_Version version) const
00376    {
00377    if(version.is_datagram_protocol())
00378       return (version >= Protocol_Version::DTLS_V12);
00379    else
00380       return (version >= Protocol_Version::TLS_V12);
00381    }
00382 
00383 }
00384 
00385 }