Restructure things so that a single entry in the KEX preference list can
authorben <ben@cda61777-01e9-0310-a592-d414129be87e>
Sat, 3 Sep 2005 13:41:43 +0000 (13:41 +0000)
committerben <ben@cda61777-01e9-0310-a592-d414129be87e>
Sat, 3 Sep 2005 13:41:43 +0000 (13:41 +0000)
correspond to multiple SSH-2 KEX algorithms.  We already do the equivalent
for cipher algorithms.

git-svn-id: svn://svn.tartarus.org/sgt/putty@6262 cda61777-01e9-0310-a592-d414129be87e

ssh.c
ssh.h
sshdh.c

diff --git a/ssh.c b/ssh.c
index 763e1fd..91bfa88 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -4996,7 +4996,7 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
        void *hkey;                    /* actual host key */
        unsigned char exchange_hash[20];
        int n_preferred_kex;
-       const struct ssh_kex *preferred_kex[KEX_MAX];
+       const struct ssh_kexes *preferred_kex[KEX_MAX];
        int n_preferred_ciphers;
        const struct ssh2_ciphers *preferred_ciphers[CIPHER_MAX];
        const struct ssh_compress *preferred_comp;
@@ -5119,12 +5119,14 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
        ssh2_pkt_addstring_start(s->pktout);
        commalist_started = 0;
        for (i = 0; i < s->n_preferred_kex; i++) {
-           const struct ssh_kex *k = s->preferred_kex[i];
+           const struct ssh_kexes *k = s->preferred_kex[i];
            if (!k) continue;          /* warning flag */
-           if (commalist_started)
-               ssh2_pkt_addstring_str(s->pktout, ",");
-           ssh2_pkt_addstring_str(s->pktout, s->preferred_kex[i]->name);
-           commalist_started = 1;
+           for (j = 0; j < k->nkexes; j++) {
+               if (commalist_started)
+                   ssh2_pkt_addstring_str(s->pktout, ",");
+               ssh2_pkt_addstring_str(s->pktout, k->list[j]->name);
+               commalist_started = 1;
+           }
        }
        /* List server host key algorithms. */
        ssh2_pkt_addstring_start(s->pktout);
@@ -5241,13 +5243,17 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
 
        preferred = NULL;
        for (i = 0; i < s->n_preferred_kex; i++) {
-           const struct ssh_kex *k = s->preferred_kex[i];
+           const struct ssh_kexes *k = s->preferred_kex[i];
            if (!k) {
                s->warn_kex = TRUE;
            } else {
-               if (!preferred) preferred = k->name;
-               if (in_commasep_string(k->name, str, len))
-                   ssh->kex = k;
+               for (j = 0; j < k->nkexes; j++) {
+                   if (!preferred) preferred = k->list[j]->name;
+                   if (in_commasep_string(k->list[j]->name, str, len)) {
+                       ssh->kex = k->list[j];
+                       break;
+                   }
+               }
            }
            if (ssh->kex)
                break;
@@ -5528,7 +5534,7 @@ static int 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 == &ssh_diffiehellman_gex) {
+    if (!ssh->kex->pdata) {
        hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits);
        hash_mpint(ssh->kex->hash, ssh->exhash, s->p);
        hash_mpint(ssh->kex->hash, ssh->exhash, s->g);
@@ -5717,7 +5723,7 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
      */
     freebn(s->f);
     freebn(s->K);
-    if (ssh->kex == &ssh_diffiehellman_gex) {
+    if (!ssh->kex->pdata) {
        freebn(s->g);
        freebn(s->p);
     }
diff --git a/ssh.h b/ssh.h
index 45405d3..43060c9 100644 (file)
--- a/ssh.h
+++ b/ssh.h
@@ -206,6 +206,11 @@ struct ssh_kex {
     const struct ssh_hash *hash;
 };
 
+struct ssh_kexes {
+    int nkexes;
+    const struct ssh_kex *const *list;
+};
+
 struct ssh_signkey {
     void *(*newkey) (char *data, int len);
     void (*freekey) (void *key);
@@ -256,9 +261,9 @@ extern const struct ssh2_ciphers ssh2_blowfish;
 extern const struct ssh2_ciphers ssh2_arcfour;
 extern const struct ssh_hash ssh_sha1;
 extern const struct ssh_hash ssh_sha256;
-extern const struct ssh_kex ssh_diffiehellman_group1;
-extern const struct ssh_kex ssh_diffiehellman_group14;
-extern const struct ssh_kex ssh_diffiehellman_gex;
+extern const struct ssh_kexes ssh_diffiehellman_group1;
+extern const struct ssh_kexes ssh_diffiehellman_group14;
+extern const struct ssh_kexes ssh_diffiehellman_gex;
 extern const struct ssh_signkey ssh_dss;
 extern const struct ssh_signkey ssh_rsa;
 extern const struct ssh_mac ssh_hmac_md5;
diff --git a/sshdh.c b/sshdh.c
index 9d24908..8d98462 100644 (file)
--- a/sshdh.c
+++ b/sshdh.c
@@ -46,21 +46,48 @@ static const unsigned char P14[] = {
  */
 static const unsigned char G[] = { 2 };
 
-const struct ssh_kex ssh_diffiehellman_group1 = {
+static const struct ssh_kex ssh_diffiehellman_group1_sha1 = {
     "diffie-hellman-group1-sha1", "group1",
     P1, G, lenof(P1), lenof(G), &ssh_sha1
 };
 
-const struct ssh_kex ssh_diffiehellman_group14 = {
+static const struct ssh_kex *const group1_list[] = {
+    &ssh_diffiehellman_group1_sha1
+};
+
+const struct ssh_kexes ssh_diffiehellman_group1 = {
+    sizeof(group1_list) / sizeof(*group1_list),
+    group1_list
+};
+
+static const struct ssh_kex ssh_diffiehellman_group14_sha1 = {
     "diffie-hellman-group14-sha1", "group14",
     P14, G, lenof(P14), lenof(G), &ssh_sha1
 };
 
-const struct ssh_kex ssh_diffiehellman_gex = {
+static const struct ssh_kex *const group14_list[] = {
+    &ssh_diffiehellman_group14_sha1
+};
+
+const struct ssh_kexes ssh_diffiehellman_group14 = {
+    sizeof(group14_list) / sizeof(*group14_list),
+    group14_list
+};
+
+static const struct ssh_kex ssh_diffiehellman_gex_sha1 = {
     "diffie-hellman-group-exchange-sha1", NULL,
     NULL, NULL, 0, 0, &ssh_sha1
 };
 
+static const struct ssh_kex *const gex_list[] = {
+    &ssh_diffiehellman_gex_sha1
+};
+
+const struct ssh_kexes ssh_diffiehellman_gex = {
+    sizeof(gex_list) / sizeof(*gex_list),
+    gex_list
+};
+
 /*
  * Variables.
  */