aboutsummaryrefslogtreecommitdiff
path: root/src/dh-gex.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dh-gex.c')
-rw-r--r--src/dh-gex.c87
1 files changed, 55 insertions, 32 deletions
diff --git a/src/dh-gex.c b/src/dh-gex.c
index 02494bb2..89be2234 100644
--- a/src/dh-gex.c
+++ b/src/dh-gex.c
@@ -65,7 +65,7 @@ int ssh_client_dhgex_init(ssh_session session)
{
int rc;
- rc = ssh_dh_init_common(session);
+ rc = ssh_dh_init_common(session->next_crypto);
if (rc != SSH_OK){
goto error;
}
@@ -107,6 +107,8 @@ SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_group)
int blen;
bignum pmin1 = NULL, one = NULL;
bignum_CTX ctx = bignum_ctx_new();
+ bignum modulus, generator;
+ const_bignum pubkey;
(void) type;
(void) user;
@@ -130,8 +132,8 @@ SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_group)
}
rc = ssh_buffer_unpack(packet,
"BB",
- &session->next_crypto->dh_ctx->modulus,
- &session->next_crypto->dh_ctx->generator);
+ &modulus,
+ &generator);
if (rc != SSH_OK) {
ssh_set_error(session, SSH_FATAL, "Invalid DH_GEX_GROUP packet");
goto error;
@@ -141,7 +143,7 @@ SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_group)
if (rc != 1) {
goto error;
}
- blen = bignum_num_bits(session->next_crypto->dh_ctx->modulus);
+ blen = bignum_num_bits(modulus);
if (blen < DH_PMIN || blen > DH_PMAX) {
ssh_set_error(session,
SSH_FATAL,
@@ -151,43 +153,46 @@ SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_group)
DH_PMAX);
goto error;
}
- if (bignum_cmp(session->next_crypto->dh_ctx->modulus, one) <= 0) {
+ if (bignum_cmp(modulus, one) <= 0) {
/* p must be positive and preferably bigger than one */
ssh_set_error(session, SSH_FATAL, "Invalid dh group parameter p");
}
- if (!bignum_is_bit_set(session->next_crypto->dh_ctx->modulus, 0)) {
+ if (!bignum_is_bit_set(modulus, 0)) {
/* p must be a prime and therefore not divisible by 2 */
ssh_set_error(session, SSH_FATAL, "Invalid dh group parameter p");
goto error;
}
- bignum_sub(pmin1, session->next_crypto->dh_ctx->modulus, one);
- if (bignum_cmp(session->next_crypto->dh_ctx->generator, one) <= 0 ||
- bignum_cmp(session->next_crypto->dh_ctx->generator, pmin1) > 0) {
+ bignum_sub(pmin1, modulus, one);
+ if (bignum_cmp(generator, one) <= 0 ||
+ bignum_cmp(generator, pmin1) > 0) {
/* generator must be at least 2 and smaller than p-1*/
ssh_set_error(session, SSH_FATAL, "Invalid dh group parameter g");
goto error;
}
- /* compute and send DH public parameter */
- rc = ssh_dh_generate_secret(session, session->next_crypto->dh_ctx->client.priv_key);
- if (rc == SSH_ERROR) {
+ bignum_ctx_free(ctx);
+ ctx = NULL;
+
+ /* all checks passed, set parameters */
+ rc = ssh_dh_set_parameters(session->next_crypto->dh_ctx,
+ modulus, generator);
+ if (rc != SSH_OK) {
+ bignum_safe_free(modulus);
+ bignum_safe_free(generator);
goto error;
}
- rc = bignum_mod_exp(session->next_crypto->dh_ctx->client.pub_key,
- session->next_crypto->dh_ctx->generator,
- session->next_crypto->dh_ctx->client.priv_key,
- session->next_crypto->dh_ctx->modulus,
- ctx);
- if (rc != 1) {
+
+ /* compute and send DH public parameter */
+ rc = ssh_dh_keypair_gen_keys(session->next_crypto->dh_ctx,
+ DH_CLIENT_KEYPAIR);
+ if (rc == SSH_ERROR) {
goto error;
}
-
- bignum_ctx_free(ctx);
- ctx = NULL;
-
+ rc = ssh_dh_keypair_get_keys(session->next_crypto->dh_ctx,
+ DH_CLIENT_KEYPAIR, NULL, &pubkey);
rc = ssh_buffer_pack(session->out_buffer,
"bB",
SSH2_MSG_KEX_DH_GEX_INIT,
- session->next_crypto->dh_ctx->client.pub_key);
+ pubkey);
if (rc != SSH_OK) {
goto error;
}
@@ -199,6 +204,7 @@ SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_group)
bignum_safe_free(one);
bignum_safe_free(pmin1);
return SSH_PACKET_USED;
+
error:
bignum_safe_free(one);
bignum_safe_free(pmin1);
@@ -216,6 +222,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_reply)
struct ssh_crypto_struct *crypto=session->next_crypto;
int rc;
ssh_string pubkey_blob = NULL;
+ bignum server_pubkey = NULL;
(void)type;
(void)user;
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEX_DH_GEX_REPLY received");
@@ -223,20 +230,28 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_reply)
ssh_packet_remove_callbacks(session, &ssh_dhgex_client_callbacks);
rc = ssh_buffer_unpack(packet,
"SBS",
- &pubkey_blob, &crypto->dh_ctx->server.pub_key,
+ &pubkey_blob, &server_pubkey,
&crypto->dh_server_signature);
-
if (rc == SSH_ERROR) {
ssh_set_error(session, SSH_FATAL, "Invalid DH_GEX_REPLY packet");
goto error;
}
+ rc = ssh_dh_keypair_set_keys(crypto->dh_ctx, DH_SERVER_KEYPAIR,
+ NULL, server_pubkey);
+ if (rc != SSH_OK) {
+ bignum_safe_free(server_pubkey);
+ goto error;
+ }
+
rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
ssh_string_free(pubkey_blob);
if (rc != 0) {
goto error;
}
- rc = ssh_dh_build_k(session);
+ rc = ssh_dh_compute_shared_secret(session->next_crypto->dh_ctx,
+ DH_CLIENT_KEYPAIR, DH_SERVER_KEYPAIR,
+ &session->next_crypto->shared_secret);
if (rc == SSH_ERROR) {
ssh_set_error(session, SSH_FATAL, "Could not generate shared secret");
goto error;
@@ -526,12 +541,13 @@ static struct ssh_packet_callbacks_struct ssh_dhgex_server_callbacks = {
void ssh_server_dhgex_init(ssh_session session){
/* register the packet callbacks */
ssh_packet_set_callbacks(session, &ssh_dhgex_server_callbacks);
- ssh_dh_init_common(session);
+ ssh_dh_init_common(session->next_crypto);
session->dh_handshake_state = DH_STATE_INIT;
}
static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_request)
{
+ bignum modulus = NULL, generator = NULL;
uint32_t pmin, pn, pmax;
size_t size = 0;
int rc;
@@ -578,8 +594,8 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_request)
pn,
pmax,
&size,
- &session->next_crypto->dh_ctx->modulus,
- &session->next_crypto->dh_ctx->generator);
+ &modulus,
+ &generator);
if (rc == SSH_ERROR) {
ssh_set_error(session,
SSH_FATAL,
@@ -589,11 +605,18 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_request)
pmax);
goto error;
}
+ rc = ssh_dh_set_parameters(session->next_crypto->dh_ctx,
+ modulus, generator);
+ if (rc != SSH_OK) {
+ bignum_safe_free(generator);
+ bignum_safe_free(modulus);
+ goto error;
+ }
rc = ssh_buffer_pack(session->out_buffer,
"bBB",
SSH2_MSG_KEX_DH_GEX_GROUP,
- session->next_crypto->dh_ctx->modulus,
- session->next_crypto->dh_ctx->generator);
+ modulus,
+ generator);
if (rc != SSH_OK) {
ssh_set_error_invalid(session);
goto error;
@@ -605,8 +628,8 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_dhgex_request)
if (rc == SSH_ERROR) {
goto error;
}
-error:
+error:
return SSH_PACKET_USED;
}