X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/c6daaa1a4842b06f4eb0f7fef5f969d12b5020ce..6226c9390d23d6868edde63b9568891cd88631cc:/ssh.c diff --git a/ssh.c b/ssh.c index ba3dfad6..7c5c7bce 100644 --- a/ssh.c +++ b/ssh.c @@ -1,7 +1,12 @@ +/* + * SSH backend. + */ + #include #include #include #include +#include #include "putty.h" #include "tree234.h" @@ -708,7 +713,7 @@ struct ssh_tag { void *cs_comp_ctx, *sc_comp_ctx; const struct ssh_kex *kex; const struct ssh_signkey *hostkey; - unsigned char v2_session_id[32]; + unsigned char v2_session_id[SSH2_KEX_MAX_HASH_LEN]; int v2_session_id_len; void *kex_ctx; @@ -4964,7 +4969,10 @@ static int first_in_commasep_string(char *needle, char *haystack, int haylen) /* * SSH-2 key creation method. + * (Currently assumes 2 lots of any hash are sufficient to generate + * keys/IVs for any cipher/MAC. SSH2_MKKEY_ITERS documents this assumption.) */ +#define SSH2_MKKEY_ITERS (2) static void ssh2_mkkey(Ssh ssh, Bignum K, unsigned char *H, char chr, unsigned char *keyspace) { @@ -5011,7 +5019,7 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen, char *hostkeydata, *sigdata, *keystr, *fingerprint; int hostkeylen, siglen; void *hkey; /* actual host key */ - unsigned char exchange_hash[32]; + unsigned char exchange_hash[SSH2_KEX_MAX_HASH_LEN]; int n_preferred_kex; const struct ssh_kexes *preferred_kex[KEX_MAX]; int n_preferred_ciphers; @@ -5064,7 +5072,7 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen, s->preferred_kex[s->n_preferred_kex++] = &ssh_diffiehellman_group1; break; - case CIPHER_WARN: + case KEX_WARN: /* Flag for later. Don't bother if it's the last in * the list. */ if (i < KEX_MAX - 1) { @@ -5662,13 +5670,21 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen, * hash from the _first_ key exchange. */ { - unsigned char keyspace[40]; + unsigned char keyspace[SSH2_KEX_MAX_HASH_LEN * SSH2_MKKEY_ITERS]; + assert(sizeof(keyspace) >= ssh->kex->hash->hlen * SSH2_MKKEY_ITERS); ssh2_mkkey(ssh,s->K,s->exchange_hash,'C',keyspace); + assert((ssh->cscipher->keylen+7) / 8 <= + ssh->kex->hash->hlen * SSH2_MKKEY_ITERS); ssh->cscipher->setkey(ssh->cs_cipher_ctx, keyspace); ssh2_mkkey(ssh,s->K,s->exchange_hash,'A',keyspace); + assert(ssh->cscipher->blksize <= + ssh->kex->hash->hlen * SSH2_MKKEY_ITERS); ssh->cscipher->setiv(ssh->cs_cipher_ctx, keyspace); ssh2_mkkey(ssh,s->K,s->exchange_hash,'E',keyspace); + assert(ssh->csmac->len <= + ssh->kex->hash->hlen * SSH2_MKKEY_ITERS); ssh->csmac->setkey(ssh->cs_mac_ctx, keyspace); + memset(keyspace, 0, sizeof(keyspace)); } logeventf(ssh, "Initialised %.200s client->server encryption", @@ -5720,13 +5736,21 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen, * hash from the _first_ key exchange. */ { - unsigned char keyspace[40]; + unsigned char keyspace[SSH2_KEX_MAX_HASH_LEN * SSH2_MKKEY_ITERS]; + assert(sizeof(keyspace) >= ssh->kex->hash->hlen * SSH2_MKKEY_ITERS); ssh2_mkkey(ssh,s->K,s->exchange_hash,'D',keyspace); + assert((ssh->sccipher->keylen+7) / 8 <= + ssh->kex->hash->hlen * SSH2_MKKEY_ITERS); ssh->sccipher->setkey(ssh->sc_cipher_ctx, keyspace); ssh2_mkkey(ssh,s->K,s->exchange_hash,'B',keyspace); + assert(ssh->sccipher->blksize <= + ssh->kex->hash->hlen * SSH2_MKKEY_ITERS); ssh->sccipher->setiv(ssh->sc_cipher_ctx, keyspace); ssh2_mkkey(ssh,s->K,s->exchange_hash,'F',keyspace); + assert(ssh->scmac->len <= + ssh->kex->hash->hlen * SSH2_MKKEY_ITERS); ssh->scmac->setkey(ssh->sc_mac_ctx, keyspace); + memset(keyspace, 0, sizeof(keyspace)); } logeventf(ssh, "Initialised %.200s server->client encryption", ssh->sccipher->text_name); @@ -8701,10 +8725,10 @@ void ssh_send_port_open(void *channel, char *hostname, int port, char *org) } } -static Socket ssh_socket(void *handle) +static int ssh_connected(void *handle) { Ssh ssh = (Ssh) handle; - return ssh->s; + return ssh->s != NULL; } static int ssh_sendok(void *handle) @@ -8741,7 +8765,7 @@ static int ssh_return_exitcode(void *handle) if (ssh->s != NULL) return -1; else - return (ssh->exitcode >= 0 ? ssh->exitcode : 0); + return (ssh->exitcode >= 0 ? ssh->exitcode : INT_MAX); } /* @@ -8774,7 +8798,7 @@ Backend ssh_backend = { ssh_size, ssh_special, ssh_get_specials, - ssh_socket, + ssh_connected, ssh_return_exitcode, ssh_sendok, ssh_ldisc,