diff options
Diffstat (limited to 'src/lib/tls')
-rw-r--r-- | src/lib/tls/credentials_manager.cpp | 13 | ||||
-rw-r--r-- | src/lib/tls/msg_client_kex.cpp | 5 | ||||
-rw-r--r-- | src/lib/tls/msg_server_kex.cpp | 54 | ||||
-rw-r--r-- | src/lib/tls/sessions_sql/tls_session_manager_sql.cpp | 56 | ||||
-rw-r--r-- | src/lib/tls/sessions_sql/tls_session_manager_sql.h | 4 | ||||
-rw-r--r-- | src/lib/tls/tls_policy.cpp | 7 | ||||
-rw-r--r-- | src/lib/tls/tls_reader.h | 2 | ||||
-rw-r--r-- | src/lib/tls/tls_session.cpp | 19 | ||||
-rw-r--r-- | src/lib/tls/tls_session_manager.h | 11 | ||||
-rw-r--r-- | src/lib/tls/tls_session_manager_memory.cpp | 11 | ||||
-rw-r--r-- | src/lib/tls/tls_suite_info.cpp | 7 |
11 files changed, 89 insertions, 100 deletions
diff --git a/src/lib/tls/credentials_manager.cpp b/src/lib/tls/credentials_manager.cpp index 43ba7650a..3762dc149 100644 --- a/src/lib/tls/credentials_manager.cpp +++ b/src/lib/tls/credentials_manager.cpp @@ -129,11 +129,14 @@ void Credentials_Manager::verify_certificate_chain( Path_Validation_Restrictions restrictions; - auto result = x509_path_validate(cert_chain, - restrictions, - trusted_CAs, - purported_hostname, - choose_leaf_usage(type)); + Path_Validation_Result result = x509_path_validate(cert_chain, + restrictions, + trusted_CAs, + purported_hostname, + choose_leaf_usage(type)); + + if(!result.successful_validation()) + throw std::runtime_error("Certificate validation failure: " + result.result_string()); if(!cert_in_some_store(trusted_CAs, result.trust_root())) throw std::runtime_error("Certificate chain roots in unknown/untrusted CA"); diff --git a/src/lib/tls/msg_client_kex.cpp b/src/lib/tls/msg_client_kex.cpp index c5b9305c7..7ce9b9df2 100644 --- a/src/lib/tls/msg_client_kex.cpp +++ b/src/lib/tls/msg_client_kex.cpp @@ -106,8 +106,9 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, DL_Group group(p, g); - if(!group.verify_group(rng, true)) - throw Internal_Error("DH group failed validation, possible attack"); + if(!group.verify_group(rng, false)) + throw TLS_Exception(Alert::INSUFFICIENT_SECURITY, + "DH group validation failed"); DH_PublicKey counterparty_key(group, Y); diff --git a/src/lib/tls/msg_server_kex.cpp b/src/lib/tls/msg_server_kex.cpp index 3fcdb5ab2..0c3b5c704 100644 --- a/src/lib/tls/msg_server_kex.cpp +++ b/src/lib/tls/msg_server_kex.cpp @@ -1,6 +1,6 @@ /* * Server Key Exchange Message -* (C) 2004-2010,2012 Jack Lloyd +* (C) 2004-2010,2012,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -145,21 +145,17 @@ Server_Key_Exchange::Server_Key_Exchange(const std::vector<byte>& buf, Protocol_Version version) : m_kex_key(nullptr), m_srp_params(nullptr) { - if(buf.size() < 6) - throw Decoding_Error("Server_Key_Exchange: Packet corrupted"); - TLS_Data_Reader reader("ServerKeyExchange", buf); /* - * We really are just serializing things back to what they were - * before, but unfortunately to know where the signature is we need - * to be able to parse the whole thing anyway. + * Here we are deserializing enough to find out what offset the + * signature is at. All processing is done when the Client Key Exchange + * is prepared. */ if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") { - const std::string identity_hint = reader.get_string(2, 0, 65535); - append_tls_length_value(m_params, identity_hint, 2); + reader.get_string(2, 0, 65535); // identity hint } if(kex_algo == "DH" || kex_algo == "DHE_PSK") @@ -168,49 +164,29 @@ Server_Key_Exchange::Server_Key_Exchange(const std::vector<byte>& buf, for(size_t i = 0; i != 3; ++i) { - BigInt v = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); - append_tls_length_value(m_params, BigInt::encode(v), 2); + reader.get_range<byte>(2, 1, 65535); } } else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") { - const byte curve_type = reader.get_byte(); - - if(curve_type != 3) - throw Decoding_Error("Server_Key_Exchange: Server sent non-named ECC curve"); - - const u16bit curve_id = reader.get_u16bit(); - - const std::string name = Supported_Elliptic_Curves::curve_id_to_name(curve_id); - - std::vector<byte> ecdh_key = reader.get_range<byte>(1, 1, 255); - - if(name == "") - throw Decoding_Error("Server_Key_Exchange: Server sent unknown named curve " + - std::to_string(curve_id)); - - m_params.push_back(curve_type); - m_params.push_back(get_byte(0, curve_id)); - m_params.push_back(get_byte(1, curve_id)); - append_tls_length_value(m_params, ecdh_key, 1); + reader.get_byte(); // curve type + reader.get_u16bit(); // curve id + reader.get_range<byte>(1, 1, 255); // public key } else if(kex_algo == "SRP_SHA") { // 2 bigints (N,g) then salt, then server B - const BigInt N = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); - const BigInt g = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); - std::vector<byte> salt = reader.get_range<byte>(1, 1, 255); - const BigInt B = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); - - append_tls_length_value(m_params, BigInt::encode(N), 2); - append_tls_length_value(m_params, BigInt::encode(g), 2); - append_tls_length_value(m_params, salt, 1); - append_tls_length_value(m_params, BigInt::encode(B), 2); + reader.get_range<byte>(2, 1, 65535); + reader.get_range<byte>(2, 1, 65535); + reader.get_range<byte>(1, 1, 255); + reader.get_range<byte>(2, 1, 65535); } else if(kex_algo != "PSK") throw Decoding_Error("Server_Key_Exchange: Unsupported kex type " + kex_algo); + m_params.assign(buf.data(), buf.data() + reader.read_so_far()); + if(sig_algo != "") { if(version.supports_negotiable_signature_algorithms()) diff --git a/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp b/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp index ed207972e..9f025374e 100644 --- a/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp +++ b/src/lib/tls/sessions_sql/tls_session_manager_sql.cpp @@ -16,27 +16,6 @@ namespace Botan { namespace TLS { -namespace { - -SymmetricKey derive_key(const std::string& passphrase, - const byte salt[], - size_t salt_len, - size_t iterations, - size_t& check_val) - { - std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(SHA-512)")); - - secure_vector<byte> x = pbkdf->derive_key(32 + 2, - passphrase, - salt, salt_len, - iterations).bits_of(); - - check_val = make_u16bit(x[0], x[1]); - return SymmetricKey(&x[2], x.size() - 2); - } - -} - Session_Manager_SQL::Session_Manager_SQL(std::shared_ptr<SQL_Database> db, const std::string& passphrase, RandomNumberGenerator& rng, @@ -67,6 +46,8 @@ Session_Manager_SQL::Session_Manager_SQL(std::shared_ptr<SQL_Database> db, const size_t salts = m_db->row_count("tls_sessions_metadata"); + std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(SHA-512)")); + if(salts == 1) { // existing db @@ -78,12 +59,13 @@ Session_Manager_SQL::Session_Manager_SQL(std::shared_ptr<SQL_Database> db, const size_t iterations = stmt->get_size_t(1); const size_t check_val_db = stmt->get_size_t(2); - size_t check_val_created; - m_session_key = derive_key(passphrase, - salt.first, - salt.second, - iterations, - check_val_created); + secure_vector<byte> x = pbkdf->pbkdf_iterations(32 + 2, + passphrase, + salt.first, salt.second, + iterations); + + const size_t check_val_created = make_u16bit(x[0], x[1]); + m_session_key.assign(x.begin() + 2, x.end()); if(check_val_created != check_val_db) throw std::runtime_error("Session database password not valid"); @@ -98,11 +80,17 @@ Session_Manager_SQL::Session_Manager_SQL(std::shared_ptr<SQL_Database> db, // new database case std::vector<byte> salt = unlock(rng.random_vec(16)); - const size_t iterations = 256 * 1024; - size_t check_val = 0; + size_t iterations = 0; - m_session_key = derive_key(passphrase, salt.data(), salt.size(), - iterations, check_val); + secure_vector<byte> x = pbkdf->pbkdf_timed(32 + 2, + passphrase, + salt.data(), salt.size(), + std::chrono::milliseconds(100), + iterations); + + printf("pbkdf iter %d\n", iterations); + size_t check_val = make_u16bit(x[0], x[1]); + m_session_key.assign(x.begin() + 2, x.end()); auto stmt = m_db->new_statement("insert into tls_sessions_metadata values(?1, ?2, ?3)"); @@ -174,6 +162,12 @@ void Session_Manager_SQL::remove_entry(const std::vector<byte>& session_id) stmt->spin(); } +size_t Session_Manager_SQL::remove_all() + { + auto stmt = m_db->new_statement("delete from tls_sessions"); + return stmt->spin(); + } + void Session_Manager_SQL::save(const Session& session) { auto stmt = m_db->new_statement("insert or replace into tls_sessions" diff --git a/src/lib/tls/sessions_sql/tls_session_manager_sql.h b/src/lib/tls/sessions_sql/tls_session_manager_sql.h index 081c42e74..24e2be7c3 100644 --- a/src/lib/tls/sessions_sql/tls_session_manager_sql.h +++ b/src/lib/tls/sessions_sql/tls_session_manager_sql.h @@ -56,6 +56,8 @@ class BOTAN_DLL Session_Manager_SQL : public Session_Manager void remove_entry(const std::vector<byte>& session_id) override; + size_t remove_all() override; + void save(const Session& session_data) override; std::chrono::seconds session_lifetime() const override @@ -65,7 +67,7 @@ class BOTAN_DLL Session_Manager_SQL : public Session_Manager void prune_session_cache(); std::shared_ptr<SQL_Database> m_db; - SymmetricKey m_session_key; + secure_vector<byte> m_session_key; RandomNumberGenerator& m_rng; size_t m_max_sessions; std::chrono::seconds m_session_lifetime; diff --git a/src/lib/tls/tls_policy.cpp b/src/lib/tls/tls_policy.cpp index d8dd2c828..7d1af71ef 100644 --- a/src/lib/tls/tls_policy.cpp +++ b/src/lib/tls/tls_policy.cpp @@ -1,6 +1,6 @@ /* * Policies for TLS -* (C) 2004-2010,2012 Jack Lloyd +* (C) 2004-2010,2012,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -44,7 +44,7 @@ std::vector<std::string> Policy::allowed_signature_hashes() const "SHA-512", "SHA-384", "SHA-256", - "SHA-224", + //"SHA-224", //"SHA-1", //"MD5", }; @@ -282,9 +282,6 @@ std::vector<u16bit> Policy::ciphersuite_list(Protocol_Version version, if(!have_srp && suite.kex_algo() == "SRP_SHA") continue; - if(version.is_datagram_protocol() && suite.cipher_algo() == "RC4") - continue; - if(!version.supports_aead_modes() && suite.mac_algo() == "AEAD") continue; diff --git a/src/lib/tls/tls_reader.h b/src/lib/tls/tls_reader.h index c2aef3163..63a59625f 100644 --- a/src/lib/tls/tls_reader.h +++ b/src/lib/tls/tls_reader.h @@ -34,6 +34,8 @@ class TLS_Data_Reader throw decode_error("Extra bytes at end of message"); } + size_t read_so_far() const { return m_offset; } + size_t remaining_bytes() const { return m_buf.size() - m_offset; } bool has_remaining() const { return (remaining_bytes() > 0); } diff --git a/src/lib/tls/tls_session.cpp b/src/lib/tls/tls_session.cpp index 8cb1a2aa7..7089a70f0 100644 --- a/src/lib/tls/tls_session.cpp +++ b/src/lib/tls/tls_session.cpp @@ -11,8 +11,7 @@ #include <botan/asn1_str.h> #include <botan/pem.h> #include <botan/aead.h> -#include <botan/sha2_32.h> -#include <botan/hmac.h> +#include <botan/mac.h> namespace Botan { @@ -162,10 +161,10 @@ Session::encrypt(const SymmetricKey& key, RandomNumberGenerator& rng) const const secure_vector<byte> bits = this->DER_encode(); // Support any length key for input - HMAC hmac(new SHA_256); - hmac.set_key(key); - hmac.update(nonce); - aead->set_key(hmac.final()); + std::unique_ptr<MessageAuthenticationCode> hmac(MessageAuthenticationCode::create("HMAC(SHA-256)")); + hmac->set_key(key); + hmac->update(nonce); + aead->set_key(hmac->final()); secure_vector<byte> buf = nonce; buf += bits; @@ -185,10 +184,10 @@ Session Session::decrypt(const byte in[], size_t in_len, const SymmetricKey& key throw Decoding_Error("Encrypted session too short to be valid"); // Support any length key for input - HMAC hmac(new SHA_256); - hmac.set_key(key); - hmac.update(in, nonce_len); // nonce bytes - aead->set_key(hmac.final()); + std::unique_ptr<MessageAuthenticationCode> hmac(MessageAuthenticationCode::create("HMAC(SHA-256)")); + hmac->set_key(key); + hmac->update(in, nonce_len); // nonce bytes + aead->set_key(hmac->final()); aead->start(in, nonce_len); secure_vector<byte> buf(in + nonce_len, in + in_len); diff --git a/src/lib/tls/tls_session_manager.h b/src/lib/tls/tls_session_manager.h index c7aa1960b..5ab151c26 100644 --- a/src/lib/tls/tls_session_manager.h +++ b/src/lib/tls/tls_session_manager.h @@ -55,6 +55,11 @@ class BOTAN_DLL Session_Manager virtual void remove_entry(const std::vector<byte>& session_id) = 0; /** + * Remove all sessions from the cache, return number of sessions deleted + */ + virtual size_t remove_all() = 0; + + /** * Save a session on a best effort basis; the manager may not in * fact be able to save the session for whatever reason; this is * not an error. Caller cannot assume that calling save followed @@ -89,6 +94,8 @@ class BOTAN_DLL Session_Manager_Noop : public Session_Manager void remove_entry(const std::vector<byte>&) override {} + size_t remove_all() override { return 0; } + void save(const Session&) override {} std::chrono::seconds session_lifetime() const override @@ -120,6 +127,8 @@ class BOTAN_DLL Session_Manager_In_Memory : public Session_Manager void remove_entry(const std::vector<byte>& session_id) override; + size_t remove_all(); + void save(const Session& session_data) override; std::chrono::seconds session_lifetime() const override @@ -136,7 +145,7 @@ class BOTAN_DLL Session_Manager_In_Memory : public Session_Manager std::chrono::seconds m_session_lifetime; RandomNumberGenerator& m_rng; - SymmetricKey m_session_key; + secure_vector<byte> m_session_key; std::map<std::string, std::vector<byte>> m_sessions; // hex(session_id) -> session std::map<Server_Information, std::string> m_info_sessions; diff --git a/src/lib/tls/tls_session_manager_memory.cpp b/src/lib/tls/tls_session_manager_memory.cpp index 2c836290b..37019c943 100644 --- a/src/lib/tls/tls_session_manager_memory.cpp +++ b/src/lib/tls/tls_session_manager_memory.cpp @@ -20,7 +20,7 @@ Session_Manager_In_Memory::Session_Manager_In_Memory( m_max_sessions(max_sessions), m_session_lifetime(session_lifetime), m_rng(rng), - m_session_key(m_rng, 32) + m_session_key(m_rng.random_vec(32)) {} bool Session_Manager_In_Memory::load_from_session_str( @@ -95,6 +95,15 @@ void Session_Manager_In_Memory::remove_entry( m_sessions.erase(i); } +size_t Session_Manager_In_Memory::remove_all() + { + const size_t removed = m_sessions.size(); + m_info_sessions.clear(); + m_sessions.clear(); + m_session_key = m_rng.random_vec(32); + return removed; + } + void Session_Manager_In_Memory::save(const Session& session) { std::lock_guard<std::mutex> lock(m_mutex); diff --git a/src/lib/tls/tls_suite_info.cpp b/src/lib/tls/tls_suite_info.cpp index cb5c1d4c5..5aff035b9 100644 --- a/src/lib/tls/tls_suite_info.cpp +++ b/src/lib/tls/tls_suite_info.cpp @@ -2,8 +2,8 @@ * TLS cipher suite information * * This file was automatically generated from the IANA assignments -* (tls-parameters.txt hash 4bc98b6f75ad5b63952b5f457fa7adbfef60f095) -* by ./src/scripts/tls_suite_info.py on 2015-05-11 +* (tls-parameters.txt hash 6a934405ed41aa4d6113dad17f815867741430ac) +* by ./src/scripts/tls_suite_info.py on 2015-11-13 * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -57,9 +57,6 @@ Ciphersuite Ciphersuite::by_id(u16bit suite) case 0xC081: // DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 return Ciphersuite(0xC081, "DSA", "DH", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); - case 0x0066: // DHE_DSS_WITH_RC4_128_SHA - return Ciphersuite(0x0066, "DSA", "DH", "RC4", 16, 0, 0, "SHA-1", 20); - case 0x0099: // DHE_DSS_WITH_SEED_CBC_SHA return Ciphersuite(0x0099, "DSA", "DH", "SEED", 16, 16, 0, "SHA-1", 20); |