aboutsummaryrefslogtreecommitdiffstats
path: root/src/tls/tls_client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tls/tls_client.cpp')
-rw-r--r--src/tls/tls_client.cpp30
1 files changed, 26 insertions, 4 deletions
diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp
index 5b1ae1a26..f796736fa 100644
--- a/src/tls/tls_client.cpp
+++ b/src/tls/tls_client.cpp
@@ -25,7 +25,8 @@ TLS_Client::TLS_Client(std::tr1::function<void (const byte[], size_t)> output_fn
Credentials_Manager& creds,
const TLS_Policy& policy,
RandomNumberGenerator& rng,
- const std::string& hostname) :
+ const std::string& hostname,
+ std::tr1::function<std::string (std::vector<std::string>)> next_protocol) :
TLS_Channel(output_fn, proc_fn, handshake_fn),
policy(policy),
rng(rng),
@@ -37,8 +38,12 @@ TLS_Client::TLS_Client(std::tr1::function<void (const byte[], size_t)> output_fn
state = new Handshake_State;
state->set_expected_next(SERVER_HELLO);
+ state->client_npn_cb = next_protocol;
+
const std::string srp_identifier = creds.srp_identifier("tls-client", hostname);
+ const bool send_npn_request = static_cast<bool>(next_protocol);
+
if(hostname != "")
{
TLS_Session session_info;
@@ -50,7 +55,8 @@ TLS_Client::TLS_Client(std::tr1::function<void (const byte[], size_t)> output_fn
writer,
state->hash,
rng,
- session_info);
+ session_info,
+ send_npn_request);
state->resume_master_secret = session_info.master_secret();
}
@@ -65,6 +71,7 @@ TLS_Client::TLS_Client(std::tr1::function<void (const byte[], size_t)> output_fn
policy,
rng,
secure_renegotiation.for_client_hello(),
+ send_npn_request,
hostname,
srp_identifier);
}
@@ -137,14 +144,21 @@ void TLS_Client::process_handshake_msg(Handshake_Type type,
if(!state->client_hello->offered_suite(state->server_hello->ciphersuite()))
{
throw TLS_Exception(HANDSHAKE_FAILURE,
- "TLS_Client: Server replied with bad ciphersuite");
+ "Server replied with ciphersuite we didn't send");
}
if(!value_exists(state->client_hello->compression_methods(),
state->server_hello->compression_method()))
{
throw TLS_Exception(HANDSHAKE_FAILURE,
- "TLS_Client: Server replied with bad compression method");
+ "Server replied with compression method we didn't send");
+ }
+
+ if(!state->client_hello->next_protocol_negotiation() &&
+ state->server_hello->next_protocol_negotiation())
+ {
+ throw TLS_Exception(HANDSHAKE_FAILURE,
+ "Server sent next protocol but we didn't request it");
}
state->version = state->server_hello->version();
@@ -336,6 +350,14 @@ void TLS_Client::process_handshake_msg(Handshake_Type type,
writer.activate(state->suite, state->keys, CLIENT);
+ if(state->server_hello->next_protocol_negotiation())
+ {
+ const std::string protocol =
+ state->client_npn_cb(state->server_hello->next_protocols());
+
+ state->next_protocol = new Next_Protocol(writer, state->hash, protocol);
+ }
+
state->client_finished = new Finished(writer, state->hash,
state->version, CLIENT,
state->keys.master_secret());