From 7a580aa4d82aebfe41ba6a02789e6f5231d83508 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Mon, 18 Dec 2000 09:20:08 +0000 Subject: [PATCH] Attempt to get repeated key exchange working in SSH2. Still under test - might not be 100%. I think it _ought_ to work though. [originally from svn r826] --- ssh.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/ssh.c b/ssh.c index a408836a..8aa6437d 100644 --- a/ssh.c +++ b/ssh.c @@ -231,7 +231,7 @@ struct Packet { long maxlen; }; -static SHA_State exhash; +static SHA_State exhash, exhashbase; static Socket s = NULL; @@ -1043,12 +1043,12 @@ static int do_ssh_init(unsigned char c) { * This is a v2 server. Begin v2 protocol. */ char *verstring = "SSH-2.0-PuTTY"; - SHA_Init(&exhash); + SHA_Init(&exhashbase); /* * Hash our version string and their version string. */ - sha_string(&exhash, verstring, strlen(verstring)); - sha_string(&exhash, vstring, strcspn(vstring, "\r\n")); + sha_string(&exhashbase, verstring, strlen(verstring)); + sha_string(&exhashbase, vstring, strcspn(vstring, "\r\n")); sprintf(vstring, "%s\n", verstring); sprintf(vlog, "We claim version: %s", verstring); logevent(vlog); @@ -1993,9 +1993,11 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt) static unsigned char keyspace[40]; static const struct ssh_cipher *preferred_cipher; static const struct ssh_compress *preferred_comp; + static int first_kex; crBegin; random_init(); + first_kex = 1; /* * Set up the preferred cipher and compression. @@ -2099,7 +2101,10 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt) ssh2_pkt_addbool(FALSE); /* Reserved. */ ssh2_pkt_adduint32(0); + + exhash = exhashbase; sha_string(&exhash, pktout.data+5, pktout.length-5); + ssh2_pkt_send(); if (!ispkt) crWaitUntil(ispkt); @@ -2274,6 +2279,19 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt) ssh2_mkkey(K, exchange_hash, 'E', keyspace); csmac->setcskey(keyspace); ssh2_mkkey(K, exchange_hash, 'F', keyspace); scmac->setsckey(keyspace); + /* + * If this is the first key exchange phase, we must pass the + * SSH2_MSG_NEWKEYS packet to the next layer, not because it + * wants to see it but because it will need time to initialise + * itself before it sees an actual packet. In subsequent key + * exchange phases, we don't pass SSH2_MSG_NEWKEYS on, because + * it would only confuse the layer above. + */ + if (!first_kex) { + crReturn(0); + } + first_kex = 0; + /* * Now we're encrypting. Begin returning 1 to the protocol main * function so that other things can run on top of the