Attempt to get repeated key exchange working in SSH2. Still under
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Mon, 18 Dec 2000 09:20:08 +0000 (09:20 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Mon, 18 Dec 2000 09:20:08 +0000 (09:20 +0000)
test - might not be 100%. I think it _ought_ to work though.

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

ssh.c

diff --git a/ssh.c b/ssh.c
index a408836..8aa6437 100644 (file)
--- 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);
@@ -2275,6 +2280,19 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
     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
      * transport. If we ever see a KEXINIT, we must go back to the