diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/tls/s_hello.cpp | 81 | ||||
-rw-r--r-- | src/tls/sessions_sqlite/tls_sqlite_sess_mgr.cpp | 2 | ||||
-rw-r--r-- | src/tls/sessions_sqlite/tls_sqlite_sess_mgr.h | 7 | ||||
-rw-r--r-- | src/tls/tls_ciphersuite.cpp | 12 | ||||
-rw-r--r-- | src/tls/tls_ciphersuite.h | 3 | ||||
-rw-r--r-- | src/tls/tls_client.cpp | 4 | ||||
-rw-r--r-- | src/tls/tls_extensions.cpp | 13 | ||||
-rw-r--r-- | src/tls/tls_messages.h | 33 | ||||
-rw-r--r-- | src/tls/tls_policy.cpp | 63 | ||||
-rw-r--r-- | src/tls/tls_policy.h | 7 | ||||
-rw-r--r-- | src/tls/tls_server.cpp | 82 | ||||
-rw-r--r-- | src/tls/tls_session.cpp | 5 | ||||
-rw-r--r-- | src/tls/tls_session.h | 5 | ||||
-rw-r--r-- | src/tls/tls_session_manager.cpp | 34 | ||||
-rw-r--r-- | src/tls/tls_session_manager.h | 23 |
15 files changed, 196 insertions, 178 deletions
diff --git a/src/tls/s_hello.cpp b/src/tls/s_hello.cpp index 7da9fdc57..bb93108d9 100644 --- a/src/tls/s_hello.cpp +++ b/src/tls/s_hello.cpp @@ -21,47 +21,6 @@ namespace TLS { */ Server_Hello::Server_Hello(Record_Writer& writer, Handshake_Hash& hash, - Protocol_Version version, - const Client_Hello& c_hello, - const std::vector<std::string>& available_cert_types, - const Policy& policy, - bool have_session_ticket_key, - bool client_has_secure_renegotiation, - const MemoryRegion<byte>& reneg_info, - bool client_has_npn, - const std::vector<std::string>& next_protocols, - RandomNumberGenerator& rng) : - s_version(version), - m_session_id(rng.random_vec(32)), - s_random(make_hello_random(rng)), - m_fragment_size(c_hello.fragment_size()), - m_secure_renegotiation(client_has_secure_renegotiation), - m_renegotiation_info(reneg_info), - m_next_protocol(client_has_npn), - m_next_protocols(next_protocols), - m_supports_session_ticket(have_session_ticket_key && - c_hello.supports_session_ticket()) - { - suite = policy.choose_suite( - c_hello.ciphersuites(), - available_cert_types, - policy.choose_curve(c_hello.supported_ecc_curves()) != "", - false); - - if(suite == 0) - throw TLS_Exception(Alert::HANDSHAKE_FAILURE, - "Can't agree on a ciphersuite with client"); - - comp_method = policy.choose_compression(c_hello.compression_methods()); - - hash.update(writer.send(*this)); - } - -/* -* Create a new Server Hello message -*/ -Server_Hello::Server_Hello(Record_Writer& writer, - Handshake_Hash& hash, const MemoryRegion<byte>& session_id, Protocol_Version ver, u16bit ciphersuite, @@ -69,21 +28,21 @@ Server_Hello::Server_Hello(Record_Writer& writer, size_t max_fragment_size, bool client_has_secure_renegotiation, const MemoryRegion<byte>& reneg_info, - bool client_supports_session_tickets, + bool offer_session_ticket, bool client_has_npn, const std::vector<std::string>& next_protocols, RandomNumberGenerator& rng) : - s_version(ver), + m_version(ver), m_session_id(session_id), - s_random(make_hello_random(rng)), - suite(ciphersuite), - comp_method(compression), + m_random(make_hello_random(rng)), + m_ciphersuite(ciphersuite), + m_comp_method(compression), m_fragment_size(max_fragment_size), m_secure_renegotiation(client_has_secure_renegotiation), m_renegotiation_info(reneg_info), m_next_protocol(client_has_npn), m_next_protocols(next_protocols), - m_supports_session_ticket(client_supports_session_tickets) + m_supports_session_ticket(offer_session_ticket) { hash.update(writer.send(*this)); } @@ -105,24 +64,24 @@ Server_Hello::Server_Hello(const MemoryRegion<byte>& buf) const byte major_version = reader.get_byte(); const byte minor_version = reader.get_byte(); - s_version = Protocol_Version(major_version, minor_version); + m_version = Protocol_Version(major_version, minor_version); - if(s_version != Protocol_Version::SSL_V3 && - s_version != Protocol_Version::TLS_V10 && - s_version != Protocol_Version::TLS_V11 && - s_version != Protocol_Version::TLS_V12) + if(m_version != Protocol_Version::SSL_V3 && + m_version != Protocol_Version::TLS_V10 && + m_version != Protocol_Version::TLS_V11 && + m_version != Protocol_Version::TLS_V12) { throw TLS_Exception(Alert::PROTOCOL_VERSION, "Server_Hello: Unsupported server version"); } - s_random = reader.get_fixed<byte>(32); + m_random = reader.get_fixed<byte>(32); m_session_id = reader.get_range<byte>(1, 0, 32); - suite = reader.get_u16bit(); + m_ciphersuite = reader.get_u16bit(); - comp_method = reader.get_byte(); + m_comp_method = reader.get_byte(); Extensions extensions(reader); @@ -154,16 +113,16 @@ MemoryVector<byte> Server_Hello::serialize() const { MemoryVector<byte> buf; - buf.push_back(s_version.major_version()); - buf.push_back(s_version.minor_version()); - buf += s_random; + buf.push_back(m_version.major_version()); + buf.push_back(m_version.minor_version()); + buf += m_random; append_tls_length_value(buf, m_session_id, 1); - buf.push_back(get_byte(0, suite)); - buf.push_back(get_byte(1, suite)); + buf.push_back(get_byte(0, m_ciphersuite)); + buf.push_back(get_byte(1, m_ciphersuite)); - buf.push_back(comp_method); + buf.push_back(m_comp_method); Extensions extensions; diff --git a/src/tls/sessions_sqlite/tls_sqlite_sess_mgr.cpp b/src/tls/sessions_sqlite/tls_sqlite_sess_mgr.cpp index 4d78a5365..cb831aadf 100644 --- a/src/tls/sessions_sqlite/tls_sqlite_sess_mgr.cpp +++ b/src/tls/sessions_sqlite/tls_sqlite_sess_mgr.cpp @@ -145,7 +145,7 @@ Session_Manager_SQLite::Session_Manager_SQLite(const std::string& passphrase, RandomNumberGenerator& rng, const std::string& db_filename, size_t max_sessions, - size_t session_lifetime) : + u32bit session_lifetime) : m_rng(rng), m_max_sessions(max_sessions), m_session_lifetime(session_lifetime) diff --git a/src/tls/sessions_sqlite/tls_sqlite_sess_mgr.h b/src/tls/sessions_sqlite/tls_sqlite_sess_mgr.h index 424db24e5..7ac2caeb2 100644 --- a/src/tls/sessions_sqlite/tls_sqlite_sess_mgr.h +++ b/src/tls/sessions_sqlite/tls_sqlite_sess_mgr.h @@ -36,7 +36,7 @@ class BOTAN_DLL Session_Manager_SQLite : public Session_Manager RandomNumberGenerator& rng, const std::string& db_filename, size_t max_sessions = 1000, - size_t session_lifetime = 7200); + u32bit session_lifetime = 7200); ~Session_Manager_SQLite(); @@ -49,6 +49,8 @@ class BOTAN_DLL Session_Manager_SQLite : public Session_Manager void remove_entry(const MemoryRegion<byte>& session_id); void save(const Session& session_data); + + u32bit session_lifetime() const { return m_session_lifetime; } private: Session_Manager_SQLite(const Session_Manager_SQLite&); Session_Manager_SQLite& operator=(const Session_Manager_SQLite&); @@ -57,7 +59,8 @@ class BOTAN_DLL Session_Manager_SQLite : public Session_Manager SymmetricKey m_session_key; RandomNumberGenerator& m_rng; - size_t m_max_sessions, m_session_lifetime; + size_t m_max_sessions; + u32bit m_session_lifetime; class sqlite3* m_db; }; diff --git a/src/tls/tls_ciphersuite.cpp b/src/tls/tls_ciphersuite.cpp index d3d8f061b..afe0e68ee 100644 --- a/src/tls/tls_ciphersuite.cpp +++ b/src/tls/tls_ciphersuite.cpp @@ -30,6 +30,18 @@ Ciphersuite Ciphersuite::by_name(const std::string& name) return Ciphersuite(); // some unknown ciphersuite } +bool Ciphersuite::psk_ciphersuite() const + { + return (kex_algo() == "PSK" || + kex_algo() == "DHE_PSK" || + kex_algo() == "ECDHE_PSK"); + } + +bool Ciphersuite::ecc_ciphersuite() const + { + return (kex_algo() == "ECDH" || sig_algo() == "ECDSA"); + } + std::string Ciphersuite::to_string() const { if(m_cipher_keylen == 0) diff --git a/src/tls/tls_ciphersuite.h b/src/tls/tls_ciphersuite.h index 6081fc9eb..dcb4b6a6f 100644 --- a/src/tls/tls_ciphersuite.h +++ b/src/tls/tls_ciphersuite.h @@ -33,6 +33,9 @@ class BOTAN_DLL Ciphersuite */ std::string to_string() const; + bool psk_ciphersuite() const; + bool ecc_ciphersuite() const; + std::string kex_algo() const { return m_kex_algo; } std::string sig_algo() const { return m_sig_algo; } diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp index ba9ec8082..2ec7eec2e 100644 --- a/src/tls/tls_client.cpp +++ b/src/tls/tls_client.cpp @@ -241,8 +241,8 @@ void Client::process_handshake_msg(Handshake_Type type, ever sent. The server may or may not send a server kex, depending on if it has an identity hint for us. - DHE_PSK always sends a server key exchange for the DH - exchange portion. + (EC)DHE_PSK always sends a server key exchange for the + DH exchange portion. */ state->set_expected_next(SERVER_KEX); diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp index 1ca4e3eb4..59ab64374 100644 --- a/src/tls/tls_extensions.cpp +++ b/src/tls/tls_extensions.cpp @@ -468,11 +468,16 @@ MemoryVector<byte> Signature_Algorithms::serialize() const for(size_t i = 0; i != m_supported_algos.size(); ++i) { - if(m_supported_algos[i].second == "") - continue; + try + { + const byte hash_code = hash_algo_code(m_supported_algos[i].first); + const byte sig_code = sig_algo_code(m_supported_algos[i].second); - buf.push_back(hash_algo_code(m_supported_algos[i].first)); - buf.push_back(sig_algo_code(m_supported_algos[i].second)); + buf.push_back(hash_code); + buf.push_back(sig_code); + } + catch(...) + {} } buf[0] = get_byte<u16bit>(0, buf.size()-2); diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h index 2f8af5fd2..920a1c7a7 100644 --- a/src/tls/tls_messages.h +++ b/src/tls/tls_messages.h @@ -163,10 +163,10 @@ class Server_Hello : public Handshake_Message { public: Handshake_Type type() const { return SERVER_HELLO; } - Protocol_Version version() { return s_version; } + Protocol_Version version() { return m_version; } const MemoryVector<byte>& session_id() const { return m_session_id; } - u16bit ciphersuite() const { return suite; } - byte compression_method() const { return comp_method; } + u16bit ciphersuite() const { return m_ciphersuite; } + byte compression_method() const { return m_comp_method; } std::vector<byte> session_id_vector() const { @@ -189,20 +189,7 @@ class Server_Hello : public Handshake_Message const MemoryVector<byte>& renegotiation_info() { return m_renegotiation_info; } - const MemoryVector<byte>& random() const { return s_random; } - - Server_Hello(Record_Writer& writer, - Handshake_Hash& hash, - Protocol_Version version, - const Client_Hello& other, - const std::vector<std::string>& available_cert_types, - const Policy& policies, - bool have_session_ticket_key, - bool client_has_secure_renegotiation, - const MemoryRegion<byte>& reneg_info, - bool client_has_npn, - const std::vector<std::string>& next_protocols, - RandomNumberGenerator& rng); + const MemoryVector<byte>& random() const { return m_random; } Server_Hello(Record_Writer& writer, Handshake_Hash& hash, @@ -213,7 +200,7 @@ class Server_Hello : public Handshake_Message size_t max_fragment_size, bool client_has_secure_renegotiation, const MemoryRegion<byte>& reneg_info, - bool client_supports_session_tickets, + bool offer_session_ticket, bool client_has_npn, const std::vector<std::string>& next_protocols, RandomNumberGenerator& rng); @@ -222,10 +209,10 @@ class Server_Hello : public Handshake_Message private: MemoryVector<byte> serialize() const; - Protocol_Version s_version; - MemoryVector<byte> m_session_id, s_random; - u16bit suite; - byte comp_method; + Protocol_Version m_version; + MemoryVector<byte> m_session_id, m_random; + u16bit m_ciphersuite; + byte m_comp_method; size_t m_fragment_size; bool m_secure_renegotiation; @@ -479,7 +466,7 @@ class New_Session_Ticket : public Handshake_Message New_Session_Ticket(Record_Writer& writer, Handshake_Hash& hash, const MemoryRegion<byte>& ticket, - u32bit lifetime = 0); + u32bit lifetime); New_Session_Ticket(Record_Writer& writer, Handshake_Hash& hash); diff --git a/src/tls/tls_policy.cpp b/src/tls/tls_policy.cpp index a2c0d01f8..3db517e56 100644 --- a/src/tls/tls_policy.cpp +++ b/src/tls/tls_policy.cpp @@ -51,9 +51,10 @@ std::vector<std::string> Policy::allowed_key_exchange_methods() const //allowed.push_back("ECDHE_PSK"); //allowed.push_back("DHE_PSK"); //allowed.push_back("PSK"); + allowed.push_back("ECDH"); allowed.push_back("DH"); - allowed.push_back("RSA"); // RSA via server cert + allowed.push_back("RSA"); return allowed; } @@ -87,6 +88,11 @@ std::vector<std::string> Policy::allowed_ecc_curves() const return curves; } +u32bit Policy::session_ticket_lifetime() const + { + return 86400; // 1 day + } + Protocol_Version Policy::min_version() const { return Protocol_Version::SSL_V3; @@ -199,13 +205,24 @@ std::vector<u16bit> Policy::ciphersuite_list(bool have_srp) const if(!suite.valid()) continue; // not a ciphersuite we know, skip - if(value_exists(ciphers, suite.cipher_algo()) && - value_exists(hashes, suite.mac_algo()) && - value_exists(kex, suite.kex_algo()) && - value_exists(sigs, suite.sig_algo())) + if(!value_exists(kex, suite.kex_algo())) + continue; // unsupported key exchange + + if(!value_exists(ciphers, suite.cipher_algo())) + continue; // unsupported cipher + + if(!value_exists(hashes, suite.mac_algo())) + continue; // unsupported MAC algo + + if(!value_exists(sigs, suite.sig_algo())) { - ciphersuites[suite] = i; + // allow if it's an empty sig algo and we want to use PSK + if(suite.sig_algo() != "" || !suite.psk_ciphersuite()) + continue; } + + // OK, allow it: + ciphersuites[suite] = i; } std::vector<u16bit> ciphersuite_codes; @@ -244,40 +261,6 @@ std::string Policy::choose_curve(const std::vector<std::string>& curve_names) co } /* -* Choose which ciphersuite to use -*/ -u16bit Policy::choose_suite(const std::vector<u16bit>& client_suites, - const std::vector<std::string>& available_cert_types, - bool have_shared_ecc_curve, - bool have_srp) const - { - std::vector<u16bit> ciphersuites = ciphersuite_list(have_srp); - - for(size_t i = 0; i != ciphersuites.size(); ++i) - { - const u16bit suite_id = ciphersuites[i]; - Ciphersuite suite = Ciphersuite::by_id(suite_id); - - if(!have_shared_ecc_curve) - { - if(suite.kex_algo() == "ECDH" || suite.sig_algo() == "ECDSA") - continue; - } - - if(suite.sig_algo() != "" && - !value_exists(available_cert_types, suite.sig_algo())) - { - continue; - } - - if(value_exists(client_suites, suite_id)) - return suite_id; - } - - return 0; // no shared cipersuite - } - -/* * Choose which compression algorithm to use */ byte Policy::choose_compression(const std::vector<byte>& c_comp) const diff --git a/src/tls/tls_policy.h b/src/tls/tls_policy.h index f53b9bab6..b12f07125 100644 --- a/src/tls/tls_policy.h +++ b/src/tls/tls_policy.h @@ -95,6 +95,13 @@ class BOTAN_DLL Policy virtual bool hide_unknown_users() const { return false; } /** + * Return the allowed lifetime of a session ticket. If 0, session + * tickets do not expire until the session ticket key rolls over. + * Old session tickets cannot be used to resume as session. + */ + virtual u32bit session_ticket_lifetime() const; + + /** * @return the minimum version that we are willing to negotiate */ virtual Protocol_Version min_version() const; diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp index 1f69d153e..43556e1bc 100644 --- a/src/tls/tls_server.cpp +++ b/src/tls/tls_server.cpp @@ -21,7 +21,8 @@ namespace { bool check_for_resume(Session& session_info, Session_Manager& session_manager, Credentials_Manager& credentials, - Client_Hello* client_hello) + Client_Hello* client_hello, + u32bit session_ticket_lifetime) { const MemoryVector<byte>& client_session_id = client_hello->session_id(); const MemoryVector<byte>& session_ticket = client_hello->session_ticket(); @@ -43,6 +44,10 @@ bool check_for_resume(Session& session_info, session_info = Session::decrypt( session_ticket, credentials.psk("tls-server", "session-ticket", "")); + + if(session_ticket_lifetime && + session_info.session_age() > session_ticket_lifetime) + return false; // ticket has expired } catch(...) { @@ -81,6 +86,43 @@ bool check_for_resume(Session& session_info, return true; } +/* +* Choose which ciphersuite to use +*/ +u16bit choose_ciphersuite( + const Policy& policy, + const std::map<std::string, std::vector<X509_Certificate> >& cert_chains, + const Client_Hello* client_hello) + { + const std::vector<u16bit> client_suites = client_hello->ciphersuites(); + const std::vector<u16bit> server_suites = policy.ciphersuite_list(false); + + const bool have_shared_ecc_curve = + (policy.choose_curve(client_hello->supported_ecc_curves()) != ""); + + // Ordering by our preferences rather than by clients + for(size_t i = 0; i != server_suites.size(); ++i) + { + const u16bit suite_id = server_suites[i]; + + if(!value_exists(client_suites, suite_id)) + continue; + + Ciphersuite suite = Ciphersuite::by_id(suite_id); + + if(!have_shared_ecc_curve && suite.ecc_ciphersuite()) + continue; + + if(cert_chains.count(suite.sig_algo()) == 0) + continue; + + return suite_id; + } + + throw TLS_Exception(Alert::HANDSHAKE_FAILURE, + "Can't agree on a ciphersuite with client"); + } + std::map<std::string, std::vector<X509_Certificate> > get_server_certs(const std::string& hostname, Credentials_Manager& creds) @@ -215,7 +257,8 @@ void Server::process_handshake_msg(Handshake_Type type, const bool resuming = check_for_resume(session_info, session_manager, creds, - state->client_hello); + state->client_hello, + policy.session_ticket_lifetime()); bool have_session_ticket_key = false; @@ -240,7 +283,9 @@ void Server::process_handshake_msg(Handshake_Type type, session_info.fragment_size(), secure_renegotiation.supported(), secure_renegotiation.for_server_hello(), - state->client_hello->supports_session_ticket() && have_session_ticket_key, + (state->client_hello->supports_session_ticket() && + state->client_hello->session_ticket().empty() && + have_session_ticket_key), state->client_hello->next_protocol_notification(), m_possible_protocols, rng); @@ -257,13 +302,12 @@ void Server::process_handshake_msg(Handshake_Type type, if(!handshake_fn(session_info)) { - if(state->server_hello->supports_session_ticket()) + session_manager.remove_entry(session_info.session_id()); + + if(state->server_hello->supports_session_ticket()) // send an empty ticket state->new_session_ticket = new New_Session_Ticket(writer, state->hash); - else - session_manager.remove_entry(session_info.session_id()); } - // FIXME: should only send a new ticket if we need too (eg old session) if(state->server_hello->supports_session_ticket() && !state->new_session_ticket) { try @@ -272,7 +316,8 @@ void Server::process_handshake_msg(Handshake_Type type, state->new_session_ticket = new New_Session_Ticket(writer, state->hash, - session_info.encrypt(ticket_key, rng)); + session_info.encrypt(ticket_key, rng), + policy.session_ticket_lifetime()); } catch(...) {} @@ -301,25 +346,17 @@ void Server::process_handshake_msg(Handshake_Type type, cert_chains = get_server_certs("", creds); } - std::vector<std::string> available_cert_types; - - for(std::map<std::string, std::vector<X509_Certificate> >::const_iterator i = cert_chains.begin(); - i != cert_chains.end(); ++i) - { - if(!i->second.empty()) - available_cert_types.push_back(i->first); - } - state->server_hello = new Server_Hello( writer, state->hash, + rng.random_vec(32), // new session ID state->version(), - *(state->client_hello), - available_cert_types, - policy, - have_session_ticket_key, + choose_ciphersuite(policy, cert_chains, state->client_hello), + policy.choose_compression(state->client_hello->compression_methods()), + state->client_hello->fragment_size(), secure_renegotiation.supported(), secure_renegotiation.for_server_hello(), + state->client_hello->supports_session_ticket() && have_session_ticket_key, state->client_hello->next_protocol_notification(), m_possible_protocols, rng); @@ -505,7 +542,8 @@ void Server::process_handshake_msg(Handshake_Type type, state->new_session_ticket = new New_Session_Ticket(writer, state->hash, - session_info.encrypt(ticket_key, rng)); + session_info.encrypt(ticket_key, rng), + policy.session_ticket_lifetime()); } catch(...) {} } diff --git a/src/tls/tls_session.cpp b/src/tls/tls_session.cpp index 2a532196d..0e8bf3051 100644 --- a/src/tls/tls_session.cpp +++ b/src/tls/tls_session.cpp @@ -131,6 +131,11 @@ std::string Session::PEM_encode() const return PEM_Code::encode(this->DER_encode(), "SSL SESSION"); } +u32bit Session::session_age() const + { + return (system_time() - m_start_time); + } + namespace { const u32bit SESSION_CRYPTO_MAGIC = 0x571B0E4E; diff --git a/src/tls/tls_session.h b/src/tls/tls_session.h index 0c57201a4..9a3c242a8 100644 --- a/src/tls/tls_session.h +++ b/src/tls/tls_session.h @@ -177,6 +177,11 @@ class BOTAN_DLL Session u64bit start_time() const { return m_start_time; } /** + * Return how long this session has existed (in seconds) + */ + u32bit session_age() const; + + /** * Return the session ticket the server gave us */ const MemoryVector<byte>& session_ticket() const { return m_session_ticket; } diff --git a/src/tls/tls_session_manager.cpp b/src/tls/tls_session_manager.cpp index 59fc75b9f..812525d69 100644 --- a/src/tls/tls_session_manager.cpp +++ b/src/tls/tls_session_manager.cpp @@ -16,16 +16,16 @@ namespace TLS { bool Session_Manager_In_Memory::load_from_session_str( const std::string& session_str, Session& session) { - std::map<std::string, Session>::iterator i = sessions.find(session_str); + std::map<std::string, Session>::iterator i = m_sessions.find(session_str); - if(i == sessions.end()) + if(i == m_sessions.end()) return false; // session has expired, remove it const u64bit now = system_time(); - if(i->second.start_time() + session_lifetime < now) + if(i->second.start_time() + session_lifetime() < now) { - sessions.erase(i); + m_sessions.erase(i); return false; } @@ -45,18 +45,18 @@ bool Session_Manager_In_Memory::load_from_host_info( std::map<std::string, std::string>::iterator i; if(port > 0) - i = host_sessions.find(hostname + ":" + to_string(port)); + i = m_host_sessions.find(hostname + ":" + to_string(port)); else - i = host_sessions.find(hostname); + i = m_host_sessions.find(hostname); - if(i == host_sessions.end()) + if(i == m_host_sessions.end()) return false; if(load_from_session_str(i->second, session)) return true; - // was removed from sessions map, remove host_sessions entry - host_sessions.erase(i); + // was removed from m_sessions map, remove m_host_sessions entry + m_host_sessions.erase(i); return false; } @@ -65,30 +65,30 @@ void Session_Manager_In_Memory::remove_entry( const MemoryRegion<byte>& session_id) { std::map<std::string, Session>::iterator i = - sessions.find(hex_encode(session_id)); + m_sessions.find(hex_encode(session_id)); - if(i != sessions.end()) - sessions.erase(i); + if(i != m_sessions.end()) + m_sessions.erase(i); } void Session_Manager_In_Memory::save(const Session& session) { - if(max_sessions != 0) + if(m_max_sessions != 0) { /* This removes randomly based on ordering of session ids. Instead, remove oldest first? */ - while(sessions.size() >= max_sessions) - sessions.erase(sessions.begin()); + while(m_sessions.size() >= m_max_sessions) + m_sessions.erase(m_sessions.begin()); } const std::string session_id_str = hex_encode(session.session_id()); - sessions[session_id_str] = session; + m_sessions[session_id_str] = session; if(session.side() == CLIENT && session.sni_hostname() != "") - host_sessions[session.sni_hostname()] = session_id_str; + m_host_sessions[session.sni_hostname()] = session_id_str; } } diff --git a/src/tls/tls_session_manager.h b/src/tls/tls_session_manager.h index c0a9996e3..3a39bf50e 100644 --- a/src/tls/tls_session_manager.h +++ b/src/tls/tls_session_manager.h @@ -63,6 +63,13 @@ class BOTAN_DLL Session_Manager */ virtual void save(const Session& session) = 0; + /** + * Return the allowed lifetime of a session; beyond this time, + * sessions are not resumed. Returns 0 if unknown/no explicit + * expiration policy. + */ + virtual u32bit session_lifetime() const = 0; + virtual ~Session_Manager() {} }; @@ -82,9 +89,9 @@ class BOTAN_DLL Session_Manager_In_Memory : public Session_Manager * seconds have elapsed from initial handshake. */ Session_Manager_In_Memory(size_t max_sessions = 1000, - size_t session_lifetime = 7200) : - max_sessions(max_sessions), - session_lifetime(session_lifetime) + u32bit session_lifetime = 7200) : + m_max_sessions(max_sessions), + m_session_lifetime(session_lifetime) {} bool load_from_session_id(const MemoryRegion<byte>& session_id, @@ -97,14 +104,18 @@ class BOTAN_DLL Session_Manager_In_Memory : public Session_Manager void save(const Session& session_data); + u32bit session_lifetime() const { return m_session_lifetime; } + private: bool load_from_session_str(const std::string& session_str, Session& session); - size_t max_sessions, session_lifetime; + size_t m_max_sessions; + + u32bit m_session_lifetime; - std::map<std::string, Session> sessions; // hex(session_id) -> session - std::map<std::string, std::string> host_sessions; + std::map<std::string, Session> m_sessions; // hex(session_id) -> session + std::map<std::string, std::string> m_host_sessions; }; } |