diff options
author | Aris Adamantiadis <aris@0xbadc0de.be> | 2015-12-23 12:46:28 +0100 |
---|---|---|
committer | Aris Adamantiadis <aris@0xbadc0de.be> | 2016-05-11 18:10:31 +0200 |
commit | 7f136b56c95e5898095eec1f8daf8c255f23c139 (patch) | |
tree | ae908ff3e66625943da187fa737d570b79f3503e | |
parent | 25d8089f77180fc230635f07cbb4f16fb57a0c5b (diff) | |
download | libssh-7f136b56c95e5898095eec1f8daf8c255f23c139.tar.gz libssh-7f136b56c95e5898095eec1f8daf8c255f23c139.tar.xz libssh-7f136b56c95e5898095eec1f8daf8c255f23c139.zip |
kex: use runtime callbacks (client)
-rw-r--r-- | include/libssh/curve25519.h | 1 | ||||
-rw-r--r-- | include/libssh/dh.h | 1 | ||||
-rw-r--r-- | include/libssh/ecdh.h | 1 | ||||
-rw-r--r-- | src/curve25519.c | 44 | ||||
-rw-r--r-- | src/dh.c | 33 | ||||
-rw-r--r-- | src/ecdh.c | 32 | ||||
-rw-r--r-- | src/packet.c | 2 | ||||
-rw-r--r-- | src/packet_cb.c | 39 |
8 files changed, 94 insertions, 59 deletions
diff --git a/include/libssh/curve25519.h b/include/libssh/curve25519.h index 0406b9ee..96018000 100644 --- a/include/libssh/curve25519.h +++ b/include/libssh/curve25519.h @@ -48,7 +48,6 @@ typedef unsigned char ssh_curve25519_privkey[CURVE25519_PRIVKEY_SIZE]; int ssh_client_curve25519_init(ssh_session session); -int ssh_client_curve25519_reply(ssh_session session, ssh_buffer packet); #ifdef WITH_SERVER int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet); diff --git a/include/libssh/dh.h b/include/libssh/dh.h index 8e0d5aa6..8b874f93 100644 --- a/include/libssh/dh.h +++ b/include/libssh/dh.h @@ -40,7 +40,6 @@ int ssh_dh_import_e(ssh_session session, ssh_string e_string); void ssh_dh_import_pubkey(ssh_session session,ssh_string pubkey_string); int ssh_dh_build_k(ssh_session session); int ssh_client_dh_init(ssh_session session); -int ssh_client_dh_reply(ssh_session session, ssh_buffer packet); int ssh_make_sessionid(ssh_session session); /* add data for the final cookie */ diff --git a/include/libssh/ecdh.h b/include/libssh/ecdh.h index 8d1e7515..72ab3c14 100644 --- a/include/libssh/ecdh.h +++ b/include/libssh/ecdh.h @@ -34,7 +34,6 @@ #endif /* HAVE_LIBCRYPTO */ int ssh_client_ecdh_init(ssh_session session); -int ssh_client_ecdh_reply(ssh_session session, ssh_buffer packet); #ifdef WITH_SERVER int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet); diff --git a/src/curve25519.c b/src/curve25519.c index 43783e88..2f42f6d9 100644 --- a/src/curve25519.c +++ b/src/curve25519.c @@ -39,6 +39,19 @@ #include "libssh/pki.h" #include "libssh/bignum.h" +static SSH_PACKET_CALLBACK(ssh_packet_client_curve25519_reply); + +static ssh_packet_callback dh_client_callbacks[]= { + ssh_packet_client_curve25519_reply +}; + +static struct ssh_packet_callbacks_struct ssh_curve25519_client_callbacks = { + .start = SSH2_MSG_KEX_ECDH_REPLY, + .n_callbacks = 1, + .callbacks = dh_client_callbacks, + .user = NULL +}; + /** @internal * @brief Starts curve25519-sha256@libssh.org key exchange */ @@ -63,7 +76,8 @@ int ssh_client_curve25519_init(ssh_session session){ ssh_set_error_oom(session); return SSH_ERROR; } - + /* register the packet callbacks */ + ssh_packet_set_callbacks(session, &ssh_curve25519_client_callbacks); rc = ssh_packet_send(session); return rc; @@ -101,11 +115,15 @@ static int ssh_curve25519_build_k(ssh_session session) { * @brief parses a SSH_MSG_KEX_ECDH_REPLY packet and sends back * a SSH_MSG_NEWKEYS */ -int ssh_client_curve25519_reply(ssh_session session, ssh_buffer packet){ +static SSH_PACKET_CALLBACK(ssh_packet_client_curve25519_reply){ ssh_string q_s_string = NULL; ssh_string pubkey = NULL; ssh_string signature = NULL; int rc; + (void)type; + (void)user; + + ssh_packet_remove_callbacks(session, &ssh_curve25519_client_callbacks); pubkey = ssh_buffer_get_ssh_string(packet); if (pubkey == NULL){ ssh_set_error(session,SSH_FATAL, "No public key in packet"); @@ -117,14 +135,14 @@ int ssh_client_curve25519_reply(ssh_session session, ssh_buffer packet){ q_s_string = ssh_buffer_get_ssh_string(packet); if (q_s_string == NULL) { - ssh_set_error(session,SSH_FATAL, "No Q_S ECC point in packet"); - goto error; + ssh_set_error(session,SSH_FATAL, "No Q_S ECC point in packet"); + goto error; } if (ssh_string_len(q_s_string) != CURVE25519_PUBKEY_SIZE){ - ssh_set_error(session, SSH_FATAL, "Incorrect size for server Curve25519 public key: %d", - (int)ssh_string_len(q_s_string)); - ssh_string_free(q_s_string); - goto error; + ssh_set_error(session, SSH_FATAL, "Incorrect size for server Curve25519 public key: %d", + (int)ssh_string_len(q_s_string)); + ssh_string_free(q_s_string); + goto error; } memcpy(session->next_crypto->curve25519_server_pubkey, ssh_string_data(q_s_string), CURVE25519_PUBKEY_SIZE); ssh_string_free(q_s_string); @@ -148,10 +166,16 @@ int ssh_client_curve25519_reply(ssh_session session, ssh_buffer packet){ } rc=ssh_packet_send(session); + if (rc==SSH_ERROR){ + goto error; + } SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); - return rc; + session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; + + return SSH_PACKET_USED; error: - return SSH_ERROR; + session->session_state=SSH_SESSION_STATE_ERROR; + return SSH_PACKET_USED; } #ifdef WITH_SERVER @@ -440,6 +440,20 @@ int ssh_dh_build_k(ssh_session session) { return 0; } + +static SSH_PACKET_CALLBACK(ssh_packet_client_dh_reply); + +static ssh_packet_callback dh_client_callbacks[]= { + ssh_packet_client_dh_reply +}; + +static struct ssh_packet_callbacks_struct ssh_dh_client_callbacks = { + .start = SSH2_MSG_KEXDH_REPLY, + .n_callbacks = 1, + .callbacks = dh_client_callbacks, + .user = NULL +}; + /** @internal * @brief Starts diffie-hellman-group1 key exchange */ @@ -468,6 +482,9 @@ int ssh_client_dh_init(ssh_session session){ ssh_string_free(e); e=NULL; + /* register the packet callbacks */ + ssh_packet_set_callbacks(session, &ssh_dh_client_callbacks); + rc = ssh_packet_send(session); return rc; error: @@ -479,11 +496,15 @@ int ssh_client_dh_init(ssh_session session){ return SSH_ERROR; } -int ssh_client_dh_reply(ssh_session session, ssh_buffer packet){ +SSH_PACKET_CALLBACK(ssh_packet_client_dh_reply){ ssh_string f; ssh_string pubkey = NULL; ssh_string signature = NULL; int rc; + (void)type; + (void)user; + + ssh_packet_remove_callbacks(session, &ssh_dh_client_callbacks); pubkey = ssh_buffer_get_ssh_string(packet); if (pubkey == NULL){ ssh_set_error(session,SSH_FATAL, "No public key in packet"); @@ -522,10 +543,16 @@ int ssh_client_dh_reply(ssh_session session, ssh_buffer packet){ } rc=ssh_packet_send(session); + if (rc==SSH_ERROR){ + goto error; + } SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); - return rc; + session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; + + return SSH_PACKET_USED; error: - return SSH_ERROR; + session->session_state=SSH_SESSION_STATE_ERROR; + return SSH_PACKET_USED; } int ssh_make_sessionid(ssh_session session) { @@ -35,6 +35,19 @@ #define NISTP384 NID_secp384r1 #define NISTP521 NID_secp521r1 +static SSH_PACKET_CALLBACK(ssh_packet_client_ecdh_reply); + +static ssh_packet_callback ecdh_client_callbacks[]= { + ssh_packet_client_ecdh_reply +}; + +static struct ssh_packet_callbacks_struct ssh_ecdh_client_callbacks = { + .start = SSH2_MSG_KEX_ECDH_REPLY, + .n_callbacks = 1, + .callbacks = ecdh_client_callbacks, + .user = NULL +}; + /** @internal * @brief Starts ecdh-sha2-nistp256 key exchange */ @@ -87,6 +100,9 @@ int ssh_client_ecdh_init(ssh_session session){ session->next_crypto->ecdh_privkey = key; session->next_crypto->ecdh_client_pubkey = client_pubkey; + /* register the packet callbacks */ + ssh_packet_set_callbacks(session, &ssh_ecdh_client_callbacks); + rc = ssh_packet_send(session); return rc; @@ -176,11 +192,15 @@ static int ecdh_build_k(ssh_session session) { * @brief parses a SSH_MSG_KEX_ECDH_REPLY packet and sends back * a SSH_MSG_NEWKEYS */ -int ssh_client_ecdh_reply(ssh_session session, ssh_buffer packet){ +SSH_PACKET_CALLBACK(ssh_packet_client_ecdh_reply){ ssh_string q_s_string = NULL; ssh_string pubkey = NULL; ssh_string signature = NULL; int rc; + (void)type; + (void)user; + + ssh_packet_remove_callbacks(session, &ssh_ecdh_client_callbacks); pubkey = ssh_buffer_get_ssh_string(packet); if (pubkey == NULL){ ssh_set_error(session,SSH_FATAL, "No public key in packet"); @@ -213,10 +233,16 @@ int ssh_client_ecdh_reply(ssh_session session, ssh_buffer packet){ } rc=ssh_packet_send(session); + if (rc==SSH_ERROR){ + goto error; + } SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); - return rc; + session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; + + return SSH_PACKET_USED; error: - return SSH_ERROR; + session->session_state=SSH_SESSION_STATE_ERROR; + return SSH_PACKET_USED; } #ifdef WITH_SERVER diff --git a/src/packet.c b/src/packet.c index 634bf3b3..1b577298 100644 --- a/src/packet.c +++ b/src/packet.c @@ -71,7 +71,7 @@ static ssh_packet_callback default_packet_handlers[]= { #else NULL, #endif - ssh_packet_dh_reply, // SSH2_MSG_KEXDH_REPLY 31 + NULL, // SSH2_MSG_KEXDH_REPLY 31 // SSH2_MSG_KEX_DH_GEX_GROUP 31 NULL, // SSH2_MSG_KEX_DH_GEX_INIT 32 NULL, // SSH2_MSG_KEX_DH_GEX_REPLY 33 diff --git a/src/packet_cb.c b/src/packet_cb.c index 472e8a73..57072681 100644 --- a/src/packet_cb.c +++ b/src/packet_cb.c @@ -92,45 +92,6 @@ SSH_PACKET_CALLBACK(ssh_packet_ignore_callback){ return SSH_PACKET_USED; } -SSH_PACKET_CALLBACK(ssh_packet_dh_reply){ - int rc; - (void)type; - (void)user; - SSH_LOG(SSH_LOG_PROTOCOL,"Received SSH_KEXDH_REPLY"); - if (session->session_state != SSH_SESSION_STATE_DH || - session->dh_handshake_state != DH_STATE_INIT_SENT){ - ssh_set_error(session,SSH_FATAL,"ssh_packet_dh_reply called in wrong state : %d:%d", - session->session_state,session->dh_handshake_state); - goto error; - } - switch(session->next_crypto->kex_type){ - case SSH_KEX_DH_GROUP1_SHA1: - case SSH_KEX_DH_GROUP14_SHA1: - rc=ssh_client_dh_reply(session, packet); - break; -#ifdef HAVE_ECDH - case SSH_KEX_ECDH_SHA2_NISTP256: - rc = ssh_client_ecdh_reply(session, packet); - break; -#endif -#ifdef HAVE_CURVE25519 - case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG: - rc = ssh_client_curve25519_reply(session, packet); - break; -#endif - default: - ssh_set_error(session,SSH_FATAL,"Wrong kex type in ssh_packet_dh_reply"); - goto error; - } - if(rc==SSH_OK) { - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; - return SSH_PACKET_USED; - } -error: - session->session_state=SSH_SESSION_STATE_ERROR; - return SSH_PACKET_USED; -} - SSH_PACKET_CALLBACK(ssh_packet_newkeys){ ssh_string sig_blob = NULL; int rc; |