aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2015-12-23 12:46:28 +0100
committerAris Adamantiadis <aris@0xbadc0de.be>2016-05-11 18:10:31 +0200
commit7f136b56c95e5898095eec1f8daf8c255f23c139 (patch)
treeae908ff3e66625943da187fa737d570b79f3503e
parent25d8089f77180fc230635f07cbb4f16fb57a0c5b (diff)
downloadlibssh-7f136b56c95e5898095eec1f8daf8c255f23c139.tar.gz
libssh-7f136b56c95e5898095eec1f8daf8c255f23c139.tar.xz
libssh-7f136b56c95e5898095eec1f8daf8c255f23c139.zip
kex: use runtime callbacks (client)
-rw-r--r--include/libssh/curve25519.h1
-rw-r--r--include/libssh/dh.h1
-rw-r--r--include/libssh/ecdh.h1
-rw-r--r--src/curve25519.c44
-rw-r--r--src/dh.c33
-rw-r--r--src/ecdh.c32
-rw-r--r--src/packet.c2
-rw-r--r--src/packet_cb.c39
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
diff --git a/src/dh.c b/src/dh.c
index c54bb9f1..1d66849e 100644
--- a/src/dh.c
+++ b/src/dh.c
@@ -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) {
diff --git a/src/ecdh.c b/src/ecdh.c
index 4dbb7b54..09b66e4f 100644
--- a/src/ecdh.c
+++ b/src/ecdh.c
@@ -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;