diff options
author | lloyd <[email protected]> | 2012-04-18 19:44:59 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-04-18 19:44:59 +0000 |
commit | a8c026b7299d748b2e94f136377d6f46d4cb5da2 (patch) | |
tree | 9d768badeabcb0943156cef7d5934ea0dcb4a4ca | |
parent | 7ab8373cc2dd32ce45c119134b05121459b2789e (diff) |
Add a bool param to renegotiate on if we should force a full
renegotiation or not.
Save the hostname in the client so we can pull the session from the
session manager.
-rw-r--r-- | src/tls/c_hello.cpp | 6 | ||||
-rw-r--r-- | src/tls/tls_channel.h | 4 | ||||
-rw-r--r-- | src/tls/tls_client.cpp | 57 | ||||
-rw-r--r-- | src/tls/tls_client.h | 3 | ||||
-rw-r--r-- | src/tls/tls_handshake_state.cpp | 2 | ||||
-rw-r--r-- | src/tls/tls_handshake_state.h | 5 | ||||
-rw-r--r-- | src/tls/tls_messages.h | 1 | ||||
-rw-r--r-- | src/tls/tls_server.cpp | 19 | ||||
-rw-r--r-- | src/tls/tls_server.h | 2 |
9 files changed, 71 insertions, 28 deletions
diff --git a/src/tls/c_hello.cpp b/src/tls/c_hello.cpp index f498258b7..056a7550f 100644 --- a/src/tls/c_hello.cpp +++ b/src/tls/c_hello.cpp @@ -98,6 +98,7 @@ Client_Hello::Client_Hello(Record_Writer& writer, Handshake_Hash& hash, const Policy& policy, RandomNumberGenerator& rng, + const MemoryRegion<byte>& reneg_info, const Session& session, bool next_protocol) : m_version(session.version()), @@ -110,6 +111,7 @@ Client_Hello::Client_Hello(Record_Writer& writer, m_next_protocol(next_protocol), m_fragment_size(session.fragment_size()), m_secure_renegotiation(session.secure_renegotiation()), + m_renegotiation_info(reneg_info), m_supported_curves(policy.allowed_ecc_curves()), m_supports_session_ticket(true), m_session_ticket(session.session_ticket()), @@ -174,7 +176,9 @@ MemoryVector<byte> Client_Hello::serialize() const Extensions extensions; - extensions.add(new Renegotation_Extension(m_renegotiation_info)); + if(m_secure_renegotiation) + extensions.add(new Renegotation_Extension(m_renegotiation_info)); + extensions.add(new Session_Ticket(m_session_ticket)); extensions.add(new Server_Name_Indicator(m_hostname)); diff --git a/src/tls/tls_channel.h b/src/tls/tls_channel.h index 05fb7e82f..257745d80 100644 --- a/src/tls/tls_channel.h +++ b/src/tls/tls_channel.h @@ -54,8 +54,10 @@ class BOTAN_DLL Channel /** * Attempt to renegotiate the session + * @param force_full_renegotiation if true, require a full renegotiation, + * otherwise allow session resumption */ - virtual void renegotiate() = 0; + virtual void renegotiate(bool force_full_renegotiation) = 0; /** * Attempt to send a heartbeat message (if negotiated with counterparty) diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp index f6266ee6a..63d0ee148 100644 --- a/src/tls/tls_client.cpp +++ b/src/tls/tls_client.cpp @@ -31,7 +31,8 @@ Client::Client(std::tr1::function<void (const byte[], size_t)> output_fn, policy(policy), rng(rng), session_manager(session_manager), - creds(creds) + creds(creds), + m_hostname(hostname) { writer.set_version(Protocol_Version::SSL_V3); @@ -56,6 +57,7 @@ Client::Client(std::tr1::function<void (const byte[], size_t)> output_fn, state->hash, policy, rng, + secure_renegotiation.for_client_hello(), session_info, send_npn_request); @@ -83,16 +85,42 @@ Client::Client(std::tr1::function<void (const byte[], size_t)> output_fn, /* * Send a new client hello to renegotiate */ -void Client::renegotiate() +void Client::renegotiate(bool force_full_renegotiation) { - if(state) - return; // currently in handshake + if(state && state->client_hello) + return; // currently in active handshake + delete state; state = new Handshake_State(new Stream_Handshake_Reader); + state->set_expected_next(SERVER_HELLO); - state->client_hello = new Client_Hello(writer, state->hash, policy, rng, - secure_renegotiation.for_client_hello()); + if(!force_full_renegotiation) + { + Session session_info; + if(session_manager.load_from_host_info(m_hostname, 0, session_info)) + { + state->client_hello = new Client_Hello( + writer, + state->hash, + policy, + rng, + secure_renegotiation.for_client_hello(), + session_info); + + state->resume_master_secret = session_info.master_secret(); + } + } + + if(!state->client_hello) + { + state->client_hello = new Client_Hello( + writer, + state->hash, + policy, + rng, + secure_renegotiation.for_client_hello()); + } secure_renegotiation.update(state->client_hello); } @@ -136,11 +164,7 @@ void Client::process_handshake_msg(Handshake_Type type, return; } - state->client_hello = new Client_Hello(writer, state->hash, policy, rng, - secure_renegotiation.for_client_hello()); - secure_renegotiation.update(state->client_hello); - - state->set_expected_next(SERVER_HELLO); + renegotiate(false); return; } @@ -283,8 +307,7 @@ void Client::process_handshake_msg(Handshake_Type type, try { - const std::string hostname = state->client_hello->sni_hostname(); - creds.verify_certificate_chain("tls-client", hostname, peer_certs); + creds.verify_certificate_chain("tls-client", m_hostname, peer_certs); } catch(std::exception& e) { @@ -333,7 +356,7 @@ void Client::process_handshake_msg(Handshake_Type type, std::vector<X509_Certificate> client_certs = creds.cert_chain(types, "tls-client", - state->client_hello->sni_hostname()); + m_hostname); state->client_certs = new Certificate(writer, state->hash, @@ -345,7 +368,7 @@ void Client::process_handshake_msg(Handshake_Type type, state, creds, peer_certs, - state->client_hello->sni_hostname(), + m_hostname, rng); state->keys = Session_Keys(state, @@ -358,7 +381,7 @@ void Client::process_handshake_msg(Handshake_Type type, Private_Key* private_key = creds.private_key_for(state->client_certs->cert_chain()[0], "tls-client", - state->client_hello->sni_hostname()); + m_hostname); state->client_verify = new Certificate_Verify(writer, state, @@ -441,7 +464,7 @@ void Client::process_handshake_msg(Handshake_Type type, state->server_hello->fragment_size(), peer_certs, session_ticket, - state->client_hello->sni_hostname(), + m_hostname, "" ); diff --git a/src/tls/tls_client.h b/src/tls/tls_client.h index 5c2692cd6..4efe2a2df 100644 --- a/src/tls/tls_client.h +++ b/src/tls/tls_client.h @@ -53,7 +53,7 @@ class BOTAN_DLL Client : public Channel std::tr1::function<std::string (std::vector<std::string>)> next_protocol = std::tr1::function<std::string (std::vector<std::string>)>()); - void renegotiate(); + void renegotiate(bool force_full_renegotiation); private: void process_handshake_msg(Handshake_Type type, const MemoryRegion<byte>& contents); @@ -64,6 +64,7 @@ class BOTAN_DLL Client : public Channel RandomNumberGenerator& rng; Session_Manager& session_manager; Credentials_Manager& creds; + const std::string m_hostname; }; } diff --git a/src/tls/tls_handshake_state.cpp b/src/tls/tls_handshake_state.cpp index 8e9003108..1a55305e3 100644 --- a/src/tls/tls_handshake_state.cpp +++ b/src/tls/tls_handshake_state.cpp @@ -104,6 +104,8 @@ Handshake_State::Handshake_State(Handshake_Reader* reader) hand_expecting_mask = 0; hand_received_mask = 0; + + allow_session_resumption = true; } void Handshake_State::set_version(const Protocol_Version& version) diff --git a/src/tls/tls_handshake_state.h b/src/tls/tls_handshake_state.h index c347c4574..ec4c2fea8 100644 --- a/src/tls/tls_handshake_state.h +++ b/src/tls/tls_handshake_state.h @@ -101,6 +101,11 @@ class Handshake_State */ SecureVector<byte> resume_master_secret; + /* + * + */ + bool allow_session_resumption; + /** * Used by client using NPN */ diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h index 4c2b1b797..d9146dda1 100644 --- a/src/tls/tls_messages.h +++ b/src/tls/tls_messages.h @@ -126,6 +126,7 @@ class Client_Hello : public Handshake_Message Handshake_Hash& hash, const Policy& policy, RandomNumberGenerator& rng, + const MemoryRegion<byte>& reneg_info, const Session& resumed_session, bool next_protocol = false); diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp index 312656eb1..9da4ca3b8 100644 --- a/src/tls/tls_server.cpp +++ b/src/tls/tls_server.cpp @@ -204,12 +204,14 @@ Server::Server(std::tr1::function<void (const byte[], size_t)> output_fn, /* * Send a hello request to the client */ -void Server::renegotiate() +void Server::renegotiate(bool force_full_renegotiation) { if(state) return; // currently in handshake state = new Handshake_State(new Stream_Handshake_Reader); + + state->allow_session_resumption = !force_full_renegotiation; state->set_expected_next(CLIENT_HELLO); Hello_Request hello_req(writer); } @@ -271,7 +273,8 @@ void Server::process_handshake_msg(Handshake_Type type, { state->client_hello = new Client_Hello(contents, type); - m_hostname = state->client_hello->sni_hostname(); + if(state->client_hello->sni_hostname() != "") + m_hostname = state->client_hello->sni_hostname(); Protocol_Version client_version = state->client_hello->version(); @@ -293,11 +296,13 @@ void Server::process_handshake_msg(Handshake_Type type, reader.set_version(state->version()); Session session_info; - const bool resuming = check_for_resume(session_info, - session_manager, - creds, - state->client_hello, - policy.session_ticket_lifetime()); + const bool resuming = + state->allow_session_resumption && + check_for_resume(session_info, + session_manager, + creds, + state->client_hello, + policy.session_ticket_lifetime()); bool have_session_ticket_key = false; diff --git a/src/tls/tls_server.h b/src/tls/tls_server.h index 025bbf3ec..6ade91afc 100644 --- a/src/tls/tls_server.h +++ b/src/tls/tls_server.h @@ -36,7 +36,7 @@ class BOTAN_DLL Server : public Channel const std::vector<std::string>& protocols = std::vector<std::string>()); - void renegotiate(); + void renegotiate(bool force_full_renegotiation); /** * Return the server name indicator, if sent by the client |