From 585db2baabf949290da78affbd7f4f9686bf5778 Mon Sep 17 00:00:00 2001 From: Markus Friedl Date: Fri, 13 Jan 2012 10:32:24 +0100 Subject: [PATCH] move kex-specific states to struct kex and release states in kex_free() --- ssh/kex.c | 4 +++ ssh/kex.h | 6 +++- ssh/kexdhc.c | 36 ++++++++--------------- ssh/kexdhs.c | 39 ++++++++---------------- ssh/kexecdhc.c | 22 ++++---------- ssh/kexgexc.c | 66 +++++++++++++---------------------------- ssh/kexgexs.c | 80 ++++++++++++++++++-------------------------------- 7 files changed, 87 insertions(+), 166 deletions(-) diff --git a/ssh/kex.c b/ssh/kex.c index 322adac..5681c71 100644 --- a/ssh/kex.c +++ b/ssh/kex.c @@ -270,6 +270,10 @@ kex_free(Kex *kex) { buffer_free(&kex->peer); buffer_free(&kex->my); + if (kex->dh) + DH_free(kex->dh); + if (kex->ec_client_key) + EC_KEY_free(kex->ec_client_key); xfree(kex); } diff --git a/ssh/kex.h b/ssh/kex.h index c4c67ea..5845730 100644 --- a/ssh/kex.h +++ b/ssh/kex.h @@ -136,7 +136,11 @@ struct Kex { struct sshkey *(*load_host_private_key)(int, struct ssh *); int (*host_key_index)(struct sshkey *); void (*kex[KEX_MAX])(struct ssh *); - void *state; + /* kex specific state */ + DH *dh; /* DH */ + int min, max, nbits; /* GEX */ + EC_KEY *ec_client_key; /* ECÐH */ + const EC_GROUP *ec_group; /* ECÐH */ }; int kex_names_valid(const char *); diff --git a/ssh/kexdhc.c b/ssh/kexdhc.c index 7e856f5..b476be7 100644 --- a/ssh/kexdhc.c +++ b/ssh/kexdhc.c @@ -44,48 +44,38 @@ #include "compat.h" #include "err.h" -struct kexdhc_state { - DH *dh; -}; - - static int input_kex_dh(int, u_int32_t, struct ssh *); void kexdh_client(struct ssh *ssh) { Kex *kex = ssh->kex; - struct kexdhc_state *kexdhc_state; - DH *dh; /* generate and send 'e', client DH public key */ switch (kex->kex_type) { case KEX_DH_GRP1_SHA1: - dh = dh_new_group1(); + kex->dh = dh_new_group1(); break; case KEX_DH_GRP14_SHA1: - dh = dh_new_group14(); + kex->dh = dh_new_group14(); break; default: fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); } - dh_gen_key(dh, kex->we_need * 8); + dh_gen_key(kex->dh, kex->we_need * 8); ssh_packet_start(ssh, SSH2_MSG_KEXDH_INIT); - ssh_packet_put_bignum2(ssh, dh->pub_key); + ssh_packet_put_bignum2(ssh, kex->dh->pub_key); ssh_packet_send(ssh); debug("sending SSH2_MSG_KEXDH_INIT"); #ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, dh); + DHparams_print_fp(stderr, kex->dh); fprintf(stderr, "pub= "); - BN_print_fp(stderr, dh->pub_key); + BN_print_fp(stderr, kex->dh->pub_key); fprintf(stderr, "\n"); #endif debug("expecting SSH2_MSG_KEXDH_REPLY"); - kexdhc_state = xcalloc(1, sizeof(*kexdhc_state)); - kexdhc_state->dh = dh; - kex->state = kexdhc_state; ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_REPLY, &input_kex_dh); } @@ -93,7 +83,6 @@ static int input_kex_dh(int type, u_int32_t seq, struct ssh *ssh) { Kex *kex = ssh->kex; - struct kexdhc_state *kexdhc_state = kex->state; BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; struct sshkey *server_host_key; u_char *server_host_key_blob = NULL, *signature = NULL; @@ -129,13 +118,13 @@ input_kex_dh(int type, u_int32_t seq, struct ssh *ssh) signature = ssh_packet_get_string(ssh, &slen); ssh_packet_check_eom(ssh); - if (!dh_pub_is_valid(kexdhc_state->dh, dh_server_pub)) + if (!dh_pub_is_valid(kex->dh, dh_server_pub)) ssh_packet_disconnect(ssh, "bad server public DH value"); - klen = DH_size(kexdhc_state->dh); + klen = DH_size(kex->dh); kbuf = xmalloc(klen); - if ((kout = DH_compute_key(kbuf, dh_server_pub, kexdhc_state->dh)) < 0) + if ((kout = DH_compute_key(kbuf, dh_server_pub, kex->dh)) < 0) fatal("DH_compute_key: failed"); #ifdef DEBUG_KEXDH dump_digest("shared secret", kbuf, kout); @@ -154,14 +143,15 @@ input_kex_dh(int type, u_int32_t seq, struct ssh *ssh) buffer_ptr(&kex->my), buffer_len(&kex->my), buffer_ptr(&kex->peer), buffer_len(&kex->peer), server_host_key_blob, sbloblen, - kexdhc_state->dh->pub_key, + kex->dh->pub_key, dh_server_pub, shared_secret, &hash, &hashlen ); xfree(server_host_key_blob); BN_clear_free(dh_server_pub); - DH_free(kexdhc_state->dh); + DH_free(kex->dh); + kex->dh = NULL; if (sshkey_verify(server_host_key, signature, slen, hash, hashlen, datafellows) != 0) @@ -178,8 +168,6 @@ input_kex_dh(int type, u_int32_t seq, struct ssh *ssh) kex_derive_keys(ssh, hash, hashlen, shared_secret); BN_clear_free(shared_secret); - xfree(kex->state); - kex->state = NULL; kex_finish(ssh); return 0; } diff --git a/ssh/kexdhs.c b/ssh/kexdhs.c index 39d51a4..281d3f1 100644 --- a/ssh/kexdhs.c +++ b/ssh/kexdhs.c @@ -47,35 +47,25 @@ #include "compat.h" #include "err.h" -struct kexdhs_state { - DH *dh; -}; - static int input_kex_dh_init(int, u_int32_t, struct ssh *); void kexdh_server(struct ssh *ssh) { Kex *kex = ssh->kex; - DH *dh; - struct kexdhs_state *kexdhs_state; /* generate server DH public key */ switch (kex->kex_type) { case KEX_DH_GRP1_SHA1: - dh = dh_new_group1(); + kex->dh = dh_new_group1(); break; case KEX_DH_GRP14_SHA1: - dh = dh_new_group14(); + kex->dh = dh_new_group14(); break; default: fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); } - dh_gen_key(dh, kex->we_need * 8); - - kexdhs_state = xcalloc(1, sizeof(*kexdhs_state)); - kexdhs_state->dh = dh; - kex->state = kexdhs_state; + dh_gen_key(kex->dh, kex->we_need * 8); debug("expecting SSH2_MSG_KEXDH_INIT"); ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_INIT, &input_kex_dh_init); @@ -85,16 +75,12 @@ static int input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh) { Kex *kex = ssh->kex; - struct kexdhs_state *kexdhs_state = kex->state; BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; - DH *dh; struct sshkey *server_host_public, *server_host_private; u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; u_int sbloblen, klen, hashlen, slen; int kout, r; - dh = kexdhs_state->dh; - if (kex->load_host_public_key == NULL || kex->load_host_private_key == NULL) fatal("Cannot load hostkey"); @@ -120,18 +106,18 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh) #endif #ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, dh); + DHparams_print_fp(stderr, kex->dh); fprintf(stderr, "pub= "); - BN_print_fp(stderr, dh->pub_key); + BN_print_fp(stderr, kex->dh->pub_key); fprintf(stderr, "\n"); #endif - if (!dh_pub_is_valid(dh, dh_client_pub)) + if (!dh_pub_is_valid(kex->dh, dh_client_pub)) ssh_packet_disconnect(ssh, "bad client public DH value"); - klen = DH_size(dh); + klen = DH_size(kex->dh); kbuf = xmalloc(klen); - if ((kout = DH_compute_key(kbuf, dh_client_pub, dh)) < 0) + if ((kout = DH_compute_key(kbuf, dh_client_pub, kex->dh)) < 0) fatal("DH_compute_key: failed"); #ifdef DEBUG_KEXDH dump_digest("shared secret", kbuf, kout); @@ -155,7 +141,7 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh) buffer_ptr(&kex->my), buffer_len(&kex->my), server_host_key_blob, sbloblen, dh_client_pub, - dh->pub_key, + kex->dh->pub_key, shared_secret, &hash, &hashlen ); @@ -178,19 +164,18 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh) /* send server hostkey, DH pubkey 'f' and singed H */ ssh_packet_start(ssh, SSH2_MSG_KEXDH_REPLY); ssh_packet_put_string(ssh, server_host_key_blob, sbloblen); - ssh_packet_put_bignum2(ssh, dh->pub_key); /* f */ + ssh_packet_put_bignum2(ssh, kex->dh->pub_key); /* f */ ssh_packet_put_string(ssh, signature, slen); ssh_packet_send(ssh); xfree(signature); xfree(server_host_key_blob); /* have keys, free DH */ - DH_free(dh); + DH_free(kex->dh); + kex->dh = NULL; kex_derive_keys(ssh, hash, hashlen, shared_secret); BN_clear_free(shared_secret); - xfree(kex->state); - kex->state = NULL; kex_finish(ssh); return 0; } diff --git a/ssh/kexecdhc.c b/ssh/kexecdhc.c index 675b24c..1e58dd6 100644 --- a/ssh/kexecdhc.c +++ b/ssh/kexecdhc.c @@ -45,11 +45,6 @@ #include "compat.h" #include "err.h" -struct kexecdhc_state { - EC_KEY *client_key; - const EC_GROUP *group; -}; - static int input_kex_ecdh_reply(int, u_int32_t, struct ssh *); void @@ -59,7 +54,6 @@ kexecdh_client(struct ssh *ssh) EC_KEY *client_key; const EC_GROUP *group; int curve_nid; - struct kexecdhc_state *kexecdhc_state; if ((curve_nid = kex_ecdh_name_to_nid(kex->name)) == -1) fatal("%s: unsupported ECDH curve \"%s\"", __func__, kex->name); @@ -79,10 +73,8 @@ kexecdh_client(struct ssh *ssh) sshkey_dump_ec_key(client_key); #endif - kexecdhc_state = xcalloc(1, sizeof(*kexecdhc_state)); - kexecdhc_state->client_key = client_key; - kexecdhc_state->group = group; - kex->state = kexecdhc_state; + kex->ec_client_key = client_key; + kex->ec_group = group; debug("expecting SSH2_MSG_KEX_ECDH_REPLY"); ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_REPLY, &input_kex_ecdh_reply); @@ -92,7 +84,6 @@ static int input_kex_ecdh_reply(int type, u_int32_t seq, struct ssh *ssh) { Kex *kex = ssh->kex; - struct kexecdhc_state *kexecdhc_state = kex->state; const EC_GROUP *group; EC_POINT *server_public; EC_KEY *client_key; @@ -103,8 +94,8 @@ input_kex_ecdh_reply(int type, u_int32_t seq, struct ssh *ssh) u_int klen, slen, sbloblen, hashlen; int r; - group = kexecdhc_state->group; - client_key = kexecdhc_state->client_key; + group = kex->ec_group; + client_key = kex->ec_client_key; /* hostkey */ server_host_key_blob = ssh_packet_get_string(ssh, &sbloblen); @@ -170,7 +161,8 @@ input_kex_ecdh_reply(int type, u_int32_t seq, struct ssh *ssh) ); xfree(server_host_key_blob); EC_POINT_clear_free(server_public); - EC_KEY_free(client_key); + EC_KEY_free(kex->ec_client_key); + kex->ec_client_key = NULL; if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen, datafellows)) != 0) @@ -187,8 +179,6 @@ input_kex_ecdh_reply(int type, u_int32_t seq, struct ssh *ssh) kex_derive_keys(ssh, hash, hashlen, shared_secret); BN_clear_free(shared_secret); - xfree(kex->state); - kex->state = NULL; kex_finish(ssh); return 0; } diff --git a/ssh/kexgexc.c b/ssh/kexgexc.c index b9f65d6..a0aca67 100644 --- a/ssh/kexgexc.c +++ b/ssh/kexgexc.c @@ -45,11 +45,6 @@ #include "dispatch.h" #include "err.h" -struct kexgexc_state { - int min, max, nbits; - DH *dh; -}; - static int input_kex_dh_gex_group(int, u_int32_t, struct ssh *); static int input_kex_dh_gex_reply(int, u_int32_t, struct ssh *); @@ -58,7 +53,6 @@ kexgex_client(struct ssh *ssh) { Kex *kex = ssh->kex; int min, max, nbits; - struct kexgexc_state *kexgexc_state; nbits = dh_estimate(kex->we_need * 8); @@ -88,12 +82,9 @@ kexgex_client(struct ssh *ssh) #endif ssh_packet_send(ssh); - kexgexc_state = xcalloc(1, sizeof(*kexgexc_state)); - kexgexc_state->min = min; - kexgexc_state->max = max; - kexgexc_state->nbits = nbits; - kex->state = kexgexc_state; - + kex->min = min; + kex->max = max; + kex->nbits = nbits; ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP, &input_kex_dh_gex_group); } @@ -101,14 +92,7 @@ static int input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh) { Kex *kex = ssh->kex; - struct kexgexc_state *kexgexc_state = kex->state; - int min, max, nbits; BIGNUM *p = NULL, *g = NULL; - DH *dh; - - min = kexgexc_state->min; - max = kexgexc_state->max; - nbits = kexgexc_state->nbits; debug("got SSH2_MSG_KEX_DH_GEX_GROUP"); @@ -120,27 +104,26 @@ input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh) ssh_packet_get_bignum2(ssh, g); ssh_packet_check_eom(ssh); - if (BN_num_bits(p) < min || BN_num_bits(p) > max) + if (BN_num_bits(p) < kex->min || BN_num_bits(p) > kex->max) fatal("DH_GEX group out of range: %d !< %d !< %d", - min, BN_num_bits(p), max); + kex->min, BN_num_bits(p), kex->max); - dh = dh_new_group(g, p); - dh_gen_key(dh, kex->we_need * 8); + kex->dh = dh_new_group(g, p); + dh_gen_key(kex->dh, kex->we_need * 8); #ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, dh); + DHparams_print_fp(stderr, kex->dh); fprintf(stderr, "pub= "); - BN_print_fp(stderr, dh->pub_key); + BN_print_fp(stderr, kex->dh->pub_key); fprintf(stderr, "\n"); #endif debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); /* generate and send 'e', client DH public key */ ssh_packet_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT); - ssh_packet_put_bignum2(ssh, dh->pub_key); + ssh_packet_put_bignum2(ssh, kex->dh->pub_key); ssh_packet_send(ssh); - kexgexc_state->dh = dh; ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP, NULL); ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REPLY, &input_kex_dh_gex_reply); return 0; @@ -150,19 +133,11 @@ static int input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh) { Kex *kex = ssh->kex; - struct kexgexc_state *kexgexc_state = kex->state; BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; struct sshkey *server_host_key; u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; u_int klen, slen, sbloblen, hashlen; - int kout, min, max, nbits, r; - DH *dh; - - debug("%s %p %p", __func__, kex, kexgexc_state); - dh = kexgexc_state->dh; - min = kexgexc_state->min; - max = kexgexc_state->max; - nbits = kexgexc_state->nbits; + int kout, r; debug("got SSH2_MSG_KEX_DH_GEX_REPLY"); @@ -194,13 +169,13 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh) signature = ssh_packet_get_string(ssh, &slen); ssh_packet_check_eom(ssh); - if (!dh_pub_is_valid(dh, dh_server_pub)) + if (!dh_pub_is_valid(kex->dh, dh_server_pub)) ssh_packet_disconnect(ssh, "bad server public DH value"); - klen = DH_size(dh); + klen = DH_size(kex->dh); kbuf = xmalloc(klen); - if ((kout = DH_compute_key(kbuf, dh_server_pub, dh)) < 0) + if ((kout = DH_compute_key(kbuf, dh_server_pub, kex->dh)) < 0) fatal("DH_compute_key: failed"); #ifdef DEBUG_KEXDH dump_digest("shared secret", kbuf, kout); @@ -213,7 +188,7 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh) xfree(kbuf); if (ssh->datafellows & SSH_OLD_DHGEX) - min = max = -1; + kex->min = kex->max = -1; /* calc and verify H */ kexgex_hash( @@ -223,16 +198,17 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh) buffer_ptr(&kex->my), buffer_len(&kex->my), buffer_ptr(&kex->peer), buffer_len(&kex->peer), server_host_key_blob, sbloblen, - min, nbits, max, - dh->p, dh->g, - dh->pub_key, + kex->min, kex->nbits, kex->max, + kex->dh->p, kex->dh->g, + kex->dh->pub_key, dh_server_pub, shared_secret, &hash, &hashlen ); /* have keys, free DH */ - DH_free(dh); + DH_free(kex->dh); + kex->dh = NULL; xfree(server_host_key_blob); BN_clear_free(dh_server_pub); @@ -252,8 +228,6 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh) BN_clear_free(shared_secret); ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REPLY, NULL); - xfree(kex->state); - kex->state = NULL; kex_finish(ssh); return 0; } diff --git a/ssh/kexgexs.c b/ssh/kexgexs.c index 02f485e..700d7b4 100644 --- a/ssh/kexgexs.c +++ b/ssh/kexgexs.c @@ -49,29 +49,24 @@ #include "dispatch.h" #include "err.h" -struct kexgexs_state { - int omin, min, omax, max, onbits; - DH *dh; -}; - static int input_kex_dh_gex_init(int, u_int32_t, struct ssh *); void kexgex_server(struct ssh *ssh) { Kex *kex = ssh->kex; - DH *dh; - int omin = -1, min = -1, omax = -1, max = -1, onbits = -1, nbits = -1; + int min = -1, max = -1, nbits = -1; int type; - struct kexgexs_state *kexgexs_state; + + kex->min = kex->nbits = kex->max = -1; type = ssh_packet_read(ssh); switch (type) { case SSH2_MSG_KEX_DH_GEX_REQUEST: debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); - omin = min = ssh_packet_get_int(ssh); - onbits = nbits = ssh_packet_get_int(ssh); - omax = max = ssh_packet_get_int(ssh); + kex->min = min = ssh_packet_get_int(ssh); + kex->nbits = nbits = ssh_packet_get_int(ssh); + kex->max = max = ssh_packet_get_int(ssh); min = MAX(DH_GRP_MIN, min); max = MIN(DH_GRP_MAX, max); nbits = MAX(DH_GRP_MIN, nbits); @@ -79,46 +74,37 @@ kexgex_server(struct ssh *ssh) break; case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); - onbits = nbits = ssh_packet_get_int(ssh); + kex->nbits = nbits = ssh_packet_get_int(ssh); /* unused for old GEX */ - omin = min = DH_GRP_MIN; - omax = max = DH_GRP_MAX; + kex->min = min = DH_GRP_MIN; + kex->max = max = DH_GRP_MAX; break; default: fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type); } ssh_packet_check_eom(ssh); - if (omax < omin || onbits < omin || omax < onbits) + if (kex->max < kex->min || kex->nbits < kex->min || kex->max < kex->nbits) fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d", - omin, onbits, omax); + kex->min, kex->nbits, kex->max); /* Contact privileged parent */ - dh = PRIVSEP(choose_dh(min, nbits, max)); - if (dh == NULL) + kex->dh = PRIVSEP(choose_dh(min, nbits, max)); + if (kex->dh == NULL) ssh_packet_disconnect(ssh, "Protocol error: no matching DH grp found"); debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); ssh_packet_start(ssh, SSH2_MSG_KEX_DH_GEX_GROUP); - ssh_packet_put_bignum2(ssh, dh->p); - ssh_packet_put_bignum2(ssh, dh->g); + ssh_packet_put_bignum2(ssh, kex->dh->p); + ssh_packet_put_bignum2(ssh, kex->dh->g); ssh_packet_send(ssh); /* flush */ ssh_packet_write_wait(ssh); /* Compute our exchange value in parallel with the client */ - dh_gen_key(dh, kex->we_need * 8); - - kexgexs_state = xcalloc(1, sizeof(*kexgexs_state)); - kexgexs_state->omin = omin; - kexgexs_state->omax = omax; - kexgexs_state->min = min; - kexgexs_state->max = max; - kexgexs_state->onbits = onbits; - kexgexs_state->dh = dh; - kex->state = kexgexs_state; + dh_gen_key(kex->dh, kex->we_need * 8); debug("expecting SSH2_MSG_KEX_DH_GEX_INIT"); ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_INIT, &input_kex_dh_gex_init); @@ -128,20 +114,11 @@ static int input_kex_dh_gex_init(int type, u_int32_t seq, struct ssh *ssh) { Kex *kex = ssh->kex; - struct kexgexs_state *kexgexs_state = kex->state; BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; struct sshkey *server_host_public, *server_host_private; - DH *dh; u_int sbloblen, klen, slen, hashlen; u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; - int omin, min, omax, max, onbits, kout, r; - - dh = kexgexs_state->dh; - omin = kexgexs_state->omin; - min = kexgexs_state->min; - omax = kexgexs_state->omax; - max = kexgexs_state->max; - onbits = kexgexs_state->onbits; + int kout, r; if (kex->load_host_public_key == NULL || kex->load_host_private_key == NULL) @@ -168,18 +145,18 @@ input_kex_dh_gex_init(int type, u_int32_t seq, struct ssh *ssh) #endif #ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, dh); + DHparams_print_fp(stderr, kex->dh); fprintf(stderr, "pub= "); BN_print_fp(stderr, dh->pub_key); fprintf(stderr, "\n"); #endif - if (!dh_pub_is_valid(dh, dh_client_pub)) + if (!dh_pub_is_valid(kex->dh, dh_client_pub)) ssh_packet_disconnect(ssh, "bad client public DH value"); - klen = DH_size(dh); + klen = DH_size(kex->dh); kbuf = xmalloc(klen); - if ((kout = DH_compute_key(kbuf, dh_client_pub, dh)) < 0) + if ((kout = DH_compute_key(kbuf, dh_client_pub, kex->dh)) < 0) fatal("DH_compute_key: failed"); #ifdef DEBUG_KEXDH dump_digest("shared secret", kbuf, kout); @@ -196,7 +173,7 @@ input_kex_dh_gex_init(int type, u_int32_t seq, struct ssh *ssh) fatal("%s: sshkey_to_blob failed: %s", __func__, ssh_err(r)); if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) - omin = min = omax = max = -1; + kex->min = kex->max = -1; /* calc H */ kexgex_hash( @@ -206,10 +183,10 @@ input_kex_dh_gex_init(int type, u_int32_t seq, struct ssh *ssh) buffer_ptr(&kex->peer), buffer_len(&kex->peer), buffer_ptr(&kex->my), buffer_len(&kex->my), server_host_key_blob, sbloblen, - omin, onbits, omax, - dh->p, dh->g, + kex->min, kex->nbits, kex->max, + kex->dh->p, kex->dh->g, dh_client_pub, - dh->pub_key, + kex->dh->pub_key, shared_secret, &hash, &hashlen ); @@ -233,20 +210,19 @@ input_kex_dh_gex_init(int type, u_int32_t seq, struct ssh *ssh) debug("SSH2_MSG_KEX_DH_GEX_REPLY sent"); ssh_packet_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY); ssh_packet_put_string(ssh, server_host_key_blob, sbloblen); - ssh_packet_put_bignum2(ssh, dh->pub_key); /* f */ + ssh_packet_put_bignum2(ssh, kex->dh->pub_key); /* f */ ssh_packet_put_string(ssh, signature, slen); ssh_packet_send(ssh); xfree(signature); xfree(server_host_key_blob); /* have keys, free DH */ - DH_free(dh); + DH_free(kex->dh); + kex->dh = NULL; kex_derive_keys(ssh, hash, hashlen, shared_secret); BN_clear_free(shared_secret); - xfree(kex->state); - kex->state = NULL; kex_finish(ssh); return 0; }