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;
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);
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;
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);
*/
freebn(s->f);
freebn(s->K);
- if (ssh->kex == &ssh_diffiehellman_gex) {
+ if (!ssh->kex->pdata) {
freebn(s->g);
freebn(s->p);
}
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);
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;
*/
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.
*/