aboutsummaryrefslogtreecommitdiffstats
path: root/src/tls/tls_server.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tls/tls_server.cpp')
-rw-r--r--src/tls/tls_server.cpp92
1 files changed, 68 insertions, 24 deletions
diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp
index 874aa064c..7632dfcdd 100644
--- a/src/tls/tls_server.cpp
+++ b/src/tls/tls_server.cpp
@@ -22,14 +22,31 @@ bool check_for_resume(Session& session_info,
Session_Manager& session_manager,
Client_Hello* client_hello)
{
- MemoryVector<byte> client_session_id = client_hello->session_id();
+ const MemoryVector<byte>& client_session_id = client_hello->session_id();
+ const MemoryVector<byte>& session_ticket = client_hello->session_ticket();
- if(client_session_id.empty()) // not resuming
- return false;
+ if(session_ticket.empty())
+ {
+ if(client_session_id.empty()) // not resuming
+ return false;
- // not found
- if(!session_manager.load_from_session_id(client_session_id, session_info))
- return false;
+ // not found
+ if(!session_manager.load_from_session_id(client_session_id, session_info))
+ return false;
+ }
+ else
+ {
+ // If a session ticket was sent, ignore client session ID
+ try
+ {
+#warning fixed key
+ session_info = Session::decrypt(session_ticket, SymmetricKey("ABCDEF"));
+ }
+ catch(std::exception& e)
+ {
+ return false;
+ }
+ }
// wrong version
if(client_hello->version() != session_info.version())
@@ -45,14 +62,14 @@ bool check_for_resume(Session& session_info,
session_info.compression_method()))
return false;
- // client sent a different SRP identity (!!!)
+ // client sent a different SRP identity
if(client_hello->srp_identifier() != "")
{
if(client_hello->srp_identifier() != session_info.srp_identifier())
return false;
}
- // client sent a different SNI hostname (!!!)
+ // client sent a different SNI hostname
if(client_hello->sni_hostname() != "")
{
if(client_hello->sni_hostname() != session_info.sni_hostname())
@@ -204,13 +221,14 @@ void Server::process_handshake_msg(Handshake_Type type,
state->server_hello = new Server_Hello(
writer,
state->hash,
- session_info.session_id(),
+ state->client_hello->session_id(),
Protocol_Version(session_info.version()),
session_info.ciphersuite_code(),
session_info.compression_method(),
session_info.fragment_size(),
secure_renegotiation.supported(),
secure_renegotiation.for_server_hello(),
+ state->client_hello->supports_session_ticket(),
state->client_hello->next_protocol_notification(),
m_possible_protocols,
rng);
@@ -225,6 +243,22 @@ void Server::process_handshake_msg(Handshake_Type type,
state->keys = Session_Keys(state, session_info.master_secret(), true);
+ if(!handshake_fn(session_info))
+ {
+ if(state->server_hello->supports_session_ticket())
+ state->new_session_ticket = new New_Session_Ticket(writer, state->hash);
+ else
+ session_manager.remove_entry(session_info.session_id());
+ }
+
+ // Should only send a new ticket if we need too (eg old session)
+ if(state->server_hello->supports_session_ticket() && !state->new_session_ticket)
+ {
+ state->new_session_ticket =
+ new New_Session_Ticket(writer, state->hash,
+ session_info.encrypt(SymmetricKey("ABCDEF"), rng));
+ }
+
writer.send(CHANGE_CIPHER_SPEC, 1);
writer.activate(SERVER, state->suite, state->keys,
@@ -232,8 +266,6 @@ void Server::process_handshake_msg(Handshake_Type type,
state->server_finished = new Finished(writer, state, SERVER);
- if(!handshake_fn(session_info))
- session_manager.remove_entry(session_info.session_id());
state->set_expected_next(HANDSHAKE_CCS);
}
@@ -423,20 +455,10 @@ void Server::process_handshake_msg(Handshake_Type type,
if(!state->server_finished)
{
- state->hash.update(type, contents);
-
- writer.send(CHANGE_CIPHER_SPEC, 1);
-
- writer.activate(SERVER, state->suite, state->keys,
- state->server_hello->compression_method());
-
- state->server_finished = new Finished(writer, state, SERVER);
-
- if(state->client_certs && state->client_verify)
- peer_certs = state->client_certs->cert_chain();
-
// already sent finished if resuming, so this is a new session
+ state->hash.update(type, contents);
+
Session session_info(
state->server_hello->session_id(),
state->keys.master_secret(),
@@ -453,7 +475,29 @@ void Server::process_handshake_msg(Handshake_Type type,
);
if(handshake_fn(session_info))
- session_manager.save(session_info);
+ {
+ if(state->server_hello->supports_session_ticket())
+ {
+ state->new_session_ticket =
+ new New_Session_Ticket(writer, state->hash,
+ session_info.encrypt(SymmetricKey("ABCDEF"), rng));
+ }
+ else
+ session_manager.save(session_info);
+ }
+
+ if(state->server_hello->supports_session_ticket() && !state->new_session_ticket)
+ state->new_session_ticket = new New_Session_Ticket(writer, state->hash);
+
+ writer.send(CHANGE_CIPHER_SPEC, 1);
+
+ writer.activate(SERVER, state->suite, state->keys,
+ state->server_hello->compression_method());
+
+ state->server_finished = new Finished(writer, state, SERVER);
+
+ if(state->client_certs && state->client_verify)
+ peer_certs = state->client_certs->cert_chain();
}
secure_renegotiation.update(state->client_finished,