diff options
author | Aris Adamantiadis <aris@0xbadc0de.be> | 2017-06-11 11:57:25 +0200 |
---|---|---|
committer | Aris Adamantiadis <aris@0xbadc0de.be> | 2017-06-11 11:57:25 +0200 |
commit | 3bd1b80c85d6657f47031b10211265fa216da37c (patch) | |
tree | e0e820ef7aa2b9dfe3d4f8c01413512edbcb789e | |
parent | 6f8ec3062c8b7f21a6995d498c3aae8f106bda8f (diff) | |
download | libssh-3bd1b80c85d6657f47031b10211265fa216da37c.tar.gz libssh-3bd1b80c85d6657f47031b10211265fa216da37c.tar.xz libssh-3bd1b80c85d6657f47031b10211265fa216da37c.zip |
dh: WIP
-rw-r--r-- | include/libssh/crypto.h | 2 | ||||
-rw-r--r-- | include/libssh/dh.h | 1 | ||||
-rw-r--r-- | include/libssh/session.h | 1 | ||||
-rw-r--r-- | src/dh.c | 60 | ||||
-rw-r--r-- | src/kex.c | 4 | ||||
-rw-r--r-- | src/server.c | 1 |
6 files changed, 47 insertions, 22 deletions
diff --git a/include/libssh/crypto.h b/include/libssh/crypto.h index 201feaf2..805873ea 100644 --- a/include/libssh/crypto.h +++ b/include/libssh/crypto.h @@ -81,7 +81,7 @@ struct ssh_crypto_struct { bignum g, p; int dh_group_is_mutable; /* do free group parameters */ int dh_group_bits; /* size of p in bits */ - int pmin; int pn; int pmax; /* preferred group parameters */ + int dh_pmin; int dh_pn; int dh_pmax; /* preferred group parameters */ #ifdef HAVE_ECDH #ifdef HAVE_OPENSSL_ECC EC_KEY *ecdh_privkey; diff --git a/include/libssh/dh.h b/include/libssh/dh.h index b270abf5..3a613cb9 100644 --- a/include/libssh/dh.h +++ b/include/libssh/dh.h @@ -38,5 +38,6 @@ void ssh_server_dh_init(ssh_session session); int ssh_dh_init_common(ssh_session session); void ssh_dh_cleanup(struct ssh_crypto_struct *crypto); int ssh_dh_generate_secret(ssh_session session, bignum dest); +int ssh_server_dh_process_init(ssh_session session, ssh_buffer packet); #endif /* DH_H_ */ diff --git a/include/libssh/session.h b/include/libssh/session.h index a97d9bda..bcf02c3d 100644 --- a/include/libssh/session.h +++ b/include/libssh/session.h @@ -45,6 +45,7 @@ enum ssh_session_state_e { enum ssh_dh_state_e { DH_STATE_INIT=0, + DH_STATE_GROUP_SENT, DH_STATE_REQUEST_SENT, DH_STATE_INIT_SENT, DH_STATE_NEWKEYS_SENT, @@ -371,23 +371,19 @@ void ssh_server_dh_init(ssh_session session){ } /** @internal - * @brief parse an incoming SSH_MSG_KEXDH_INIT packet and complete - * Diffie-Hellman key exchange - **/ -static SSH_PACKET_CALLBACK(ssh_packet_server_dh_init){ + * @brief processes a SSH_MSG_KEXDH_INIT or SSH_MSG_KEX_DH_GEX_INIT packet and send + * the appropriate SSH_MSG_KEXDH_REPLY or SSH_MSG_KEXDEH_GEX_REPLY + */ +int ssh_server_dh_process_init(ssh_session session, ssh_buffer packet){ ssh_key privkey; ssh_string sig_blob; - bignum_CTX ctx = bignum_ctx_new(); int rc; - - (void)type; - (void)user; + int packet_type; + bignum_CTX ctx = bignum_ctx_new(); if (bignum_ctx_invalid(ctx)) { goto error; } - ssh_packet_remove_callbacks(session, &ssh_dh_server_callbacks); - rc = ssh_buffer_unpack(packet, "B", &session->next_crypto->e); if (rc == SSH_ERROR) { ssh_set_error(session, SSH_FATAL, "No e number in client request"); @@ -428,10 +424,22 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_dh_init){ ssh_set_error(session, SSH_FATAL, "Could not sign the session id"); goto error; } - + switch (session->next_crypto->kex_type){ + case SSH_KEX_DH_GROUP1_SHA1: + case SSH_KEX_DH_GROUP14_SHA1: + packet_type = SSH2_MSG_KEXDH_REPLY; + break; + case SSH_KEX_DH_GEX_SHA1: + case SSH_KEX_DH_GEX_SHA256: + packet_type = SSH2_MSG_KEX_DH_GEX_REPLY; + break; + default: + ssh_set_error(session, SSH_FATAL, "Invalid kex type"); + goto error; + } rc = ssh_buffer_pack(session->out_buffer, "bSBS", - SSH2_MSG_KEXDH_REPLY, + packet_type, session->next_crypto->server_pubkey, session->next_crypto->f, sig_blob); @@ -442,28 +450,40 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_dh_init){ goto error; } - if (ssh_packet_send(session) == SSH_ERROR) { + if (ssh_packet_send(session) == SSH_ERROR) { goto error; } - - if (ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) { + SSH_LOG(SSH_LOG_DEBUG, "Sent KEX_DH_[GEX]_REPLY"); + if (ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) { ssh_buffer_reinit(session->out_buffer); goto error; } + session->dh_handshake_state=DH_STATE_NEWKEYS_SENT; - if (ssh_packet_send(session) == SSH_ERROR) { + if (ssh_packet_send(session) == SSH_ERROR) { goto error; } SSH_LOG(SSH_LOG_PACKET, "SSH_MSG_NEWKEYS sent"); - session->dh_handshake_state=DH_STATE_NEWKEYS_SENT; - ssh_dh_cleanup(session); - return SSH_PACKET_USED; + return SSH_OK; error: - ssh_dh_cleanup(session); if (!bignum_ctx_invalid(ctx)){ bignum_ctx_free(ctx); } session->session_state=SSH_SESSION_STATE_ERROR; + ssh_dh_cleanup(session->next_crypto); + return SSH_ERROR; +} + +/** @internal + * @brief parse an incoming SSH_MSG_KEXDH_INIT packet and complete + * Diffie-Hellman key exchange + **/ +static SSH_PACKET_CALLBACK(ssh_packet_server_dh_init){ + (void)type; + (void)user; + SSH_LOG(SSH_LOG_DEBUG, "Received SSH_MSG_KEXDH_INIT"); + ssh_packet_remove_callbacks(session, &ssh_dh_server_callbacks); + ssh_server_dh_process_init(session, packet); return SSH_PACKET_USED; } @@ -768,7 +768,9 @@ int ssh_make_sessionid(ssh_session session) { case SSH_KEX_DH_GEX_SHA256: rc = ssh_buffer_pack(buf, "dddBBBB", - 1534, 2048, 8192, + session->next_crypto->dh_pmin, + session->next_crypto->dh_pn, + session->next_crypto->dh_pmax, session->next_crypto->p, session->next_crypto->g, session->next_crypto->e, diff --git a/src/server.c b/src/server.c index e6c51d30..683488c9 100644 --- a/src/server.c +++ b/src/server.c @@ -165,6 +165,7 @@ SSH_PACKET_CALLBACK(ssh_packet_kexdh_init){ session->first_kex_follows_guess_wrong = 0; return SSH_PACKET_USED; } + SSH_LOG(SSH_LOG_DEBUG, "Calling next KEXDH handler"); return SSH_PACKET_NOT_USED; } |