aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/tls.txt5
-rw-r--r--src/credentials/credentials_manager.cpp8
-rw-r--r--src/credentials/credentials_manager.h11
-rw-r--r--src/tls/s_hello.cpp4
-rw-r--r--src/tls/tls_messages.h1
-rw-r--r--src/tls/tls_server.cpp67
6 files changed, 39 insertions, 57 deletions
diff --git a/doc/tls.txt b/doc/tls.txt
index 8c2b815b6..dd4fb1270 100644
--- a/doc/tls.txt
+++ b/doc/tls.txt
@@ -98,7 +98,10 @@ TLS Clients
The *handshake_complete* function is called when a handshake
(either initial or renegotiation) is completed. The return value of
the callback specifies if the session should be cached for later
- resumption.
+ resumption. If the function for some reason desires to prevent the
+ connection from completing, it should throw an exception
+ (preferably a TLS_Exception, which can provide more specific alert
+ information to the counterparty).
The *session_manager* is an interface for storing TLS sessions,
which allows for session resumption upon reconnecting to a server.
diff --git a/src/credentials/credentials_manager.cpp b/src/credentials/credentials_manager.cpp
index a70d8d660..ef5d44819 100644
--- a/src/credentials/credentials_manager.cpp
+++ b/src/credentials/credentials_manager.cpp
@@ -7,7 +7,6 @@
#include <botan/credentials_manager.h>
#include <botan/x509stor.h>
-#include <botan/libstate.h>
namespace Botan {
@@ -31,13 +30,6 @@ SymmetricKey Credentials_Manager::psk(const std::string&,
throw Internal_Error("No PSK set for identity " + identity);
}
-const SymmetricKey& Credentials_Manager::session_ticket_key()
- {
- if(m_session_ticket_key.length() == 0)
- m_session_ticket_key = SymmetricKey(global_state().global_rng(), 32);
- return m_session_ticket_key;
- }
-
std::string Credentials_Manager::srp_identifier(const std::string&,
const std::string&)
{
diff --git a/src/credentials/credentials_manager.h b/src/credentials/credentials_manager.h
index 7fcdcd6eb..e1b4268e3 100644
--- a/src/credentials/credentials_manager.h
+++ b/src/credentials/credentials_manager.h
@@ -41,18 +41,14 @@ class BOTAN_DLL Credentials_Manager
const std::string& identity_hint);
/**
- * @return the PSK used for identity
+ * @return the PSK used for identity, or throw an exception if no
+ * key exists
*/
virtual SymmetricKey psk(const std::string& type,
const std::string& context,
const std::string& identity);
/**
- * @return key used to encrypt session tickets by a TLS server
- */
- virtual const SymmetricKey& session_ticket_key();
-
- /**
* @return identifier for client-side SRP auth, if available
for this type/context. Should return empty string
if password auth not desired/available.
@@ -142,9 +138,6 @@ class BOTAN_DLL Credentials_Manager
virtual Private_Key* private_key_for(const X509_Certificate& cert,
const std::string& type,
const std::string& context);
-
- private:
- SymmetricKey m_session_ticket_key;
};
}
diff --git a/src/tls/s_hello.cpp b/src/tls/s_hello.cpp
index 4cbc69f30..7da9fdc57 100644
--- a/src/tls/s_hello.cpp
+++ b/src/tls/s_hello.cpp
@@ -25,6 +25,7 @@ Server_Hello::Server_Hello(Record_Writer& writer,
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,
@@ -38,7 +39,8 @@ Server_Hello::Server_Hello(Record_Writer& writer,
m_renegotiation_info(reneg_info),
m_next_protocol(client_has_npn),
m_next_protocols(next_protocols),
- m_supports_session_ticket(c_hello.supports_session_ticket())
+ m_supports_session_ticket(have_session_ticket_key &&
+ c_hello.supports_session_ticket())
{
suite = policy.choose_suite(
c_hello.ciphersuites(),
diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h
index 7312d8bb1..2f8af5fd2 100644
--- a/src/tls/tls_messages.h
+++ b/src/tls/tls_messages.h
@@ -197,6 +197,7 @@ class Server_Hello : public Handshake_Message
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,
diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp
index e4c7ea339..1f69d153e 100644
--- a/src/tls/tls_server.cpp
+++ b/src/tls/tls_server.cpp
@@ -40,13 +40,9 @@ bool check_for_resume(Session& session_info,
// If a session ticket was sent, ignore client session ID
try
{
- const SymmetricKey& session_ticket_key = credentials.session_ticket_key();
-
- if(session_ticket_key.length() == 0)
- return false;
-
- session_info = Session::decrypt(session_ticket,
- session_ticket_key);
+ session_info = Session::decrypt(
+ session_ticket,
+ credentials.psk("tls-server", "session-ticket", ""));
}
catch(...)
{
@@ -221,7 +217,14 @@ void Server::process_handshake_msg(Handshake_Type type,
creds,
state->client_hello);
- const SymmetricKey& session_ticket_key = creds.session_ticket_key();
+ bool have_session_ticket_key = false;
+
+ try
+ {
+ have_session_ticket_key =
+ creds.psk("tls-server", "session-ticket", "").length() > 0;
+ }
+ catch(...) {}
if(resuming)
{
@@ -237,7 +240,7 @@ 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() && session_ticket_key.length() > 0,
+ state->client_hello->supports_session_ticket() && have_session_ticket_key,
state->client_hello->next_protocol_notification(),
m_possible_protocols,
rng);
@@ -265,14 +268,16 @@ void Server::process_handshake_msg(Handshake_Type type,
{
try
{
+ const SymmetricKey ticket_key = creds.psk("tls-server", "session-ticket", "");
+
state->new_session_ticket =
new New_Session_Ticket(writer, state->hash,
- session_info.encrypt(session_ticket_key, rng));
+ session_info.encrypt(ticket_key, rng));
}
- catch(...)
- {
+ catch(...) {}
+
+ if(!state->new_session_ticket)
state->new_session_ticket = new New_Session_Ticket(writer, state->hash);
- }
}
writer.send(CHANGE_CIPHER_SPEC, 1);
@@ -312,6 +317,7 @@ void Server::process_handshake_msg(Handshake_Type type,
*(state->client_hello),
available_cert_types,
policy,
+ have_session_ticket_key,
secure_renegotiation.supported(),
secure_renegotiation.for_server_hello(),
state->client_hello->next_protocol_notification(),
@@ -422,10 +428,9 @@ void Server::process_handshake_msg(Handshake_Type type,
state->hash.update(type, contents);
/*
- * Using DECRYPT_ERROR looks weird here, but per RFC 4346 this
- * error is for indicating that "A handshake cryptographic
- * operation failed, including being unable to correctly verify a
- * signature, ..."
+ * Using DECRYPT_ERROR looks weird here, but per RFC 4346 is for
+ * "A handshake cryptographic operation failed, including being
+ * unable to correctly verify a signature, ..."
*/
if(!sig_valid)
throw TLS_Exception(Alert::DECRYPT_ERROR, "Client cert verify failed");
@@ -496,17 +501,11 @@ void Server::process_handshake_msg(Handshake_Type type,
{
try
{
- const SymmetricKey& session_ticket_key =
- creds.session_ticket_key();
-
- if(session_ticket_key.length() > 0)
- {
- state->new_session_ticket =
- new New_Session_Ticket(
- writer,
- state->hash,
- session_info.encrypt(session_ticket_key, rng));
- }
+ const SymmetricKey ticket_key = creds.psk("tls-server", "session-ticket", "");
+
+ state->new_session_ticket =
+ new New_Session_Ticket(writer, state->hash,
+ session_info.encrypt(ticket_key, rng));
}
catch(...) {}
}
@@ -514,16 +513,8 @@ void Server::process_handshake_msg(Handshake_Type type,
session_manager.save(session_info);
}
- /*
- If we sent the extension we have to send something;
- an empty ticket is allowed
- */
- if(!state->new_session_ticket &&
- state->server_hello->supports_session_ticket())
- {
- state->new_session_ticket =
- new New_Session_Ticket(writer, state->hash);
- }
+ 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);