diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/tls/tls_client.cpp | 8 | ||||
-rw-r--r-- | src/tls/tls_messages.h | 2 | ||||
-rw-r--r-- | src/tls/tls_server.cpp | 53 | ||||
-rw-r--r-- | src/tls/tls_session_state.cpp | 7 | ||||
-rw-r--r-- | src/tls/tls_session_state.h | 2 |
5 files changed, 30 insertions, 42 deletions
diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp index d8861459c..5dbcadaea 100644 --- a/src/tls/tls_client.cpp +++ b/src/tls/tls_client.cpp @@ -69,13 +69,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, state->confirm_transition_to(type); if(type != HANDSHAKE_CCS && type != HELLO_REQUEST && type != FINISHED) - { - state->hash.update(static_cast<byte>(type)); - const size_t record_length = contents.size(); - for(size_t i = 0; i != 3; i++) - state->hash.update(get_byte<u32bit>(i+1, record_length)); - state->hash.update(contents); - } + state->hash.update(type, contents); if(type == HELLO_REQUEST) { diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h index 880f77c98..8cfaea37e 100644 --- a/src/tls/tls_messages.h +++ b/src/tls/tls_messages.h @@ -131,7 +131,7 @@ class Certificate : public HandshakeMessage { public: Handshake_Type type() const { return CERTIFICATE; } - std::vector<X509_Certificate> cert_chain() const { return certs; } + const std::vector<X509_Certificate>& cert_chain() const { return certs; } size_t count() const { return certs.size(); } bool empty() const { return certs.empty(); } diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp index 581d562be..784bdc031 100644 --- a/src/tls/tls_server.cpp +++ b/src/tls/tls_server.cpp @@ -133,18 +133,19 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, state->confirm_transition_to(type); + /* + * The change cipher spec message isn't technically a handshake + * message so it's not included in the hash. The finished and + * certificate verify messages are verified based on the current + * state of the hash *before* this message so we delay adding them + * to the hash computation until we've processed them below. + */ if(type != HANDSHAKE_CCS && type != FINISHED && type != CERTIFICATE_VERIFY) { - if(type != CLIENT_HELLO_SSLV2) - { - state->hash.update(static_cast<byte>(type)); - - const size_t record_length = contents.size(); - for(size_t i = 0; i != 3; i++) - state->hash.update(get_byte<u32bit>(i+1, record_length)); - } - - state->hash.update(contents); + if(type == CLIENT_HELLO_SSLV2) + state->hash.update(contents); + else + state->hash.update(type, contents); } if(type == CLIENT_HELLO || type == CLIENT_HELLO_SSLV2) @@ -292,30 +293,23 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, { state->client_verify = new Certificate_Verify(contents); - std::vector<X509_Certificate> client_certs = state->client_certs->cert_chain(); + const std::vector<X509_Certificate>& client_certs = + state->client_certs->cert_chain(); const bool sig_valid = state->client_verify->verify(client_certs[0], state->hash); - state->hash.update(static_cast<byte>(type)); - - const size_t record_length = contents.size(); - for(size_t i = 0; i != 3; i++) - state->hash.update(get_byte<u32bit>(i+1, record_length)); - - state->hash.update(contents); + state->hash.update(type, contents); /* * Using DECRYPT_ERROR looks weird here, but per RFC 4346 is for * "A handshake cryptographic operation failed, including being * unable to correctly verify a signature, ..." */ - if(!sig_valid && false) + if(!sig_valid) throw TLS_Exception(DECRYPT_ERROR, "Client cert verify failed"); - printf("Sig valid? %d\n", sig_valid); - - // Check cert was issued by a CA we requested, signatures, etc. + // FIXME: check cert was issued by a CA we requested, signatures, etc. state->set_expected_next(HANDSHAKE_CCS); } @@ -339,13 +333,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, // already sent it if resuming if(!state->server_finished) { - state->hash.update(static_cast<byte>(type)); - - const size_t record_length = contents.size(); - for(size_t i = 0; i != 3; i++) - state->hash.update(get_byte<u32bit>(i+1, record_length)); - - state->hash.update(contents); + state->hash.update(type, contents); writer.send(CHANGE_CIPHER_SPEC, 1); writer.flush(); @@ -356,6 +344,11 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, state->keys.master_secret(), state->hash); + std::vector<X509_Certificate> peer_certs; + + if(state->client_certs && state->client_verify) + peer_certs = state->client_certs->cert_chain(); + TLS_Session_Params session_info( state->server_hello->session_id(), state->keys.master_secret(), @@ -363,7 +356,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, state->server_hello->ciphersuite(), state->server_hello->compression_method(), SERVER, - 0, + peer_certs, client_requested_hostname, "" ); diff --git a/src/tls/tls_session_state.cpp b/src/tls/tls_session_state.cpp index dd2c91c70..3b54a795e 100644 --- a/src/tls/tls_session_state.cpp +++ b/src/tls/tls_session_state.cpp @@ -19,7 +19,7 @@ TLS_Session_Params::TLS_Session_Params(const MemoryRegion<byte>& session_identif u16bit ciphersuite, byte compression_method, Connection_Side side, - const X509_Certificate* cert, + const std::vector<X509_Certificate>& certs, const std::string& sni_hostname, const std::string& srp_identifier) : session_start_time(system_time()), @@ -32,8 +32,9 @@ TLS_Session_Params::TLS_Session_Params(const MemoryRegion<byte>& session_identif session_sni_hostname(sni_hostname), session_srp_identifier(srp_identifier) { - if(cert) - session_peer_certificate = cert->BER_encode(); + // FIXME: encode all of them? + if(certs.size()) + session_peer_certificate = certs[0].BER_encode(); } TLS_Session_Params::TLS_Session_Params(const byte ber[], size_t ber_len) diff --git a/src/tls/tls_session_state.h b/src/tls/tls_session_state.h index 93793c882..3f1b52a00 100644 --- a/src/tls/tls_session_state.h +++ b/src/tls/tls_session_state.h @@ -44,7 +44,7 @@ class BOTAN_DLL TLS_Session_Params u16bit ciphersuite, byte compression_method, Connection_Side side, - const X509_Certificate* cert = 0, + const std::vector<X509_Certificate>& peer_certs, const std::string& sni_hostname = "", const std::string& srp_identifier = ""); |