diff options
-rw-r--r-- | doc/tls.txt | 5 | ||||
-rw-r--r-- | src/credentials/credentials_manager.cpp | 8 | ||||
-rw-r--r-- | src/credentials/credentials_manager.h | 11 | ||||
-rw-r--r-- | src/tls/s_hello.cpp | 4 | ||||
-rw-r--r-- | src/tls/tls_messages.h | 1 | ||||
-rw-r--r-- | src/tls/tls_server.cpp | 67 |
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); |