diff options
author | lloyd <[email protected]> | 2012-06-09 07:14:36 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-06-09 07:14:36 +0000 |
commit | 55538ea412ef728f04ca4d86ec6b34360f7bb92c (patch) | |
tree | fe3a934f8e66642b67120cc022b8776c363f112a /src/tls | |
parent | 6af7a5414fde971efd767f3e881a16acdda6f497 (diff) |
m_ namespace Channel, Client, and Server.
Fix printing of Camellia ciphersuites.
Diffstat (limited to 'src/tls')
-rw-r--r-- | src/tls/tls_channel.cpp | 82 | ||||
-rw-r--r-- | src/tls/tls_channel.h | 24 | ||||
-rw-r--r-- | src/tls/tls_ciphersuite.cpp | 2 | ||||
-rw-r--r-- | src/tls/tls_client.cpp | 354 | ||||
-rw-r--r-- | src/tls/tls_client.h | 8 | ||||
-rw-r--r-- | src/tls/tls_server.cpp | 286 |
6 files changed, 378 insertions, 378 deletions
diff --git a/src/tls/tls_channel.cpp b/src/tls/tls_channel.cpp index e7313b709..c06bd3e3a 100644 --- a/src/tls/tls_channel.cpp +++ b/src/tls/tls_channel.cpp @@ -19,12 +19,12 @@ namespace TLS { Channel::Channel(std::function<void (const byte[], size_t)> socket_output_fn, std::function<void (const byte[], size_t, Alert)> proc_fn, std::function<bool (const Session&)> handshake_complete) : - proc_fn(proc_fn), - handshake_fn(handshake_complete), - writer(socket_output_fn), - state(nullptr), - handshake_completed(false), - connection_closed(false), + m_proc_fn(proc_fn), + m_handshake_fn(handshake_complete), + m_writer(socket_output_fn), + m_state(nullptr), + m_handshake_completed(false), + m_connection_closed(false), m_peer_supports_heartbeats(false), m_heartbeat_sending_allowed(false) { @@ -32,8 +32,8 @@ Channel::Channel(std::function<void (const byte[], size_t)> socket_output_fn, Channel::~Channel() { - delete state; - state = nullptr; + delete m_state; + m_state = nullptr; } size_t Channel::received_data(const byte buf[], size_t buf_size) @@ -46,9 +46,9 @@ size_t Channel::received_data(const byte buf[], size_t buf_size) std::vector<byte> record; size_t consumed = 0; - const size_t needed = reader.add_input(buf, buf_size, - consumed, - rec_type, record); + const size_t needed = m_reader.add_input(buf, buf_size, + consumed, + rec_type, record); BOTAN_ASSERT(consumed <= buf_size, "Record reader consumed sane amount"); @@ -72,22 +72,22 @@ size_t Channel::received_data(const byte buf[], size_t buf_size) const std::vector<byte>& payload = heartbeat.payload(); - if(heartbeat.is_request() && !state) + if(heartbeat.is_request() && !m_state) { Heartbeat_Message response(Heartbeat_Message::RESPONSE, &payload[0], payload.size()); - writer.send(HEARTBEAT, response.contents()); + m_writer.send(HEARTBEAT, response.contents()); } else { // pass up to the application - proc_fn(&payload[0], payload.size(), Alert(Alert::HEARTBEAT_PAYLOAD)); + m_proc_fn(&payload[0], payload.size(), Alert(Alert::HEARTBEAT_PAYLOAD)); } } else if(rec_type == APPLICATION_DATA) { - if(handshake_completed) + if(m_handshake_completed) { /* * OpenSSL among others sends empty records in versions @@ -95,7 +95,7 @@ size_t Channel::received_data(const byte buf[], size_t buf_size) * following record. Avoid spurious callbacks. */ if(record.size() > 0) - proc_fn(&record[0], record.size(), Alert()); + m_proc_fn(&record[0], record.size(), Alert()); } else { @@ -108,25 +108,25 @@ size_t Channel::received_data(const byte buf[], size_t buf_size) alert_notify(alert_msg); - proc_fn(nullptr, 0, alert_msg); + m_proc_fn(nullptr, 0, alert_msg); if(alert_msg.type() == Alert::CLOSE_NOTIFY) { - if(connection_closed) - reader.reset(); + if(m_connection_closed) + m_reader.reset(); else send_alert(Alert(Alert::CLOSE_NOTIFY)); // reply in kind } else if(alert_msg.is_fatal()) { // delete state immediately - connection_closed = true; + m_connection_closed = true; - delete state; - state = nullptr; + delete m_state; + m_state = nullptr; - writer.reset(); - reader.reset(); + m_writer.reset(); + m_reader.reset(); } } else @@ -166,12 +166,12 @@ void Channel::read_handshake(byte rec_type, { if(rec_type == HANDSHAKE) { - if(!state) - state = new Handshake_State(new Stream_Handshake_Reader); - state->handshake_reader()->add_input(&rec_buf[0], rec_buf.size()); + if(!m_state) + m_state = new Handshake_State(new Stream_Handshake_Reader); + m_state->handshake_reader()->add_input(&rec_buf[0], rec_buf.size()); } - BOTAN_ASSERT(state, "Handshake message recieved without state in place"); + BOTAN_ASSERT(m_state, "Handshake message recieved without state in place"); while(true) { @@ -179,10 +179,10 @@ void Channel::read_handshake(byte rec_type, if(rec_type == HANDSHAKE) { - if(state->handshake_reader()->have_full_record()) + if(m_state->handshake_reader()->have_full_record()) { std::pair<Handshake_Type, std::vector<byte> > msg = - state->handshake_reader()->get_next_record(); + m_state->handshake_reader()->get_next_record(); process_handshake_msg(msg.first, msg.second); } else @@ -190,7 +190,7 @@ void Channel::read_handshake(byte rec_type, } else if(rec_type == CHANGE_CIPHER_SPEC) { - if(state->handshake_reader()->empty() && rec_buf.size() == 1 && rec_buf[0] == 1) + if(m_state->handshake_reader()->empty() && rec_buf.size() == 1 && rec_buf[0] == 1) process_handshake_msg(HANDSHAKE_CCS, std::vector<byte>()); else throw Decoding_Error("Malformed ChangeCipherSpec message"); @@ -198,7 +198,7 @@ void Channel::read_handshake(byte rec_type, else throw Decoding_Error("Unknown message type in handshake processing"); - if(type == HANDSHAKE_CCS || !state || !state->handshake_reader()->have_full_record()) + if(type == HANDSHAKE_CCS || !m_state || !m_state->handshake_reader()->have_full_record()) break; } } @@ -213,7 +213,7 @@ void Channel::heartbeat(const byte payload[], size_t payload_size) Heartbeat_Message heartbeat(Heartbeat_Message::REQUEST, payload, payload_size); - writer.send(HEARTBEAT, heartbeat.contents()); + m_writer.send(HEARTBEAT, heartbeat.contents()); } } @@ -222,28 +222,28 @@ void Channel::send(const byte buf[], size_t buf_size) if(!is_active()) throw std::runtime_error("Data cannot be sent on inactive TLS connection"); - writer.send(APPLICATION_DATA, buf, buf_size); + m_writer.send(APPLICATION_DATA, buf, buf_size); } void Channel::send_alert(const Alert& alert) { - if(alert.is_valid() && !connection_closed) + if(alert.is_valid() && !m_connection_closed) { try { - writer.send_alert(alert); + m_writer.send_alert(alert); } catch(...) { /* swallow it */ } } - if(!connection_closed && (alert.type() == Alert::CLOSE_NOTIFY || alert.is_fatal())) + if(!m_connection_closed && (alert.type() == Alert::CLOSE_NOTIFY || alert.is_fatal())) { - connection_closed = true; + m_connection_closed = true; - delete state; - state = nullptr; + delete m_state; + m_state = nullptr; - writer.reset(); + m_writer.reset(); } } diff --git a/src/tls/tls_channel.h b/src/tls/tls_channel.h index 110509d1c..ca4247c85 100644 --- a/src/tls/tls_channel.h +++ b/src/tls/tls_channel.h @@ -45,12 +45,12 @@ class BOTAN_DLL Channel /** * @return true iff the connection is active for sending application data */ - bool is_active() const { return handshake_completed && !is_closed(); } + bool is_active() const { return m_handshake_completed && !is_closed(); } /** * @return true iff the connection has been definitely closed */ - bool is_closed() const { return connection_closed; } + bool is_closed() const { return m_connection_closed; } /** * Attempt to renegotiate the session @@ -74,7 +74,7 @@ class BOTAN_DLL Channel /** * @return certificate chain of the peer (may be empty) */ - std::vector<X509_Certificate> peer_cert_chain() const { return peer_certs; } + std::vector<X509_Certificate> peer_cert_chain() const { return m_peer_certs; } Channel(std::function<void (const byte[], size_t)> socket_output_fn, std::function<void (const byte[], size_t, Alert)> proc_fn, @@ -99,15 +99,15 @@ class BOTAN_DLL Channel virtual void alert_notify(const Alert& alert) = 0; - std::function<void (const byte[], size_t, Alert)> proc_fn; - std::function<bool (const Session&)> handshake_fn; + std::function<void (const byte[], size_t, Alert)> m_proc_fn; + std::function<bool (const Session&)> m_handshake_fn; - Record_Writer writer; - Record_Reader reader; + Record_Writer m_writer; + Record_Reader m_reader; - std::vector<X509_Certificate> peer_certs; + std::vector<X509_Certificate> m_peer_certs; - class Handshake_State* state; + class Handshake_State* m_state; class Secure_Renegotiation_State { @@ -142,10 +142,10 @@ class BOTAN_DLL Channel std::vector<byte> m_client_verify, m_server_verify; }; - Secure_Renegotiation_State secure_renegotiation; + Secure_Renegotiation_State m_secure_renegotiation; - bool handshake_completed; - bool connection_closed; + bool m_handshake_completed; + bool m_connection_closed; bool m_peer_supports_heartbeats; bool m_heartbeat_sending_allowed; }; diff --git a/src/tls/tls_ciphersuite.cpp b/src/tls/tls_ciphersuite.cpp index e3bda06e4..5c92e1eba 100644 --- a/src/tls/tls_ciphersuite.cpp +++ b/src/tls/tls_ciphersuite.cpp @@ -78,7 +78,7 @@ std::string Ciphersuite::to_string() const { if(cipher_algo() == "3DES") out << "3DES_EDE"; - else if(cipher_algo() == "Camellia") + else if(cipher_algo() == "Camellia-128" || cipher_algo() == "Camellia-256") out << "CAMELLIA_" << std::to_string(8*cipher_keylen()); else out << replace_char(cipher_algo(), '-', '_'); diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp index ec3d9953f..1a515b1f6 100644 --- a/src/tls/tls_client.cpp +++ b/src/tls/tls_client.cpp @@ -28,59 +28,59 @@ Client::Client(std::function<void (const byte[], size_t)> output_fn, const std::string& hostname, std::function<std::string (std::vector<std::string>)> next_protocol) : Channel(output_fn, proc_fn, handshake_fn), - policy(policy), - rng(rng), - session_manager(session_manager), - creds(creds), + m_policy(policy), + m_rng(rng), + m_session_manager(session_manager), + m_creds(creds), m_hostname(hostname) { - writer.set_version(Protocol_Version::SSL_V3); + m_writer.set_version(Protocol_Version::SSL_V3); - state = new Handshake_State(new Stream_Handshake_Reader); - state->set_expected_next(SERVER_HELLO); + m_state = new Handshake_State(new Stream_Handshake_Reader); + m_state->set_expected_next(SERVER_HELLO); - state->client_npn_cb = next_protocol; + m_state->client_npn_cb = next_protocol; - const std::string srp_identifier = creds.srp_identifier("tls-client", hostname); + const std::string srp_identifier = m_creds.srp_identifier("tls-client", hostname); const bool send_npn_request = static_cast<bool>(next_protocol); if(hostname != "") { Session session_info; - if(session_manager.load_from_host_info(hostname, 0, session_info)) + if(m_session_manager.load_from_host_info(m_hostname, 0, session_info)) { if(session_info.srp_identifier() == srp_identifier) { - state->client_hello = new Client_Hello( - writer, - state->hash, - policy, - rng, - secure_renegotiation.for_client_hello(), + m_state->client_hello = new Client_Hello( + m_writer, + m_state->hash, + m_policy, + m_rng, + m_secure_renegotiation.for_client_hello(), session_info, send_npn_request); - state->resume_master_secret = session_info.master_secret(); + m_state->resume_master_secret = session_info.master_secret(); } } } - if(!state->client_hello) // not resuming + if(!m_state->client_hello) // not resuming { - state->client_hello = new Client_Hello( - writer, - state->hash, - policy.pref_version(), - policy, - rng, - secure_renegotiation.for_client_hello(), + m_state->client_hello = new Client_Hello( + m_writer, + m_state->hash, + m_policy.pref_version(), + m_policy, + m_rng, + m_secure_renegotiation.for_client_hello(), send_npn_request, - hostname, + m_hostname, srp_identifier); } - secure_renegotiation.update(state->client_hello); + m_secure_renegotiation.update(m_state->client_hello); } /* @@ -88,53 +88,53 @@ Client::Client(std::function<void (const byte[], size_t)> output_fn, */ void Client::renegotiate(bool force_full_renegotiation) { - if(state && state->client_hello) + if(m_state && m_state->client_hello) return; // currently in active handshake - delete state; - state = new Handshake_State(new Stream_Handshake_Reader); + delete m_state; + m_state = new Handshake_State(new Stream_Handshake_Reader); - state->set_expected_next(SERVER_HELLO); + m_state->set_expected_next(SERVER_HELLO); if(!force_full_renegotiation) { Session session_info; - if(session_manager.load_from_host_info(m_hostname, 0, session_info)) + if(m_session_manager.load_from_host_info(m_hostname, 0, session_info)) { - state->client_hello = new Client_Hello( - writer, - state->hash, - policy, - rng, - secure_renegotiation.for_client_hello(), + m_state->client_hello = new Client_Hello( + m_writer, + m_state->hash, + m_policy, + m_rng, + m_secure_renegotiation.for_client_hello(), session_info); - state->resume_master_secret = session_info.master_secret(); + m_state->resume_master_secret = session_info.master_secret(); } } - if(!state->client_hello) + if(!m_state->client_hello) { - state->client_hello = new Client_Hello( - writer, - state->hash, - reader.get_version(), - policy, - rng, - secure_renegotiation.for_client_hello()); + m_state->client_hello = new Client_Hello( + m_writer, + m_state->hash, + m_reader.get_version(), + m_policy, + m_rng, + m_secure_renegotiation.for_client_hello()); } - secure_renegotiation.update(state->client_hello); + m_secure_renegotiation.update(m_state->client_hello); } void Client::alert_notify(const Alert& alert) { if(alert.type() == Alert::NO_RENEGOTIATION) { - if(handshake_completed && state) + if(m_handshake_completed && m_state) { - delete state; - state = nullptr; + delete m_state; + m_state = nullptr; } } } @@ -145,7 +145,7 @@ void Client::alert_notify(const Alert& alert) void Client::process_handshake_msg(Handshake_Type type, const std::vector<byte>& contents) { - if(!state) + if(!m_state) throw Unexpected_Message("Unexpected handshake message from server"); if(type == HELLO_REQUEST) @@ -153,13 +153,13 @@ void Client::process_handshake_msg(Handshake_Type type, Hello_Request hello_request(contents); // Ignore request entirely if we are currently negotiating a handshake - if(state->client_hello) + if(m_state->client_hello) return; - if(!secure_renegotiation.supported() && !policy.allow_insecure_renegotiation()) + if(!m_secure_renegotiation.supported() && !m_policy.allow_insecure_renegotiation()) { - delete state; - state = nullptr; + delete m_state; + m_state = nullptr; // RFC 5746 section 4.2 send_alert(Alert(Alert::NO_RENEGOTIATION)); @@ -171,57 +171,57 @@ void Client::process_handshake_msg(Handshake_Type type, return; } - state->confirm_transition_to(type); + m_state->confirm_transition_to(type); if(type != HANDSHAKE_CCS && type != FINISHED) - state->hash.update(type, contents); + m_state->hash.update(type, contents); if(type == SERVER_HELLO) { - state->server_hello = new Server_Hello(contents); + m_state->server_hello = new Server_Hello(contents); - if(!state->client_hello->offered_suite(state->server_hello->ciphersuite())) + if(!m_state->client_hello->offered_suite(m_state->server_hello->ciphersuite())) { throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Server replied with ciphersuite we didn't send"); } - if(!value_exists(state->client_hello->compression_methods(), - state->server_hello->compression_method())) + if(!value_exists(m_state->client_hello->compression_methods(), + m_state->server_hello->compression_method())) { throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Server replied with compression method we didn't send"); } - if(!state->client_hello->next_protocol_notification() && - state->server_hello->next_protocol_notification()) + if(!m_state->client_hello->next_protocol_notification() && + m_state->server_hello->next_protocol_notification()) { throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Server sent next protocol but we didn't request it"); } - if(state->server_hello->supports_session_ticket()) + if(m_state->server_hello->supports_session_ticket()) { - if(!state->client_hello->supports_session_ticket()) + if(!m_state->client_hello->supports_session_ticket()) throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Server sent session ticket extension but we did not"); } - state->set_version(state->server_hello->version()); + m_state->set_version(m_state->server_hello->version()); - writer.set_version(state->version()); - reader.set_version(state->version()); + m_writer.set_version(m_state->version()); + m_reader.set_version(m_state->version()); - secure_renegotiation.update(state->server_hello); + m_secure_renegotiation.update(m_state->server_hello); - m_peer_supports_heartbeats = state->server_hello->supports_heartbeats(); - m_heartbeat_sending_allowed = state->server_hello->peer_can_send_heartbeats(); + m_peer_supports_heartbeats = m_state->server_hello->supports_heartbeats(); + m_heartbeat_sending_allowed = m_state->server_hello->peer_can_send_heartbeats(); - state->suite = Ciphersuite::by_id(state->server_hello->ciphersuite()); + m_state->suite = Ciphersuite::by_id(m_state->server_hello->ciphersuite()); const bool server_returned_same_session_id = - !state->server_hello->session_id().empty() && - (state->server_hello->session_id() == state->client_hello->session_id()); + !m_state->server_hello->session_id().empty() && + (m_state->server_hello->session_id() == m_state->client_hello->session_id()); if(server_returned_same_session_id) { @@ -231,41 +231,41 @@ void Client::process_handshake_msg(Handshake_Type type, * In this case, we offered the version used in the original * session, and the server must resume with the same version. */ - if(state->server_hello->version() != state->client_hello->version()) + if(m_state->server_hello->version() != m_state->client_hello->version()) throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Server resumed session but with wrong version"); - state->keys = Session_Keys(state, - state->resume_master_secret, + m_state->keys = Session_Keys(m_state, + m_state->resume_master_secret, true); // The server is not strictly required to send us a new ticket - if(state->server_hello->supports_session_ticket()) - state->set_expected_next(NEW_SESSION_TICKET); + if(m_state->server_hello->supports_session_ticket()) + m_state->set_expected_next(NEW_SESSION_TICKET); - state->set_expected_next(HANDSHAKE_CCS); + m_state->set_expected_next(HANDSHAKE_CCS); } else { // new session - if(state->version() > state->client_hello->version()) + if(m_state->version() > m_state->client_hello->version()) { throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Client: Server replied with bad version"); } - if(state->version() < policy.min_version()) + if(m_state->version() < m_policy.min_version()) { throw TLS_Exception(Alert::PROTOCOL_VERSION, "Client: Server is too old for specified policy"); } - if(state->suite.sig_algo() != "") + if(m_state->suite.sig_algo() != "") { - state->set_expected_next(CERTIFICATE); + m_state->set_expected_next(CERTIFICATE); } - else if(state->suite.kex_algo() == "PSK") + else if(m_state->suite.kex_algo() == "PSK") { /* PSK is anonymous so no certificate/cert req message is ever sent. The server may or may not send a server kex, @@ -275,67 +275,67 @@ void Client::process_handshake_msg(Handshake_Type type, DH exchange portion. */ - state->set_expected_next(SERVER_KEX); - state->set_expected_next(SERVER_HELLO_DONE); + m_state->set_expected_next(SERVER_KEX); + m_state->set_expected_next(SERVER_HELLO_DONE); } - else if(state->suite.kex_algo() != "RSA") + else if(m_state->suite.kex_algo() != "RSA") { - state->set_expected_next(SERVER_KEX); + m_state->set_expected_next(SERVER_KEX); } else { - state->set_expected_next(CERTIFICATE_REQUEST); // optional - state->set_expected_next(SERVER_HELLO_DONE); + m_state->set_expected_next(CERTIFICATE_REQUEST); // optional + m_state->set_expected_next(SERVER_HELLO_DONE); } } } else if(type == CERTIFICATE) { - if(state->suite.kex_algo() != "RSA") + if(m_state->suite.kex_algo() != "RSA") { - state->set_expected_next(SERVER_KEX); + m_state->set_expected_next(SERVER_KEX); } else { - state->set_expected_next(CERTIFICATE_REQUEST); // optional - state->set_expected_next(SERVER_HELLO_DONE); + m_state->set_expected_next(CERTIFICATE_REQUEST); // optional + m_state->set_expected_next(SERVER_HELLO_DONE); } - state->server_certs = new Certificate(contents); + m_state->server_certs = new Certificate(contents); - peer_certs = state->server_certs->cert_chain(); - if(peer_certs.size() == 0) + m_peer_certs = m_state->server_certs->cert_chain(); + if(m_peer_certs.empty()) throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Client: No certificates sent by server"); try { - creds.verify_certificate_chain("tls-client", m_hostname, peer_certs); + m_creds.verify_certificate_chain("tls-client", m_hostname, m_peer_certs); } catch(std::exception& e) { throw TLS_Exception(Alert::BAD_CERTIFICATE, e.what()); } - std::unique_ptr<Public_Key> peer_key(peer_certs[0].subject_public_key()); + std::unique_ptr<Public_Key> peer_key(m_peer_certs[0].subject_public_key()); - if(peer_key->algo_name() != state->suite.sig_algo()) + if(peer_key->algo_name() != m_state->suite.sig_algo()) throw TLS_Exception(Alert::ILLEGAL_PARAMETER, "Certificate key type did not match ciphersuite"); } else if(type == SERVER_KEX) { - state->set_expected_next(CERTIFICATE_REQUEST); // optional - state->set_expected_next(SERVER_HELLO_DONE); + m_state->set_expected_next(CERTIFICATE_REQUEST); // optional + m_state->set_expected_next(SERVER_HELLO_DONE); - state->server_kex = new Server_Key_Exchange(contents, - state->suite.kex_algo(), - state->suite.sig_algo(), - state->version()); + m_state->server_kex = new Server_Key_Exchange(contents, + m_state->suite.kex_algo(), + m_state->suite.sig_algo(), + m_state->version()); - if(state->suite.sig_algo() != "") + if(m_state->suite.sig_algo() != "") { - if(!state->server_kex->verify(peer_certs[0], state)) + if(!m_state->server_kex->verify(m_peer_certs[0], m_state)) { throw TLS_Exception(Alert::DECRYPT_ERROR, "Bad signature on server key exchange"); @@ -344,141 +344,141 @@ void Client::process_handshake_msg(Handshake_Type type, } else if(type == CERTIFICATE_REQUEST) { - state->set_expected_next(SERVER_HELLO_DONE); - state->cert_req = new Certificate_Req(contents, state->version()); + m_state->set_expected_next(SERVER_HELLO_DONE); + m_state->cert_req = new Certificate_Req(contents, m_state->version()); } else if(type == SERVER_HELLO_DONE) { - state->server_hello_done = new Server_Hello_Done(contents); + m_state->server_hello_done = new Server_Hello_Done(contents); - if(state->received_handshake_msg(CERTIFICATE_REQUEST)) + if(m_state->received_handshake_msg(CERTIFICATE_REQUEST)) { const std::vector<std::string>& types = - state->cert_req->acceptable_cert_types(); + m_state->cert_req->acceptable_cert_types(); std::vector<X509_Certificate> client_certs = - creds.cert_chain(types, - "tls-client", - m_hostname); + m_creds.cert_chain(types, + "tls-client", + m_hostname); - state->client_certs = new Certificate(writer, - state->hash, + m_state->client_certs = new Certificate(m_writer, + m_state->hash, client_certs); } - state->client_kex = - new Client_Key_Exchange(writer, - state, - creds, - peer_certs, + m_state->client_kex = + new Client_Key_Exchange(m_writer, + m_state, + m_creds, + m_peer_certs, m_hostname, - rng); + m_rng); - state->keys = Session_Keys(state, - state->client_kex->pre_master_secret(), + m_state->keys = Session_Keys(m_state, + m_state->client_kex->pre_master_secret(), false); - if(state->received_handshake_msg(CERTIFICATE_REQUEST) && - !state->client_certs->empty()) + if(m_state->received_handshake_msg(CERTIFICATE_REQUEST) && + !m_state->client_certs->empty()) { Private_Key* private_key = - creds.private_key_for(state->client_certs->cert_chain()[0], - "tls-client", - m_hostname); + m_creds.private_key_for(m_state->client_certs->cert_chain()[0], + "tls-client", + m_hostname); - state->client_verify = new Certificate_Verify(writer, - state, - rng, + m_state->client_verify = new Certificate_Verify(m_writer, + m_state, + m_rng, private_key); } - writer.send(CHANGE_CIPHER_SPEC, 1); + m_writer.send(CHANGE_CIPHER_SPEC, 1); - writer.activate(CLIENT, state->suite, state->keys, - state->server_hello->compression_method()); + m_writer.activate(CLIENT, m_state->suite, m_state->keys, + m_state->server_hello->compression_method()); - if(state->server_hello->next_protocol_notification()) + if(m_state->server_hello->next_protocol_notification()) { const std::string protocol = - state->client_npn_cb(state->server_hello->next_protocols()); + m_state->client_npn_cb(m_state->server_hello->next_protocols()); - state->next_protocol = new Next_Protocol(writer, state->hash, protocol); + m_state->next_protocol = new Next_Protocol(m_writer, m_state->hash, protocol); } - state->client_finished = new Finished(writer, state, CLIENT); + m_state->client_finished = new Finished(m_writer, m_state, CLIENT); - if(state->server_hello->supports_session_ticket()) - state->set_expected_next(NEW_SESSION_TICKET); + if(m_state->server_hello->supports_session_ticket()) + m_state->set_expected_next(NEW_SESSION_TICKET); else - state->set_expected_next(HANDSHAKE_CCS); + m_state->set_expected_next(HANDSHAKE_CCS); } else if(type == NEW_SESSION_TICKET) { - state->new_session_ticket = new New_Session_Ticket(contents); + m_state->new_session_ticket = new New_Session_Ticket(contents); - state->set_expected_next(HANDSHAKE_CCS); + m_state->set_expected_next(HANDSHAKE_CCS); } else if(type == HANDSHAKE_CCS) { - state->set_expected_next(FINISHED); + m_state->set_expected_next(FINISHED); - reader.activate(CLIENT, state->suite, state->keys, - state->server_hello->compression_method()); + m_reader.activate(CLIENT, m_state->suite, m_state->keys, + m_state->server_hello->compression_method()); } else if(type == FINISHED) { - state->set_expected_next(HELLO_REQUEST); + m_state->set_expected_next(HELLO_REQUEST); - state->server_finished = new Finished(contents); + m_state->server_finished = new Finished(contents); - if(!state->server_finished->verify(state, SERVER)) + if(!m_state->server_finished->verify(m_state, SERVER)) throw TLS_Exception(Alert::DECRYPT_ERROR, "Finished message didn't verify"); - state->hash.update(type, contents); + m_state->hash.update(type, contents); - if(!state->client_finished) // session resume case + if(!m_state->client_finished) // session resume case { - writer.send(CHANGE_CIPHER_SPEC, 1); + m_writer.send(CHANGE_CIPHER_SPEC, 1); - writer.activate(CLIENT, state->suite, state->keys, - state->server_hello->compression_method()); + m_writer.activate(CLIENT, m_state->suite, m_state->keys, + m_state->server_hello->compression_method()); - state->client_finished = new Finished(writer, state, CLIENT); + m_state->client_finished = new Finished(m_writer, m_state, CLIENT); } - secure_renegotiation.update(state->client_finished, state->server_finished); + m_secure_renegotiation.update(m_state->client_finished, m_state->server_finished); - std::vector<byte> session_id = state->server_hello->session_id(); + std::vector<byte> session_id = m_state->server_hello->session_id(); - const std::vector<byte>& session_ticket = state->session_ticket(); + const std::vector<byte>& session_ticket = m_state->session_ticket(); if(session_id.empty() && !session_ticket.empty()) - session_id = make_hello_random(rng); + session_id = make_hello_random(m_rng); Session session_info( session_id, - state->keys.master_secret(), - state->server_hello->version(), - state->server_hello->ciphersuite(), - state->server_hello->compression_method(), + m_state->keys.master_secret(), + m_state->server_hello->version(), + m_state->server_hello->ciphersuite(), + m_state->server_hello->compression_method(), CLIENT, - secure_renegotiation.supported(), - state->server_hello->fragment_size(), - peer_certs, + m_secure_renegotiation.supported(), + m_state->server_hello->fragment_size(), + m_peer_certs, session_ticket, m_hostname, "" ); - if(handshake_fn(session_info)) - session_manager.save(session_info); + if(m_handshake_fn(session_info)) + m_session_manager.save(session_info); else - session_manager.remove_entry(session_info.session_id()); + m_session_manager.remove_entry(session_info.session_id()); - delete state; - state = nullptr; - handshake_completed = true; + delete m_state; + m_state = nullptr; + m_handshake_completed = true; } else throw Unexpected_Message("Unknown handshake message received"); diff --git a/src/tls/tls_client.h b/src/tls/tls_client.h index 2844780bd..7e38465af 100644 --- a/src/tls/tls_client.h +++ b/src/tls/tls_client.h @@ -60,10 +60,10 @@ class BOTAN_DLL Client : public Channel void alert_notify(const Alert& alert); - const Policy& policy; - RandomNumberGenerator& rng; - Session_Manager& session_manager; - Credentials_Manager& creds; + const Policy& m_policy; + RandomNumberGenerator& m_rng; + Session_Manager& m_session_manager; + Credentials_Manager& m_creds; const std::string m_hostname; }; diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp index 204affb16..e412c97ab 100644 --- a/src/tls/tls_server.cpp +++ b/src/tls/tls_server.cpp @@ -206,24 +206,24 @@ Server::Server(std::function<void (const byte[], size_t)> output_fn, */ void Server::renegotiate(bool force_full_renegotiation) { - if(state) + if(m_state) return; // currently in handshake - state = new Handshake_State(new Stream_Handshake_Reader); + m_state = new Handshake_State(new Stream_Handshake_Reader); - state->allow_session_resumption = !force_full_renegotiation; - state->set_expected_next(CLIENT_HELLO); - Hello_Request hello_req(writer); + m_state->allow_session_resumption = !force_full_renegotiation; + m_state->set_expected_next(CLIENT_HELLO); + Hello_Request hello_req(m_writer); } void Server::alert_notify(const Alert& alert) { if(alert.type() == Alert::NO_RENEGOTIATION) { - if(handshake_completed && state) + if(m_handshake_completed && m_state) { - delete state; - state = nullptr; + delete m_state; + m_state = nullptr; } } } @@ -234,10 +234,10 @@ void Server::alert_notify(const Alert& alert) void Server::read_handshake(byte rec_type, const std::vector<byte>& rec_buf) { - if(rec_type == HANDSHAKE && !state) + if(rec_type == HANDSHAKE && !m_state) { - state = new Handshake_State(new Stream_Handshake_Reader); - state->set_expected_next(CLIENT_HELLO); + m_state = new Handshake_State(new Stream_Handshake_Reader); + m_state->set_expected_next(CLIENT_HELLO); } Channel::read_handshake(rec_type, rec_buf); @@ -249,10 +249,10 @@ void Server::read_handshake(byte rec_type, void Server::process_handshake_msg(Handshake_Type type, const std::vector<byte>& contents) { - if(!state) + if(!m_state) throw Unexpected_Message("Unexpected handshake message from client"); - state->confirm_transition_to(type); + m_state->confirm_transition_to(type); /* * The change cipher spec message isn't technically a handshake @@ -264,19 +264,19 @@ void Server::process_handshake_msg(Handshake_Type type, if(type != HANDSHAKE_CCS && type != FINISHED && type != CERTIFICATE_VERIFY) { if(type == CLIENT_HELLO_SSLV2) - state->hash.update(contents); + m_state->hash.update(contents); else - state->hash.update(type, contents); + m_state->hash.update(type, contents); } if(type == CLIENT_HELLO || type == CLIENT_HELLO_SSLV2) { - state->client_hello = new Client_Hello(contents, type); + m_state->client_hello = new Client_Hello(contents, type); - if(state->client_hello->sni_hostname() != "") - m_hostname = state->client_hello->sni_hostname(); + if(m_state->client_hello->sni_hostname() != "") + m_hostname = m_state->client_hello->sni_hostname(); - Protocol_Version client_version = state->client_hello->version(); + Protocol_Version client_version = m_state->client_hello->version(); if(client_version < policy.min_version()) throw TLS_Exception(Alert::PROTOCOL_VERSION, @@ -284,11 +284,11 @@ void Server::process_handshake_msg(Handshake_Type type, if(client_version > policy.pref_version()) { - state->set_version(policy.pref_version()); + m_state->set_version(policy.pref_version()); } else { - Protocol_Version prev_version = reader.get_version(); + Protocol_Version prev_version = m_reader.get_version(); if(prev_version.valid() && client_version != prev_version) { @@ -302,7 +302,7 @@ void Server::process_handshake_msg(Handshake_Type type, */ if(client_version > prev_version) { - state->set_version(prev_version); + m_state->set_version(prev_version); } else { @@ -315,34 +315,34 @@ void Server::process_handshake_msg(Handshake_Type type, } else { - state->set_version(client_version); + m_state->set_version(client_version); } } if(!policy.allow_insecure_renegotiation() && - !(secure_renegotiation.initial_handshake() || secure_renegotiation.supported())) + !(m_secure_renegotiation.initial_handshake() || m_secure_renegotiation.supported())) { - delete state; - state = nullptr; + delete m_state; + m_state = nullptr; send_alert(Alert(Alert::NO_RENEGOTIATION)); return; } - secure_renegotiation.update(state->client_hello); + m_secure_renegotiation.update(m_state->client_hello); - m_peer_supports_heartbeats = state->client_hello->supports_heartbeats(); - m_heartbeat_sending_allowed = state->client_hello->peer_can_send_heartbeats(); + m_peer_supports_heartbeats = m_state->client_hello->supports_heartbeats(); + m_heartbeat_sending_allowed = m_state->client_hello->peer_can_send_heartbeats(); - writer.set_version(state->version()); - reader.set_version(state->version()); + m_writer.set_version(m_state->version()); + m_reader.set_version(m_state->version()); Session session_info; const bool resuming = - state->allow_session_resumption && + m_state->allow_session_resumption && check_for_resume(session_info, session_manager, creds, - state->client_hello, + m_state->client_hello, std::chrono::seconds(policy.session_ticket_lifetime())); bool have_session_ticket_key = false; @@ -358,69 +358,69 @@ void Server::process_handshake_msg(Handshake_Type type, { // resume session - state->server_hello = new Server_Hello( - writer, - state->hash, - state->client_hello->session_id(), + m_state->server_hello = new Server_Hello( + m_writer, + m_state->hash, + m_state->client_hello->session_id(), Protocol_Version(session_info.version()), session_info.ciphersuite_code(), session_info.compression_method(), session_info.fragment_size(), - secure_renegotiation.supported(), - secure_renegotiation.for_server_hello(), - (state->client_hello->supports_session_ticket() && - state->client_hello->session_ticket().empty() && + m_secure_renegotiation.supported(), + m_secure_renegotiation.for_server_hello(), + (m_state->client_hello->supports_session_ticket() && + m_state->client_hello->session_ticket().empty() && have_session_ticket_key), - state->client_hello->next_protocol_notification(), + m_state->client_hello->next_protocol_notification(), m_possible_protocols, - state->client_hello->supports_heartbeats(), + m_state->client_hello->supports_heartbeats(), rng); - secure_renegotiation.update(state->server_hello); + m_secure_renegotiation.update(m_state->server_hello); if(session_info.fragment_size()) { - reader.set_maximum_fragment_size(session_info.fragment_size()); - writer.set_maximum_fragment_size(session_info.fragment_size()); + m_reader.set_maximum_fragment_size(session_info.fragment_size()); + m_writer.set_maximum_fragment_size(session_info.fragment_size()); } - state->suite = Ciphersuite::by_id(state->server_hello->ciphersuite()); + m_state->suite = Ciphersuite::by_id(m_state->server_hello->ciphersuite()); - state->keys = Session_Keys(state, session_info.master_secret(), true); + m_state->keys = Session_Keys(m_state, session_info.master_secret(), true); - if(!handshake_fn(session_info)) + if(!m_handshake_fn(session_info)) { session_manager.remove_entry(session_info.session_id()); - if(state->server_hello->supports_session_ticket()) // send an empty ticket - state->new_session_ticket = new New_Session_Ticket(writer, state->hash); + if(m_state->server_hello->supports_session_ticket()) // send an empty ticket + m_state->new_session_ticket = new New_Session_Ticket(m_writer, m_state->hash); } - if(state->server_hello->supports_session_ticket() && !state->new_session_ticket) + if(m_state->server_hello->supports_session_ticket() && !m_state->new_session_ticket) { try { const SymmetricKey ticket_key = creds.psk("tls-server", "session-ticket", ""); - state->new_session_ticket = - new New_Session_Ticket(writer, state->hash, + m_state->new_session_ticket = + new New_Session_Ticket(m_writer, m_state->hash, session_info.encrypt(ticket_key, rng), policy.session_ticket_lifetime()); } catch(...) {} - if(!state->new_session_ticket) - state->new_session_ticket = new New_Session_Ticket(writer, state->hash); + if(!m_state->new_session_ticket) + m_state->new_session_ticket = new New_Session_Ticket(m_writer, m_state->hash); } - writer.send(CHANGE_CIPHER_SPEC, 1); + m_writer.send(CHANGE_CIPHER_SPEC, 1); - writer.activate(SERVER, state->suite, state->keys, - state->server_hello->compression_method()); + m_writer.activate(SERVER, m_state->suite, m_state->keys, + m_state->server_hello->compression_method()); - state->server_finished = new Finished(writer, state, SERVER); + m_state->server_finished = new Finished(m_writer, m_state, SERVER); - state->set_expected_next(HANDSHAKE_CCS); + m_state->set_expected_next(HANDSHAKE_CCS); } else // new session { @@ -434,42 +434,42 @@ void Server::process_handshake_msg(Handshake_Type type, cert_chains = get_server_certs("", creds); } - state->server_hello = new Server_Hello( - writer, - state->hash, + m_state->server_hello = new Server_Hello( + m_writer, + m_state->hash, unlock(rng.random_vec(32)), // new session ID - state->version(), - choose_ciphersuite(policy, creds, cert_chains, state->client_hello), - choose_compression(policy, state->client_hello->compression_methods()), - state->client_hello->fragment_size(), - secure_renegotiation.supported(), - secure_renegotiation.for_server_hello(), - state->client_hello->supports_session_ticket() && have_session_ticket_key, - state->client_hello->next_protocol_notification(), + m_state->version(), + choose_ciphersuite(policy, creds, cert_chains, m_state->client_hello), + choose_compression(policy, m_state->client_hello->compression_methods()), + m_state->client_hello->fragment_size(), + m_secure_renegotiation.supported(), + m_secure_renegotiation.for_server_hello(), + m_state->client_hello->supports_session_ticket() && have_session_ticket_key, + m_state->client_hello->next_protocol_notification(), m_possible_protocols, - state->client_hello->supports_heartbeats(), + m_state->client_hello->supports_heartbeats(), rng); - secure_renegotiation.update(state->server_hello); + m_secure_renegotiation.update(m_state->server_hello); - if(state->client_hello->fragment_size()) + if(m_state->client_hello->fragment_size()) { - reader.set_maximum_fragment_size(state->client_hello->fragment_size()); - writer.set_maximum_fragment_size(state->client_hello->fragment_size()); + m_reader.set_maximum_fragment_size(m_state->client_hello->fragment_size()); + m_writer.set_maximum_fragment_size(m_state->client_hello->fragment_size()); } - state->suite = Ciphersuite::by_id(state->server_hello->ciphersuite()); + m_state->suite = Ciphersuite::by_id(m_state->server_hello->ciphersuite()); - const std::string sig_algo = state->suite.sig_algo(); - const std::string kex_algo = state->suite.kex_algo(); + const std::string sig_algo = m_state->suite.sig_algo(); + const std::string kex_algo = m_state->suite.kex_algo(); if(sig_algo != "") { BOTAN_ASSERT(!cert_chains[sig_algo].empty(), "Attempting to send empty certificate chain"); - state->server_certs = new Certificate(writer, - state->hash, + m_state->server_certs = new Certificate(m_writer, + m_state->hash, cert_chains[sig_algo]); } @@ -477,7 +477,7 @@ void Server::process_handshake_msg(Handshake_Type type, if(kex_algo == "RSA" || sig_algo != "") { - private_key = creds.private_key_for(state->server_certs->cert_chain()[0], + private_key = creds.private_key_for(m_state->server_certs->cert_chain()[0], "tls-server", m_hostname); @@ -487,26 +487,26 @@ void Server::process_handshake_msg(Handshake_Type type, if(kex_algo == "RSA") { - state->server_rsa_kex_key = private_key; + m_state->server_rsa_kex_key = private_key; } else { - state->server_kex = - new Server_Key_Exchange(writer, state, policy, creds, rng, private_key); + m_state->server_kex = + new Server_Key_Exchange(m_writer, m_state, policy, creds, rng, private_key); } std::vector<X509_Certificate> client_auth_CAs = creds.trusted_certificate_authorities("tls-server", m_hostname); - if(!client_auth_CAs.empty() && state->suite.sig_algo() != "") + if(!client_auth_CAs.empty() && m_state->suite.sig_algo() != "") { - state->cert_req = new Certificate_Req(writer, - state->hash, + m_state->cert_req = new Certificate_Req(m_writer, + m_state->hash, policy, client_auth_CAs, - state->version()); + m_state->version()); - state->set_expected_next(CERTIFICATE); + m_state->set_expected_next(CERTIFICATE); } /* @@ -514,38 +514,38 @@ void Server::process_handshake_msg(Handshake_Type type, * allowed to send either an empty cert message or proceed * directly to the client key exchange, so allow either case. */ - state->set_expected_next(CLIENT_KEX); + m_state->set_expected_next(CLIENT_KEX); - state->server_hello_done = new Server_Hello_Done(writer, state->hash); + m_state->server_hello_done = new Server_Hello_Done(m_writer, m_state->hash); } } else if(type == CERTIFICATE) { - state->client_certs = new Certificate(contents); + m_state->client_certs = new Certificate(contents); - state->set_expected_next(CLIENT_KEX); + m_state->set_expected_next(CLIENT_KEX); } else if(type == CLIENT_KEX) { - if(state->received_handshake_msg(CERTIFICATE) && !state->client_certs->empty()) - state->set_expected_next(CERTIFICATE_VERIFY); + if(m_state->received_handshake_msg(CERTIFICATE) && !m_state->client_certs->empty()) + m_state->set_expected_next(CERTIFICATE_VERIFY); else - state->set_expected_next(HANDSHAKE_CCS); + m_state->set_expected_next(HANDSHAKE_CCS); - state->client_kex = new Client_Key_Exchange(contents, state, creds, policy, rng); + m_state->client_kex = new Client_Key_Exchange(contents, m_state, creds, policy, rng); - state->keys = Session_Keys(state, state->client_kex->pre_master_secret(), false); + m_state->keys = Session_Keys(m_state, m_state->client_kex->pre_master_secret(), false); } else if(type == CERTIFICATE_VERIFY) { - state->client_verify = new Certificate_Verify(contents, state->version()); + m_state->client_verify = new Certificate_Verify(contents, m_state->version()); - peer_certs = state->client_certs->cert_chain(); + m_peer_certs = m_state->client_certs->cert_chain(); const bool sig_valid = - state->client_verify->verify(peer_certs[0], state); + m_state->client_verify->verify(m_peer_certs[0], m_state); - state->hash.update(type, contents); + m_state->hash.update(type, contents); /* * Using DECRYPT_ERROR looks weird here, but per RFC 4346 is for @@ -557,74 +557,74 @@ void Server::process_handshake_msg(Handshake_Type type, try { - creds.verify_certificate_chain("tls-server", "", peer_certs); + creds.verify_certificate_chain("tls-server", "", m_peer_certs); } catch(std::exception& e) { throw TLS_Exception(Alert::BAD_CERTIFICATE, e.what()); } - state->set_expected_next(HANDSHAKE_CCS); + m_state->set_expected_next(HANDSHAKE_CCS); } else if(type == HANDSHAKE_CCS) { - if(state->server_hello->next_protocol_notification()) - state->set_expected_next(NEXT_PROTOCOL); + if(m_state->server_hello->next_protocol_notification()) + m_state->set_expected_next(NEXT_PROTOCOL); else - state->set_expected_next(FINISHED); + m_state->set_expected_next(FINISHED); - reader.activate(SERVER, state->suite, state->keys, - state->server_hello->compression_method()); + m_reader.activate(SERVER, m_state->suite, m_state->keys, + m_state->server_hello->compression_method()); } else if(type == NEXT_PROTOCOL) { - state->set_expected_next(FINISHED); + m_state->set_expected_next(FINISHED); - state->next_protocol = new Next_Protocol(contents); + m_state->next_protocol = new Next_Protocol(contents); - m_next_protocol = state->next_protocol->protocol(); + m_next_protocol = m_state->next_protocol->protocol(); } else if(type == FINISHED) { - state->set_expected_next(HANDSHAKE_NONE); + m_state->set_expected_next(HANDSHAKE_NONE); - state->client_finished = new Finished(contents); + m_state->client_finished = new Finished(contents); - if(!state->client_finished->verify(state, CLIENT)) + if(!m_state->client_finished->verify(m_state, CLIENT)) throw TLS_Exception(Alert::DECRYPT_ERROR, "Finished message didn't verify"); - if(!state->server_finished) + if(!m_state->server_finished) { // already sent finished if resuming, so this is a new session - state->hash.update(type, contents); + m_state->hash.update(type, contents); Session session_info( - state->server_hello->session_id(), - state->keys.master_secret(), - state->server_hello->version(), - state->server_hello->ciphersuite(), - state->server_hello->compression_method(), + m_state->server_hello->session_id(), + m_state->keys.master_secret(), + m_state->server_hello->version(), + m_state->server_hello->ciphersuite(), + m_state->server_hello->compression_method(), SERVER, - secure_renegotiation.supported(), - state->server_hello->fragment_size(), - peer_certs, + m_secure_renegotiation.supported(), + m_state->server_hello->fragment_size(), + m_peer_certs, std::vector<byte>(), m_hostname, - state->srp_identifier() + m_state->srp_identifier() ); - if(handshake_fn(session_info)) + if(m_handshake_fn(session_info)) { - if(state->server_hello->supports_session_ticket()) + if(m_state->server_hello->supports_session_ticket()) { try { const SymmetricKey ticket_key = creds.psk("tls-server", "session-ticket", ""); - state->new_session_ticket = - new New_Session_Ticket(writer, state->hash, + m_state->new_session_ticket = + new New_Session_Ticket(m_writer, m_state->hash, session_info.encrypt(ticket_key, rng), policy.session_ticket_lifetime()); } @@ -634,23 +634,23 @@ void Server::process_handshake_msg(Handshake_Type type, session_manager.save(session_info); } - if(state->server_hello->supports_session_ticket() && !state->new_session_ticket) - state->new_session_ticket = new New_Session_Ticket(writer, state->hash); + if(m_state->server_hello->supports_session_ticket() && !m_state->new_session_ticket) + m_state->new_session_ticket = new New_Session_Ticket(m_writer, m_state->hash); - writer.send(CHANGE_CIPHER_SPEC, 1); + m_writer.send(CHANGE_CIPHER_SPEC, 1); - writer.activate(SERVER, state->suite, state->keys, - state->server_hello->compression_method()); + m_writer.activate(SERVER, m_state->suite, m_state->keys, + m_state->server_hello->compression_method()); - state->server_finished = new Finished(writer, state, SERVER); + m_state->server_finished = new Finished(m_writer, m_state, SERVER); } - secure_renegotiation.update(state->client_finished, - state->server_finished); + m_secure_renegotiation.update(m_state->client_finished, + m_state->server_finished); - delete state; - state = nullptr; - handshake_completed = true; + delete m_state; + m_state = nullptr; + m_handshake_completed = true; } else throw Unexpected_Message("Unknown handshake message received"); |