diff options
author | lloyd <[email protected]> | 2011-12-30 16:44:51 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2011-12-30 16:44:51 +0000 |
commit | 480adf560aedce4165cb5606701e3a5ff99dda41 (patch) | |
tree | 36679472c82a89ea6af14dddd5a83c209fbdbf3e /src/tls/tls_channel.cpp | |
parent | eedc562549e726e040a1a76893ddb264d3b85e64 (diff) |
Full support for renegotiation including RFC 5746 extensions for
client and server. Server side can handle SCSV values as well,
client always sends the extension instead.
Handle an empty SNI extension coming back from the server - this is
used to indicate that it understood the name. Also add better checking
for extensions by passing in what the supposed size of the extension
is.
Only send the secure negotiation extension in the server hello if the
client indicated support for it.
Diffstat (limited to 'src/tls/tls_channel.cpp')
-rw-r--r-- | src/tls/tls_channel.cpp | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/src/tls/tls_channel.cpp b/src/tls/tls_channel.cpp index 144ca659f..7d4bdc744 100644 --- a/src/tls/tls_channel.cpp +++ b/src/tls/tls_channel.cpp @@ -10,8 +10,6 @@ #include <botan/internal/tls_state.h> #include <botan/loadstor.h> -#include <stdio.h> - namespace Botan { TLS_Channel::TLS_Channel(std::tr1::function<void (const byte[], size_t)> socket_output_fn, @@ -200,14 +198,51 @@ void TLS_Channel::alert(Alert_Level alert_level, Alert_Type alert_code) void TLS_Channel::Secure_Renegotiation_State::update(Client_Hello* client_hello) { + if(initial_handshake) + { + secure_renegotiation = client_hello->secure_renegotiation(); + } + else + { + if(secure_renegotiation != client_hello->secure_renegotiation()) + throw TLS_Exception(HANDSHAKE_FAILURE, + "Client changed its mind about secure negotiation"); + } + if(client_hello->secure_renegotiation()) + { + const MemoryVector<byte>& data = client_hello->renegotiation_info(); + + if(initial_handshake) + { + if(!data.empty()) + throw TLS_Exception(HANDSHAKE_FAILURE, + "Client sent renegotiation data on initial handshake"); + } + else + { + if(data != for_client_hello()) + throw TLS_Exception(HANDSHAKE_FAILURE, + "Client sent bad renegotiation data"); + } + } } void TLS_Channel::Secure_Renegotiation_State::update(Server_Hello* server_hello) { - secure_renegotiation = server_hello->secure_renegotiation(); - - printf("server hello says sec reneg: %d\n", secure_renegotiation); + if(initial_handshake) + { + /* If the client offered but server rejected, then this toggles + * secure_renegotiation to off + */ + secure_renegotiation = server_hello->secure_renegotiation(); + } + else + { + if(secure_renegotiation != server_hello->secure_renegotiation()) + throw TLS_Exception(HANDSHAKE_FAILURE, + "Server changed its mind about secure negotiation"); + } if(secure_renegotiation) { |