1
1

kex: use runtime callbacks (client)

Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Этот коммит содержится в:
Aris Adamantiadis 2018-10-27 21:27:00 +02:00 коммит произвёл Andreas Schneider
родитель fd5770973f
Коммит 602a1defea
11 изменённых файлов: 99 добавлений и 59 удалений

Просмотреть файл

@ -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);

Просмотреть файл

@ -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,

Просмотреть файл

@ -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);

Просмотреть файл

@ -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

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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 */

Просмотреть файл

@ -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;

Просмотреть файл

@ -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:

Просмотреть файл

@ -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:

Просмотреть файл

@ -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

Просмотреть файл

@ -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;