X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/8479e33ca623ad057fadf5b48c0638f42d9b4520..0a3f1d48f7f8779690073685f057bc5705d61006:/ssh.c diff --git a/ssh.c b/ssh.c index c239eb22..5996fd39 100644 --- a/ssh.c +++ b/ssh.c @@ -165,13 +165,11 @@ enum { PKT_END, PKT_INT, PKT_CHAR, PKT_DATA, PKT_STR, PKT_BIGNUM }; #define crWaitUntilV(c) do { crReturnV; } while (!(c)) extern const struct ssh_cipher ssh_3des; -extern const struct ssh_cipher ssh_3des_ssh2; +extern const struct ssh2_ciphers ssh2_3des; extern const struct ssh_cipher ssh_des; -extern const struct ssh_cipher ssh_aes128_ssh2; -extern const struct ssh_cipher ssh_aes192_ssh2; -extern const struct ssh_cipher ssh_aes256_ssh2; +extern const struct ssh2_ciphers ssh2_aes; extern const struct ssh_cipher ssh_blowfish_ssh1; -extern const struct ssh_cipher ssh_blowfish_ssh2; +extern const struct ssh2_ciphers ssh2_blowfish; extern char *x11_init (Socket *, char *, void *); extern void x11_close (Socket); @@ -184,12 +182,10 @@ extern void x11_invent_auth(char *, int, char *, int); * SSH1. (3DES uses outer chaining; Blowfish has the opposite * endianness and different-sized keys.) */ -const static struct ssh_cipher *ciphers[] = { - &ssh_aes256_ssh2, - &ssh_aes192_ssh2, - &ssh_aes128_ssh2, - &ssh_blowfish_ssh2, - &ssh_3des_ssh2 +const static struct ssh2_ciphers *ciphers[] = { + &ssh2_aes, + &ssh2_blowfish, + &ssh2_3des, }; extern const struct ssh_kex ssh_diffiehellman; @@ -278,8 +274,8 @@ static int ssh1_compressing; static int ssh_agentfwd_enabled; static int ssh_X11_fwd_enabled; static const struct ssh_cipher *cipher = NULL; -static const struct ssh_cipher *cscipher = NULL; -static const struct ssh_cipher *sccipher = NULL; +static const struct ssh2_cipher *cscipher = NULL; +static const struct ssh2_cipher *sccipher = NULL; static const struct ssh_mac *csmac = NULL; static const struct ssh_mac *scmac = NULL; static const struct ssh_compress *cscomp = NULL; @@ -1396,9 +1392,15 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt) logevent("Encrypted session key"); - cipher_type = cfg.cipher == CIPHER_BLOWFISH ? SSH_CIPHER_BLOWFISH : - cfg.cipher == CIPHER_DES ? SSH_CIPHER_DES : - SSH_CIPHER_3DES; + switch (cfg.cipher) { + case CIPHER_BLOWFISH: cipher_type = SSH_CIPHER_BLOWFISH; break; + case CIPHER_DES: cipher_type = SSH_CIPHER_DES; break; + case CIPHER_3DES: cipher_type = SSH_CIPHER_3DES; break; + case CIPHER_AES: + c_write("AES not supported in SSH1, falling back to 3DES\r\n", 49); + cipher_type = SSH_CIPHER_3DES; + break; + } if ((supported_ciphers_mask & (1 << cipher_type)) == 0) { c_write("Selected cipher not supported, falling back to 3DES\r\n", 53); cipher_type = SSH_CIPHER_3DES; @@ -2181,14 +2183,14 @@ static void ssh2_mkkey(Bignum K, char *H, char *sessid, char chr, char *keyspace */ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt) { - static int i, len, nbits; + static int i, j, len, nbits; static char *str; static Bignum p, g, e, f, K; static int kex_init_value, kex_reply_value; static const struct ssh_mac **maclist; static int nmacs; - static const struct ssh_cipher *cscipher_tobe = NULL; - static const struct ssh_cipher *sccipher_tobe = NULL; + static const struct ssh2_cipher *cscipher_tobe = NULL; + static const struct ssh2_cipher *sccipher_tobe = NULL; static const struct ssh_mac *csmac_tobe = NULL; static const struct ssh_mac *scmac_tobe = NULL; static const struct ssh_compress *cscomp_tobe = NULL; @@ -2199,7 +2201,7 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt) static unsigned char exchange_hash[20]; static unsigned char first_exchange_hash[20]; static unsigned char keyspace[40]; - static const struct ssh_cipher *preferred_cipher; + static const struct ssh2_ciphers *preferred_cipher; static const struct ssh_compress *preferred_comp; static int first_kex; @@ -2211,15 +2213,17 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt) * Set up the preferred cipher and compression. */ if (cfg.cipher == CIPHER_BLOWFISH) { - preferred_cipher = &ssh_blowfish_ssh2; + preferred_cipher = &ssh2_blowfish; } else if (cfg.cipher == CIPHER_DES) { logevent("Single DES not supported in SSH2; using 3DES"); - preferred_cipher = &ssh_3des_ssh2; + preferred_cipher = &ssh2_3des; } else if (cfg.cipher == CIPHER_3DES) { - preferred_cipher = &ssh_3des_ssh2; + preferred_cipher = &ssh2_3des; + } else if (cfg.cipher == CIPHER_AES) { + preferred_cipher = &ssh2_aes; } else { /* Shouldn't happen, but we do want to initialise to _something_. */ - preferred_cipher = &ssh_3des_ssh2; + preferred_cipher = &ssh2_3des; } if (cfg.compression) preferred_comp = &ssh_zlib; @@ -2258,18 +2262,22 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt) /* List client->server encryption algorithms. */ ssh2_pkt_addstring_start(); for (i = 0; i < lenof(ciphers)+1; i++) { - const struct ssh_cipher *c = i==0 ? preferred_cipher : ciphers[i-1]; - ssh2_pkt_addstring_str(c->name); - if (i < lenof(ciphers)) - ssh2_pkt_addstring_str(","); + const struct ssh2_ciphers *c = i==0 ? preferred_cipher : ciphers[i-1]; + for (j = 0; j < c->nciphers; j++) { + ssh2_pkt_addstring_str(c->list[j]->name); + if (i < lenof(ciphers) || j < c->nciphers-1) + ssh2_pkt_addstring_str(","); + } } /* List server->client encryption algorithms. */ ssh2_pkt_addstring_start(); for (i = 0; i < lenof(ciphers)+1; i++) { - const struct ssh_cipher *c = i==0 ? preferred_cipher : ciphers[i-1]; - ssh2_pkt_addstring_str(c->name); - if (i < lenof(ciphers)) - ssh2_pkt_addstring_str(","); + const struct ssh2_ciphers *c = i==0 ? preferred_cipher : ciphers[i-1]; + for (j = 0; j < c->nciphers; j++) { + ssh2_pkt_addstring_str(c->list[j]->name); + if (i < lenof(ciphers) || j < c->nciphers-1) + ssh2_pkt_addstring_str(","); + } } /* List client->server MAC algorithms. */ ssh2_pkt_addstring_start(); @@ -2345,19 +2353,27 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt) } ssh2_pkt_getstring(&str, &len); /* client->server cipher */ for (i = 0; i < lenof(ciphers)+1; i++) { - const struct ssh_cipher *c = i==0 ? preferred_cipher : ciphers[i-1]; - if (in_commasep_string(c->name, str, len)) { - cscipher_tobe = c; - break; + const struct ssh2_ciphers *c = i==0 ? preferred_cipher : ciphers[i-1]; + for (j = 0; j < c->nciphers; j++) { + if (in_commasep_string(c->list[j]->name, str, len)) { + cscipher_tobe = c->list[j]; + break; + } } + if (cscipher_tobe) + break; } ssh2_pkt_getstring(&str, &len); /* server->client cipher */ for (i = 0; i < lenof(ciphers)+1; i++) { - const struct ssh_cipher *c = i==0 ? preferred_cipher : ciphers[i-1]; - if (in_commasep_string(c->name, str, len)) { - sccipher_tobe = c; - break; + const struct ssh2_ciphers *c = i==0 ? preferred_cipher : ciphers[i-1]; + for (j = 0; j < c->nciphers; j++) { + if (in_commasep_string(c->list[j]->name, str, len)) { + sccipher_tobe = c->list[j]; + break; + } } + if (sccipher_tobe) + break; } ssh2_pkt_getstring(&str, &len); /* client->server mac */ for (i = 0; i < nmacs; i++) {