aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libssh/curve25519.h1
-rw-r--r--include/libssh/dh.h1
-rw-r--r--include/libssh/ecdh.h3
-rw-r--r--src/curve25519.c34
-rw-r--r--src/dh.c32
-rw-r--r--src/ecdh.c30
-rw-r--r--src/ecdh_crypto.c4
-rw-r--r--src/ecdh_gcrypt.c4
-rw-r--r--src/ecdh_mbedcrypto.c3
-rw-r--r--src/packet.c2
-rw-r--r--src/packet_cb.c44
11 files changed, 99 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 cfdcfeec..2198a9fa 100644
--- a/include/libssh/dh.h
+++ b/include/libssh/dh.h
@@ -43,7 +43,6 @@ int ssh_dh_import_next_pubkey_blob(ssh_session session, ssh_string pubkey_blob);
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);
ssh_key ssh_dh_get_current_server_publickey(ssh_session session);
int ssh_dh_get_current_server_publickey_blob(ssh_session session,
diff --git a/include/libssh/ecdh.h b/include/libssh/ecdh.h
index 66659b85..c5212bc7 100644
--- a/include/libssh/ecdh.h
+++ b/include/libssh/ecdh.h
@@ -41,8 +41,7 @@
#define HAVE_ECDH 1
#endif
-/* Common functions. */
-int ssh_client_ecdh_reply(ssh_session session, ssh_buffer packet);
+extern struct ssh_packet_callbacks_struct ssh_ecdh_client_callbacks;
/* Backend-specific functions. */
int ssh_client_ecdh_init(ssh_session session);
diff --git a/src/curve25519.c b/src/curve25519.c
index 167209f4..6738da61 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 / curve25519-sha256 key exchange
*/
@@ -64,7 +77,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;
@@ -117,11 +131,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_blob = NULL;
ssh_string signature = NULL;
int rc;
+ (void)type;
+ (void)user;
+
+ ssh_packet_remove_callbacks(session, &ssh_curve25519_client_callbacks);
pubkey_blob = ssh_buffer_get_ssh_string(packet);
if (pubkey_blob == NULL) {
@@ -171,10 +189,18 @@ 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 cc12fd46..474f52f3 100644
--- a/src/dh.c
+++ b/src/dh.c
@@ -652,6 +652,19 @@ 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
*/
@@ -680,6 +693,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:
@@ -691,11 +707,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_blob = NULL;
ssh_string signature = NULL;
int rc;
+ (void)type;
+ (void)user;
+
+ ssh_packet_remove_callbacks(session, &ssh_dh_client_callbacks);
pubkey_blob = ssh_buffer_get_ssh_string(packet);
if (pubkey_blob == NULL){
@@ -740,10 +760,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 f7fcaf13..71779da9 100644
--- a/src/ecdh.c
+++ b/src/ecdh.c
@@ -30,16 +30,32 @@
#ifdef HAVE_ECDH
+static SSH_PACKET_CALLBACK(ssh_packet_client_ecdh_reply);
+
+static ssh_packet_callback ecdh_client_callbacks[]= {
+ ssh_packet_client_ecdh_reply
+};
+
+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 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_blob = NULL;
ssh_string signature = NULL;
int rc;
+ (void)type;
+ (void)user;
+ ssh_packet_remove_callbacks(session, &ssh_ecdh_client_callbacks);
pubkey_blob = ssh_buffer_get_ssh_string(packet);
if (pubkey_blob == NULL) {
ssh_set_error(session,SSH_FATAL, "No public key in packet");
@@ -77,10 +93,18 @@ 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;
}
#endif /* HAVE_ECDH */
diff --git a/src/ecdh_crypto.c b/src/ecdh_crypto.c
index 24f21c03..10cc6a5f 100644
--- a/src/ecdh_crypto.c
+++ b/src/ecdh_crypto.c
@@ -108,6 +108,10 @@ 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);
+ session->dh_handshake_state = DH_STATE_INIT_SENT;
+
rc = ssh_packet_send(session);
return rc;
diff --git a/src/ecdh_gcrypt.c b/src/ecdh_gcrypt.c
index e43cacea..96dbd1a0 100644
--- a/src/ecdh_gcrypt.c
+++ b/src/ecdh_gcrypt.c
@@ -106,6 +106,10 @@ int ssh_client_ecdh_init(ssh_session session)
session->next_crypto->ecdh_client_pubkey = client_pubkey;
client_pubkey = NULL;
+ /* register the packet callbacks */
+ ssh_packet_set_callbacks(session, &ssh_ecdh_client_callbacks);
+ session->dh_handshake_state = DH_STATE_INIT_SENT;
+
rc = ssh_packet_send(session);
out:
diff --git a/src/ecdh_mbedcrypto.c b/src/ecdh_mbedcrypto.c
index fa350028..3ff93ee8 100644
--- a/src/ecdh_mbedcrypto.c
+++ b/src/ecdh_mbedcrypto.c
@@ -106,6 +106,9 @@ int ssh_client_ecdh_init(ssh_session session)
session->next_crypto->ecdh_client_pubkey = client_pubkey;
client_pubkey = NULL;
+ /* register the packet callbacks */
+ ssh_packet_set_callbacks(session, &ssh_ecdh_client_callbacks);
+ session->dh_handshake_state = DH_STATE_INIT_SENT;
rc = ssh_packet_send(session);
out:
diff --git a/src/packet.c b/src/packet.c
index 030a29a1..8fa10283 100644
--- a/src/packet.c
+++ b/src/packet.c
@@ -74,7 +74,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 43dae481..22051c5d 100644
--- a/src/packet_cb.c
+++ b/src/packet_cb.c
@@ -92,50 +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:
- case SSH_KEX_DH_GROUP16_SHA512:
- case SSH_KEX_DH_GROUP18_SHA512:
- rc=ssh_client_dh_reply(session, packet);
- break;
-#ifdef HAVE_ECDH
- case SSH_KEX_ECDH_SHA2_NISTP256:
- case SSH_KEX_ECDH_SHA2_NISTP384:
- case SSH_KEX_ECDH_SHA2_NISTP521:
- rc = ssh_client_ecdh_reply(session, packet);
- break;
-#endif
-#ifdef HAVE_CURVE25519
- case SSH_KEX_CURVE25519_SHA256:
- 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;
ssh_signature sig = NULL;