aboutsummaryrefslogtreecommitdiffstats
path: root/src/tls
diff options
context:
space:
mode:
Diffstat (limited to 'src/tls')
-rw-r--r--src/tls/s_hello.cpp81
-rw-r--r--src/tls/sessions_sqlite/tls_sqlite_sess_mgr.cpp2
-rw-r--r--src/tls/sessions_sqlite/tls_sqlite_sess_mgr.h7
-rw-r--r--src/tls/tls_ciphersuite.cpp12
-rw-r--r--src/tls/tls_ciphersuite.h3
-rw-r--r--src/tls/tls_client.cpp4
-rw-r--r--src/tls/tls_extensions.cpp13
-rw-r--r--src/tls/tls_messages.h33
-rw-r--r--src/tls/tls_policy.cpp63
-rw-r--r--src/tls/tls_policy.h7
-rw-r--r--src/tls/tls_server.cpp82
-rw-r--r--src/tls/tls_session.cpp5
-rw-r--r--src/tls/tls_session.h5
-rw-r--r--src/tls/tls_session_manager.cpp34
-rw-r--r--src/tls/tls_session_manager.h23
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;
};
}