aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-04-18 19:44:59 +0000
committerlloyd <[email protected]>2012-04-18 19:44:59 +0000
commita8c026b7299d748b2e94f136377d6f46d4cb5da2 (patch)
tree9d768badeabcb0943156cef7d5934ea0dcb4a4ca
parent7ab8373cc2dd32ce45c119134b05121459b2789e (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.cpp6
-rw-r--r--src/tls/tls_channel.h4
-rw-r--r--src/tls/tls_client.cpp57
-rw-r--r--src/tls/tls_client.h3
-rw-r--r--src/tls/tls_handshake_state.cpp2
-rw-r--r--src/tls/tls_handshake_state.h5
-rw-r--r--src/tls/tls_messages.h1
-rw-r--r--src/tls/tls_server.cpp19
-rw-r--r--src/tls/tls_server.h2
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