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.cpp70
1 files changed, 56 insertions, 14 deletions
diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp
index 2119ca44e..a97ac65b3 100644
--- a/src/tls/tls_client.cpp
+++ b/src/tls/tls_client.cpp
@@ -12,6 +12,8 @@
#include <botan/dsa.h>
#include <botan/dh.h>
+#include <stdio.h>
+
namespace Botan {
/*
@@ -37,8 +39,11 @@ TLS_Client::TLS_Client(std::tr1::function<void (const byte[], size_t)> output_fn
state->hash,
policy,
rng,
+ secure_renegotiation.for_client_hello(),
hostname,
srp_username);
+
+ secure_renegotiation.update(state->client_hello);
}
void TLS_Client::add_client_cert(const X509_Certificate& cert,
@@ -57,33 +62,66 @@ TLS_Client::~TLS_Client()
}
/*
+* Send a new client hello to renegotiate
+*/
+void TLS_Client::renegotiate()
+ {
+ if(state)
+ return; // currently in handshake
+
+ state = new Handshake_State;
+ state->set_expected_next(SERVER_HELLO);
+
+ state->client_hello = new Client_Hello(writer, state->hash, policy, rng,
+ secure_renegotiation.for_client_hello());
+
+ secure_renegotiation.update(state->client_hello);
+ }
+
+/*
* Process a handshake message
*/
void TLS_Client::process_handshake_msg(Handshake_Type type,
const MemoryRegion<byte>& contents)
{
+ if(state == 0)
+ throw Unexpected_Message("Unexpected handshake message from server");
+
if(type == HELLO_REQUEST)
{
- if(state == 0)
- state = new Handshake_State();
- else
- return; // hello request in middle of handshake?
- }
+ printf("got a hello request\n");
- if(state == 0)
- throw Unexpected_Message("Unexpected handshake message");
+ Hello_Request hello_request(contents);
+
+ // Ignore request entirely if we are currently negotiating a handshake
+ if(state->client_hello)
+ return;
+
+ if(!secure_renegotiation.supported() && policy.require_secure_renegotiation())
+ {
+ delete state;
+ state = 0;
+
+ // RFC 5746 section 4.2
+ alert(WARNING, NO_RENEGOTIATION);
+ return;
+ }
+
+ state->set_expected_next(SERVER_HELLO);
+ state->client_hello = new Client_Hello(writer, state->hash, policy, rng,
+ secure_renegotiation.for_client_hello());
+
+ secure_renegotiation.update(state->client_hello);
+
+ return;
+ }
state->confirm_transition_to(type);
- if(type != HANDSHAKE_CCS && type != HELLO_REQUEST && type != FINISHED)
+ if(type != HANDSHAKE_CCS && type != FINISHED)
state->hash.update(type, contents);
- if(type == HELLO_REQUEST)
- {
- Hello_Request hello_request(contents);
- state->client_hello = new Client_Hello(writer, state->hash, policy, rng);
- }
- else if(type == SERVER_HELLO)
+ if(type == SERVER_HELLO)
{
state->server_hello = new Server_Hello(contents);
@@ -110,6 +148,8 @@ void TLS_Client::process_handshake_msg(Handshake_Type type,
writer.set_version(state->version);
reader.set_version(state->version);
+ secure_renegotiation.update(state->server_hello);
+
state->suite = CipherSuite(state->server_hello->ciphersuite());
// if resuming, next is HANDSHAKE_CCS
@@ -271,6 +311,8 @@ void TLS_Client::process_handshake_msg(Handshake_Type type,
throw TLS_Exception(DECRYPT_ERROR,
"Finished message didn't verify");
+ secure_renegotiation.update(state->client_finished, state->server_finished);
+
delete state;
state = 0;
active = true;