diff --git a/ssh.c b/ssh.c index bd7471fa..51bfe8c3 100644 --- a/ssh.c +++ b/ssh.c @@ -6740,7 +6740,7 @@ static void do_ssh2_transport(Ssh ssh, void *vin, int inlen, * If we're doing Diffie-Hellman group exchange, start by * requesting a group. */ - if (!ssh->kex->pdata) { + if (dh_is_gex(ssh->kex)) { logevent("Doing Diffie-Hellman group exchange"); ssh->pkt_kctx = SSH2_PKTCTX_DHGEX; /* @@ -6828,7 +6828,7 @@ static void do_ssh2_transport(Ssh ssh, void *vin, int inlen, set_busy_status(ssh->frontend, BUSY_NOT); hash_string(ssh->kex->hash, ssh->exhash, s->hostkeydata, s->hostkeylen); - if (!ssh->kex->pdata) { + if (dh_is_gex(ssh->kex)) { if (!(ssh->remote_bugs & BUG_SSH2_OLDGEX)) hash_uint32(ssh->kex->hash, ssh->exhash, DH_MIN_SIZE); hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits); @@ -6842,7 +6842,7 @@ static void do_ssh2_transport(Ssh ssh, void *vin, int inlen, dh_cleanup(ssh->kex_ctx); freebn(s->f); - if (!ssh->kex->pdata) { + if (dh_is_gex(ssh->kex)) { freebn(s->g); freebn(s->p); } diff --git a/ssh.h b/ssh.h index f23972f0..29590c25 100644 --- a/ssh.h +++ b/ssh.h @@ -344,10 +344,8 @@ struct ssh_hash { struct ssh_kex { char *name, *groupname; enum { KEXTYPE_DH, KEXTYPE_RSA, KEXTYPE_ECDH } main_type; - /* For DH */ - const unsigned char *pdata, *gdata; /* NULL means group exchange */ - int plen, glen; const struct ssh_hash *hash; + const void *extra; /* private to the kex methods */ }; struct ssh_kexes { @@ -385,6 +383,7 @@ struct ssh_signkey { int *siglen); const char *name; const char *keytype; /* for host key cache */ + const void *extra; /* private to the public key methods */ }; struct ssh_compress { @@ -639,6 +638,7 @@ Bignum bignum_from_decimal(const char *decimal); void diagbn(char *prefix, Bignum md); #endif +int dh_is_gex(const struct ssh_kex *kex); void *dh_setup_group(const struct ssh_kex *kex); void *dh_setup_gex(Bignum pval, Bignum gval); void dh_cleanup(void *); diff --git a/sshdh.c b/sshdh.c index 8f8ab2d2..f254bc1d 100644 --- a/sshdh.c +++ b/sshdh.c @@ -50,9 +50,18 @@ static const unsigned char P14[] = { */ static const unsigned char G[] = { 2 }; +struct dh_extra { + const unsigned char *pdata, *gdata; /* NULL means group exchange */ + int plen, glen; +}; + +static const struct dh_extra extra_group1 = { + P1, G, lenof(P1), lenof(G), +}; + static const struct ssh_kex ssh_diffiehellman_group1_sha1 = { "diffie-hellman-group1-sha1", "group1", - KEXTYPE_DH, P1, G, lenof(P1), lenof(G), &ssh_sha1 + KEXTYPE_DH, &ssh_sha1, &extra_group1, }; static const struct ssh_kex *const group1_list[] = { @@ -64,9 +73,13 @@ const struct ssh_kexes ssh_diffiehellman_group1 = { group1_list }; +static const struct dh_extra extra_group14 = { + P14, G, lenof(P14), lenof(G), +}; + static const struct ssh_kex ssh_diffiehellman_group14_sha1 = { "diffie-hellman-group14-sha1", "group14", - KEXTYPE_DH, P14, G, lenof(P14), lenof(G), &ssh_sha1 + KEXTYPE_DH, &ssh_sha1, &extra_group14, }; static const struct ssh_kex *const group14_list[] = { @@ -78,14 +91,18 @@ const struct ssh_kexes ssh_diffiehellman_group14 = { group14_list }; +static const struct dh_extra extra_gex = { + NULL, NULL, 0, 0, +}; + static const struct ssh_kex ssh_diffiehellman_gex_sha256 = { "diffie-hellman-group-exchange-sha256", NULL, - KEXTYPE_DH, NULL, NULL, 0, 0, &ssh_sha256 + KEXTYPE_DH, &ssh_sha256, &extra_gex, }; static const struct ssh_kex ssh_diffiehellman_gex_sha1 = { "diffie-hellman-group-exchange-sha1", NULL, - KEXTYPE_DH, NULL, NULL, 0, 0, &ssh_sha1 + KEXTYPE_DH, &ssh_sha1, &extra_gex, }; static const struct ssh_kex *const gex_list[] = { @@ -115,14 +132,21 @@ static void dh_init(struct dh_ctx *ctx) ctx->x = ctx->e = NULL; } +int dh_is_gex(const struct ssh_kex *kex) +{ + const struct dh_extra *extra = (const struct dh_extra *)kex->extra; + return extra->pdata == NULL; +} + /* * Initialise DH for a standard group. */ void *dh_setup_group(const struct ssh_kex *kex) { + const struct dh_extra *extra = (const struct dh_extra *)kex->extra; struct dh_ctx *ctx = snew(struct dh_ctx); - ctx->p = bignum_from_bytes(kex->pdata, kex->plen); - ctx->g = bignum_from_bytes(kex->gdata, kex->glen); + ctx->p = bignum_from_bytes(extra->pdata, extra->plen); + ctx->g = bignum_from_bytes(extra->gdata, extra->glen); dh_init(ctx); return ctx; } diff --git a/sshdss.c b/sshdss.c index bd7e0887..20a5e7fa 100644 --- a/sshdss.c +++ b/sshdss.c @@ -675,5 +675,6 @@ const struct ssh_signkey ssh_dss = { dss_verifysig, dss_sign, "ssh-dss", - "dss" + "dss", + NULL, }; diff --git a/sshecc.c b/sshecc.c index 84ab2477..ec2648b0 100644 --- a/sshecc.c +++ b/sshecc.c @@ -3473,6 +3473,7 @@ const struct ssh_signkey ssh_ecdsa_ed25519 = { ecdsa_sign, "ssh-ed25519", "ssh-ed25519", + NULL, }; const struct ssh_signkey ssh_ecdsa_nistp256 = { @@ -3490,6 +3491,7 @@ const struct ssh_signkey ssh_ecdsa_nistp256 = { ecdsa_sign, "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp256", + NULL, }; const struct ssh_signkey ssh_ecdsa_nistp384 = { @@ -3507,6 +3509,7 @@ const struct ssh_signkey ssh_ecdsa_nistp384 = { ecdsa_sign, "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp384", + NULL, }; const struct ssh_signkey ssh_ecdsa_nistp521 = { @@ -3524,6 +3527,7 @@ const struct ssh_signkey ssh_ecdsa_nistp521 = { ecdsa_sign, "ecdsa-sha2-nistp521", "ecdsa-sha2-nistp521", + NULL, }; /* ---------------------------------------------------------------------- @@ -3701,19 +3705,19 @@ void ssh_ecdhkex_freekey(void *key) } static const struct ssh_kex ssh_ec_kex_curve25519 = { - "curve25519-sha256@libssh.org", NULL, KEXTYPE_ECDH, NULL, NULL, 0, 0, &ssh_sha256 + "curve25519-sha256@libssh.org", NULL, KEXTYPE_ECDH, &ssh_sha256, NULL }; static const struct ssh_kex ssh_ec_kex_nistp256 = { - "ecdh-sha2-nistp256", NULL, KEXTYPE_ECDH, NULL, NULL, 0, 0, &ssh_sha256 + "ecdh-sha2-nistp256", NULL, KEXTYPE_ECDH, &ssh_sha256, NULL }; static const struct ssh_kex ssh_ec_kex_nistp384 = { - "ecdh-sha2-nistp384", NULL, KEXTYPE_ECDH, NULL, NULL, 0, 0, &ssh_sha384 + "ecdh-sha2-nistp384", NULL, KEXTYPE_ECDH, &ssh_sha384, NULL }; static const struct ssh_kex ssh_ec_kex_nistp521 = { - "ecdh-sha2-nistp521", NULL, KEXTYPE_ECDH, NULL, NULL, 0, 0, &ssh_sha512 + "ecdh-sha2-nistp521", NULL, KEXTYPE_ECDH, &ssh_sha512, NULL }; static const struct ssh_kex *const ec_kex_list[] = { diff --git a/sshrsa.c b/sshrsa.c index 32694456..850204c7 100644 --- a/sshrsa.c +++ b/sshrsa.c @@ -917,7 +917,8 @@ const struct ssh_signkey ssh_rsa = { rsa2_verifysig, rsa2_sign, "ssh-rsa", - "rsa2" + "rsa2", + NULL, }; void *ssh_rsakex_newkey(char *data, int len) @@ -1057,11 +1058,11 @@ void ssh_rsakex_encrypt(const struct ssh_hash *h, unsigned char *in, int inlen, } static const struct ssh_kex ssh_rsa_kex_sha1 = { - "rsa1024-sha1", NULL, KEXTYPE_RSA, NULL, NULL, 0, 0, &ssh_sha1 + "rsa1024-sha1", NULL, KEXTYPE_RSA, &ssh_sha1, NULL, }; static const struct ssh_kex ssh_rsa_kex_sha256 = { - "rsa2048-sha256", NULL, KEXTYPE_RSA, NULL, NULL, 0, 0, &ssh_sha256 + "rsa2048-sha256", NULL, KEXTYPE_RSA, &ssh_sha256, NULL, }; static const struct ssh_kex *const rsa_kex_list[] = {