diff options
Diffstat (limited to 'src/dh-gex.c')
-rw-r--r-- | src/dh-gex.c | 87 |
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; } |