From d2e2853bf59b1ac2adf82f8f5cd943f8c0bf4fe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?= <grubba@grubba.org> Date: Sun, 4 May 2014 22:38:00 +0200 Subject: [PATCH] SSL.Connection: Unified the handshake states. Now that there is separate code for the server and client handshake state-machines, there's no reason for them to have different STATE_* codes. Also splits and moves finished_packet() to {Client,Server}Connection. --- lib/modules/SSL.pmod/ClientConnection.pike | 22 ++++++++++----- lib/modules/SSL.pmod/Connection.pike | 14 ---------- lib/modules/SSL.pmod/Constants.pmod | 13 +++------ lib/modules/SSL.pmod/ServerConnection.pike | 32 ++++++++++++++-------- 4 files changed, 39 insertions(+), 42 deletions(-) diff --git a/lib/modules/SSL.pmod/ClientConnection.pike b/lib/modules/SSL.pmod/ClientConnection.pike index 7e34401102..d87aee483c 100644 --- a/lib/modules/SSL.pmod/ClientConnection.pike +++ b/lib/modules/SSL.pmod/ClientConnection.pike @@ -169,10 +169,18 @@ Packet client_hello() return handshake_packet(HANDSHAKE_client_hello, data); } +Packet finished_packet(string(0..255) sender) +{ + SSL3_DEBUG_MSG("Sending finished_packet, with sender=\""+sender+"\"\n" ); + // We're the client. + client_verify_data = hash_messages(sender); + return handshake_packet(HANDSHAKE_finished, client_verify_data); +} + protected void create(.context ctx) { ::create(ctx); - handshake_state = STATE_client_wait_for_hello; + handshake_state = STATE_wait_for_hello; handshake_messages = ""; session = context->new_session(); send_packet(client_hello()); @@ -202,7 +210,7 @@ int(-1..1) handle_handshake(int type, string(0..255) data, string(0..255) raw) { default: error( "Internal error\n" ); - case STATE_client_wait_for_hello: + case STATE_wait_for_hello: if(type != HANDSHAKE_server_hello) { send_packet(Alert(ALERT_fatal, ALERT_unexpected_message, @@ -265,7 +273,7 @@ int(-1..1) handle_handshake(int type, string(0..255) data, string(0..255) raw) return -1; } session->set_compression_method(compression_method); - SSL3_DEBUG_MSG("STATE_client_wait_for_hello: received hello\n" + SSL3_DEBUG_MSG("STATE_wait_for_hello: received hello\n" "version = %s\n" "id=%O\n" "cipher suite: %O\n" @@ -370,12 +378,12 @@ int(-1..1) handle_handshake(int type, string(0..255) data, string(0..255) raw) return -1; } - handshake_state = STATE_client_wait_for_server; + handshake_state = STATE_wait_for_peer; break; } break; - case STATE_client_wait_for_server: + case STATE_wait_for_peer: handshake_messages += raw; switch(type) { @@ -581,13 +589,13 @@ int(-1..1) handle_handshake(int type, string(0..255) data, string(0..255) raw) send_packet(heartbleed_packet()); } - handshake_state = STATE_client_wait_for_finish; + handshake_state = STATE_wait_for_finish; expect_change_cipher = 1; break; } break; - case STATE_client_wait_for_finish: + case STATE_wait_for_finish: { if((type) != HANDSHAKE_finished) { diff --git a/lib/modules/SSL.pmod/Connection.pike b/lib/modules/SSL.pmod/Connection.pike index 176706db7e..f8841db2b2 100644 --- a/lib/modules/SSL.pmod/Connection.pike +++ b/lib/modules/SSL.pmod/Connection.pike @@ -362,20 +362,6 @@ string(0..255) hash_messages(string(0..255) sender) } } -Packet finished_packet(string(0..255) sender) -{ - SSL3_DEBUG_MSG("Sending finished_packet, with sender=\""+sender+"\"\n" ); - string(0..255) verify_data = hash_messages(sender); - if (handshake_state >= STATE_client_min) { - // We're the client. - client_verify_data = verify_data; - } else { - // We're the server. - server_verify_data = verify_data; - } - return handshake_packet(HANDSHAKE_finished, verify_data); -} - Packet certificate_request_packet(SSL.context context) { /* Send a CertificateRequest message */ diff --git a/lib/modules/SSL.pmod/Constants.pmod b/lib/modules/SSL.pmod/Constants.pmod index ba93b524c5..53ed0c216d 100644 --- a/lib/modules/SSL.pmod/Constants.pmod +++ b/lib/modules/SSL.pmod/Constants.pmod @@ -101,15 +101,10 @@ constant PACKET_types = (< PACKET_change_cipher_spec, constant PACKET_MAX_SIZE = 0x4000; // 2^14. /* Handshake states */ -constant STATE_server_wait_for_hello = 1; -constant STATE_server_wait_for_client = 2; -constant STATE_server_wait_for_finish = 3; -constant STATE_server_wait_for_verify = 4; - -constant STATE_client_min = 10; -constant STATE_client_wait_for_hello = 10; -constant STATE_client_wait_for_server = 11; -constant STATE_client_wait_for_finish = 12; +constant STATE_wait_for_hello = 0; +constant STATE_wait_for_peer = 1; +constant STATE_wait_for_verify = 2; +constant STATE_wait_for_finish = 3; /* Cipher specification */ constant CIPHER_stream = 0; diff --git a/lib/modules/SSL.pmod/ServerConnection.pike b/lib/modules/SSL.pmod/ServerConnection.pike index 9476633027..8b3d9f79a8 100644 --- a/lib/modules/SSL.pmod/ServerConnection.pike +++ b/lib/modules/SSL.pmod/ServerConnection.pike @@ -18,10 +18,18 @@ Packet hello_request() return handshake_packet(HANDSHAKE_hello_request, ""); } +Packet finished_packet(string(0..255) sender) +{ + SSL3_DEBUG_MSG("Sending finished_packet, with sender=\""+sender+"\"\n" ); + // We're the server. + server_verify_data = hash_messages(sender); + return handshake_packet(HANDSHAKE_finished, server_verify_data); +} + protected void create(.context ctx) { ::create(ctx); - handshake_state = STATE_server_wait_for_hello; + handshake_state = STATE_wait_for_hello; } //! Do handshake processing. Type is one of HANDSHAKE_*, data is the @@ -48,7 +56,7 @@ int(-1..1) handle_handshake(int type, string(0..255) data, string(0..255) raw) { default: error( "Internal error\n" ); - case STATE_server_wait_for_hello: + case STATE_wait_for_hello: { array(int) cipher_suites; @@ -93,7 +101,7 @@ int(-1..1) handle_handshake(int type, string(0..255) data, string(0..255) raw) cipher_len = input->get_uint(2); cipher_suites = input->get_fix_uint_array(2, cipher_len/2); compression_methods = input->get_var_uint_array(1, 1); - SSL3_DEBUG_MSG("STATE_server_wait_for_hello: received hello\n" + SSL3_DEBUG_MSG("STATE_wait_for_hello: received hello\n" "version = %s\n" "id=%O\n" "cipher suites:\n%s\n" @@ -480,7 +488,7 @@ int(-1..1) handle_handshake(int type, string(0..255) data, string(0..255) raw) expect_change_cipher = 1; - handshake_state = STATE_server_wait_for_finish; + handshake_state = STATE_wait_for_finish; } else { /* New session, do full handshake. */ @@ -488,14 +496,14 @@ int(-1..1) handle_handshake(int type, string(0..255) data, string(0..255) raw) compression_methods); if (err) return err; - handshake_state = STATE_server_wait_for_client; + handshake_state = STATE_wait_for_peer; } break; } } break; } - case STATE_server_wait_for_finish: + case STATE_wait_for_finish: switch(type) { default: @@ -572,13 +580,13 @@ int(-1..1) handle_handshake(int type, string(0..255) data, string(0..255) raw) expect_change_cipher = 1; context->record_session(session); /* Cache this session */ } - handshake_state = STATE_server_wait_for_hello; + handshake_state = STATE_wait_for_hello; return 1; } } break; - case STATE_server_wait_for_client: + case STATE_wait_for_peer: // NB: ALERT_no_certificate can be valid in this state, and // is handled directly by connection:handle_alert(). handshake_messages += raw; @@ -615,11 +623,11 @@ int(-1..1) handle_handshake(int type, string(0..255) data, string(0..255) raw) // TODO: we need to determine whether the certificate has signing abilities. if (certificate_state == CERT_received) { - handshake_state = STATE_server_wait_for_verify; + handshake_state = STATE_wait_for_verify; } else { - handshake_state = STATE_server_wait_for_finish; + handshake_state = STATE_wait_for_finish; expect_change_cipher = 1; } @@ -673,7 +681,7 @@ int(-1..1) handle_handshake(int type, string(0..255) data, string(0..255) raw) } } break; - case STATE_server_wait_for_verify: + case STATE_wait_for_verify: // compute challenge first, then update handshake_messages /Sigge switch(type) { @@ -707,7 +715,7 @@ int(-1..1) handle_handshake(int type, string(0..255) data, string(0..255) raw) } } handshake_messages += raw; - handshake_state = STATE_server_wait_for_finish; + handshake_state = STATE_wait_for_finish; expect_change_cipher = 1; break; } -- GitLab