]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Don't try to agree a MAC we'll never use.
authorSimon Tatham <anakin@pobox.com>
Thu, 24 Sep 2015 10:41:43 +0000 (11:41 +0100)
committerSimon Tatham <anakin@pobox.com>
Thu, 24 Sep 2015 10:41:43 +0000 (11:41 +0100)
If we've chosen the ChaCha20-Poly1305 option for a cipher, then that
forces the use of its associated MAC. In that situation, we should
avoid even _trying_ to figure out a MAC by examining the MAC string
from the server's KEXINIT, because we won't use the MAC selected by
that method anyway, so there's no point imposing the requirement on
servers to present a MAC we believe in just so we know it's there.

This was breaking interoperation with tinysshd, and is in violation of
OpenSSH's spec for the "chacha20-poly1305@openssh.com" cipher.

ssh.c

diff --git a/ssh.c b/ssh.c
index 4979268f130b9c05a0d972306ec86cec869ac726..d53b392601db8bc1794b46e4f7ae13cc0de458c3 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -6568,6 +6568,24 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen,
                bombout(("KEXINIT packet was incomplete"));
                crStopV;
            }
+
+            /* If we've already selected a cipher which requires a
+             * particular MAC, then just select that, and don't even
+             * bother looking through the server's KEXINIT string for
+             * MACs. */
+            if (i == KEXLIST_CSMAC && s->cscipher_tobe &&
+                s->cscipher_tobe->required_mac) {
+                s->csmac_tobe = s->cscipher_tobe->required_mac;
+                s->csmac_etm_tobe = !!(s->csmac_tobe->etm_name);
+                goto matched;
+            }
+            if (i == KEXLIST_SCMAC && s->sccipher_tobe &&
+                s->sccipher_tobe->required_mac) {
+                s->scmac_tobe = s->sccipher_tobe->required_mac;
+                s->scmac_etm_tobe = !!(s->scmac_tobe->etm_name);
+                goto matched;
+            }
+
            for (j = 0; j < MAXKEXLIST; j++) {
                struct kexinit_algorithm *alg = &s->kexlists[i][j];
                if (alg->name == NULL) break;
@@ -6613,16 +6631,6 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen,
          matched:;
        }
 
-        /* If the cipher over-rides the mac, then pick it */
-        if (s->cscipher_tobe && s->cscipher_tobe->required_mac) {
-            s->csmac_tobe = s->cscipher_tobe->required_mac;
-           s->csmac_etm_tobe = !!(s->csmac_tobe->etm_name);
-        }
-        if (s->sccipher_tobe && s->sccipher_tobe->required_mac) {
-            s->scmac_tobe = s->sccipher_tobe->required_mac;
-           s->scmac_etm_tobe = !!(s->scmac_tobe->etm_name);
-        }
-
        if (s->pending_compression) {
            logevent("Server supports delayed compression; "
                     "will try this later");