aboutsummaryrefslogtreecommitdiffstats
path: root/src/tls
diff options
context:
space:
mode:
Diffstat (limited to 'src/tls')
-rw-r--r--src/tls/tls_channel.cpp56
-rw-r--r--src/tls/tls_channel.h41
-rw-r--r--src/tls/tls_client.cpp15
-rw-r--r--src/tls/tls_server.cpp18
4 files changed, 62 insertions, 68 deletions
diff --git a/src/tls/tls_channel.cpp b/src/tls/tls_channel.cpp
index 2054d4bec..e54af7f0b 100644
--- a/src/tls/tls_channel.cpp
+++ b/src/tls/tls_channel.cpp
@@ -124,9 +124,6 @@ void Channel::change_cipher_spec_writer(Connection_Side side)
void Channel::activate_session()
{
- m_secure_renegotiation.update(m_pending_state->client_finished(),
- m_pending_state->server_finished());
-
std::swap(m_active_state, m_pending_state);
m_pending_state.reset();
}
@@ -426,15 +423,17 @@ void Channel::send_alert(const Alert& alert)
}
}
-void Channel::Secure_Renegotiation_State::update(const Client_Hello* client_hello)
+void Channel::secure_renegotiation_check(const Client_Hello* client_hello)
{
- if(initial_handshake())
+ const bool initial_handshake = !m_active_state;
+
+ if(initial_handshake)
{
m_secure_renegotiation = client_hello->secure_renegotiation();
}
else
{
- if(supported() && !client_hello->secure_renegotiation())
+ if(secure_renegotiation_supported() && !client_hello->secure_renegotiation())
throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
"Client changed its mind about secure renegotiation");
}
@@ -443,7 +442,7 @@ void Channel::Secure_Renegotiation_State::update(const Client_Hello* client_hell
{
const std::vector<byte>& data = client_hello->renegotiation_info();
- if(initial_handshake())
+ if(initial_handshake)
{
if(!data.empty())
throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
@@ -451,35 +450,37 @@ void Channel::Secure_Renegotiation_State::update(const Client_Hello* client_hell
}
else
{
- if(data != for_client_hello())
+ if(data != secure_renegotiation_data_for_client_hello())
throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
"Client sent bad renegotiation data");
}
}
}
-void Channel::Secure_Renegotiation_State::update(const Server_Hello* server_hello)
+void Channel::secure_renegotiation_check(const Server_Hello* server_hello)
{
- if(initial_handshake())
+ const bool initial_handshake = !m_active_state;
+
+ if(initial_handshake)
{
/* If the client offered but server rejected, then this toggles
- * secure_renegotiation to off
+ * secure renegotiation to off
*/
if(m_secure_renegotiation)
m_secure_renegotiation = server_hello->secure_renegotiation();
}
else
{
- if(supported() != server_hello->secure_renegotiation())
+ if(secure_renegotiation_supported() != server_hello->secure_renegotiation())
throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
"Server changed its mind about secure renegotiation");
}
- if(supported())
+ if(secure_renegotiation_supported())
{
const std::vector<byte>& data = server_hello->renegotiation_info();
- if(initial_handshake())
+ if(initial_handshake)
{
if(!data.empty())
throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
@@ -487,20 +488,35 @@ void Channel::Secure_Renegotiation_State::update(const Server_Hello* server_hell
}
else
{
- if(data != for_server_hello())
+ if(data != secure_renegotiation_data_for_server_hello())
throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
"Server sent bad renegotiation data");
}
}
+ }
+
+std::vector<byte> Channel::secure_renegotiation_data_for_client_hello() const
+ {
+ if(m_active_state)
+ return m_active_state->client_finished()->verify_data();
+ return std::vector<byte>();
+ }
+
+std::vector<byte> Channel::secure_renegotiation_data_for_server_hello() const
+ {
+ if(m_active_state)
+ {
+ std::vector<byte> buf = m_active_state->client_finished()->verify_data();
+ buf += m_active_state->server_finished()->verify_data();
+ return buf;
+ }
- m_initial_handshake = false;
+ return std::vector<byte>();
}
-void Channel::Secure_Renegotiation_State::update(const Finished* client_finished,
- const Finished* server_finished)
+bool Channel::secure_renegotiation_supported() const
{
- m_client_verify = client_finished->verify_data();
- m_server_verify = server_finished->verify_data();
+ return m_secure_renegotiation;
}
}
diff --git a/src/tls/tls_channel.h b/src/tls/tls_channel.h
index 63d9b7264..1d0629ff9 100644
--- a/src/tls/tls_channel.h
+++ b/src/tls/tls_channel.h
@@ -132,35 +132,17 @@ class BOTAN_DLL Channel
void send_record(byte record_type, const std::vector<byte>& record);
- class Secure_Renegotiation_State
- {
- public:
- void update(const class Client_Hello* client_hello);
- void update(const class Server_Hello* server_hello);
-
- void update(const class Finished* client_finished,
- const class Finished* server_finished);
-
- const std::vector<byte>& for_client_hello() const
- { return m_client_verify; }
-
- std::vector<byte> for_server_hello() const
- {
- std::vector<byte> buf = m_client_verify;
- buf += m_server_verify;
- return buf;
- }
-
- bool supported() const
- { return m_secure_renegotiation; }
-
- bool initial_handshake() const { return m_initial_handshake; }
- private:
- bool m_initial_handshake = true;
- bool m_secure_renegotiation = false;
- std::vector<byte> m_client_verify, m_server_verify;
- };
+ /* secure renegotiation handling */
+ void secure_renegotiation_check(const class Client_Hello* client_hello);
+ void secure_renegotiation_check(const class Server_Hello* server_hello);
+
+ std::vector<byte> secure_renegotiation_data_for_client_hello() const;
+ std::vector<byte> secure_renegotiation_data_for_server_hello() const;
+
+ bool secure_renegotiation_supported() const;
+
+ /* state accesssible by subclasses */
std::function<bool (const Session&)> m_handshake_fn;
RandomNumberGenerator& m_rng;
@@ -168,8 +150,6 @@ class BOTAN_DLL Channel
std::vector<X509_Certificate> m_peer_certs;
- Secure_Renegotiation_State m_secure_renegotiation;
-
private:
void send_record(byte type, const byte input[], size_t length);
@@ -201,6 +181,7 @@ class BOTAN_DLL Channel
Protocol_Version m_current_version;
size_t m_max_fragment = MAX_PLAINTEXT_SIZE;
+ bool m_secure_renegotiation = false;
bool m_connection_closed = false;
};
diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp
index 77206abc3..eac8e263b 100644
--- a/src/tls/tls_client.cpp
+++ b/src/tls/tls_client.cpp
@@ -111,7 +111,7 @@ void Client::initiate_handshake(Handshake_State& state,
state.hash(),
m_policy,
m_rng,
- m_secure_renegotiation.for_client_hello(),
+ secure_renegotiation_data_for_client_hello(),
session_info,
send_npn_request));
@@ -129,13 +129,13 @@ void Client::initiate_handshake(Handshake_State& state,
version,
m_policy,
m_rng,
- m_secure_renegotiation.for_client_hello(),
+ secure_renegotiation_data_for_client_hello(),
send_npn_request,
m_hostname,
srp_identifier));
}
- m_secure_renegotiation.update(state.client_hello());
+ secure_renegotiation_check(state.client_hello());
set_maximum_fragment_size(state.client_hello()->fragment_size());
}
@@ -157,7 +157,7 @@ void Client::process_handshake_msg(const Handshake_State* /*active_state*/,
return;
if(!m_policy.allow_server_initiated_renegotiation() ||
- (!m_policy.allow_insecure_renegotiation() && !m_secure_renegotiation.supported()))
+ (!m_policy.allow_insecure_renegotiation() && !secure_renegotiation_supported()))
{
// RFC 5746 section 4.2
send_alert(Alert(Alert::NO_RENEGOTIATION));
@@ -224,7 +224,7 @@ void Client::process_handshake_msg(const Handshake_State* /*active_state*/,
set_protocol_version(state.server_hello()->version());
- m_secure_renegotiation.update(state.server_hello());
+ secure_renegotiation_check(state.server_hello());
const bool server_returned_same_session_id =
!state.server_hello()->session_id().empty() &&
@@ -479,9 +479,6 @@ void Client::process_handshake_msg(const Handshake_State* /*active_state*/,
);
}
- m_secure_renegotiation.update(state.client_finished(),
- state.server_finished());
-
std::vector<byte> session_id = state.server_hello()->session_id();
const std::vector<byte>& session_ticket = state.session_ticket();
@@ -496,7 +493,7 @@ void Client::process_handshake_msg(const Handshake_State* /*active_state*/,
state.server_hello()->ciphersuite(),
state.server_hello()->compression_method(),
CLIENT,
- m_secure_renegotiation.supported(),
+ secure_renegotiation_supported(),
state.server_hello()->fragment_size(),
m_peer_certs,
session_ticket,
diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp
index fe9018ac2..cda53d6b2 100644
--- a/src/tls/tls_server.cpp
+++ b/src/tls/tls_server.cpp
@@ -278,7 +278,7 @@ void Server::process_handshake_msg(const Handshake_State* active_state,
const bool initial_handshake = !active_state;
if(!m_policy.allow_insecure_renegotiation() &&
- !(initial_handshake || m_secure_renegotiation.supported()))
+ !(initial_handshake || secure_renegotiation_supported()))
{
send_alert(Alert(Alert::NO_RENEGOTIATION));
return;
@@ -340,7 +340,7 @@ void Server::process_handshake_msg(const Handshake_State* active_state,
"Client version is unacceptable by policy");
}
- m_secure_renegotiation.update(state.client_hello());
+ secure_renegotiation_check(state.client_hello());
set_protocol_version(negotiated_version);
@@ -380,8 +380,8 @@ void Server::process_handshake_msg(const Handshake_State* active_state,
session_info.ciphersuite_code(),
session_info.compression_method(),
session_info.fragment_size(),
- m_secure_renegotiation.supported(),
- m_secure_renegotiation.for_server_hello(),
+ secure_renegotiation_supported(),
+ secure_renegotiation_data_for_server_hello(),
offer_new_session_ticket,
state.client_hello()->next_protocol_notification(),
m_possible_protocols,
@@ -389,7 +389,7 @@ void Server::process_handshake_msg(const Handshake_State* active_state,
m_rng)
);
- m_secure_renegotiation.update(state.server_hello());
+ secure_renegotiation_check(state.server_hello());
if(session_info.fragment_size())
set_maximum_fragment_size(session_info.fragment_size());
@@ -476,8 +476,8 @@ void Server::process_handshake_msg(const Handshake_State* active_state,
state.client_hello()),
choose_compression(m_policy, state.client_hello()->compression_methods()),
state.client_hello()->fragment_size(),
- m_secure_renegotiation.supported(),
- m_secure_renegotiation.for_server_hello(),
+ secure_renegotiation_supported(),
+ secure_renegotiation_data_for_server_hello(),
state.client_hello()->supports_session_ticket() && have_session_ticket_key,
state.client_hello()->next_protocol_notification(),
m_possible_protocols,
@@ -485,7 +485,7 @@ void Server::process_handshake_msg(const Handshake_State* active_state,
m_rng)
);
- m_secure_renegotiation.update(state.server_hello());
+ secure_renegotiation_check(state.server_hello());
if(state.client_hello()->fragment_size())
set_maximum_fragment_size(state.client_hello()->fragment_size());
@@ -654,7 +654,7 @@ void Server::process_handshake_msg(const Handshake_State* active_state,
state.server_hello()->ciphersuite(),
state.server_hello()->compression_method(),
SERVER,
- m_secure_renegotiation.supported(),
+ secure_renegotiation_supported(),
state.server_hello()->fragment_size(),
m_peer_certs,
std::vector<byte>(),