Botan
1.11.15
|
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 }