On Sun, Mar 01, 2015 at 08:21:17PM +0000, Colin Watson wrote:
> On Sun, Mar 01, 2015 at 01:21:32PM +0100, Moritz Muehlenhoff wrote:
> > This has been assigned CVE-2015-2157:
> > http://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/private-key-not-wiped-2.html
> 
> Thanks.  Fixed in unstable and unblocked.  I'd like to upload the
> attached debdiff to stable-security; would that be OK?  I can also work
> on a squeeze-lts upload once this is done.

That'll teach me to send mail before testing.  Here's a corrected
version that actually builds.

-- 
Colin Watson                                       [cjwat...@debian.org]
diff -Nru putty-0.62/debian/changelog putty-0.62/debian/changelog
--- putty-0.62/debian/changelog 2013-08-07 10:11:20.000000000 +0100
+++ putty-0.62/debian/changelog 2015-03-01 21:04:32.000000000 +0000
@@ -1,3 +1,14 @@
+putty (0.62-9+deb7u2) stable-security; urgency=high
+
+  * Backport from upstream:
+    - MATTA-2015-002: Enforce acceptable range for Diffie-Hellman server
+      value.
+    - Fix an erroneous length field in SSH-1 key load.
+    - CVE-2015-2157: Fix failure to clear sensitive private key information
+      from memory (closes: #779488).
+
+ -- Colin Watson <cjwat...@debian.org>  Sun, 01 Mar 2015 21:04:30 +0000
+
 putty (0.62-9+deb7u1) stable-security; urgency=high
 
   * CVE-2013-4206: Buffer underrun in modmul could corrupt the heap.
diff -Nru putty-0.62/debian/patches/enforce-dh-range.patch 
putty-0.62/debian/patches/enforce-dh-range.patch
--- putty-0.62/debian/patches/enforce-dh-range.patch    1970-01-01 
01:00:00.000000000 +0100
+++ putty-0.62/debian/patches/enforce-dh-range.patch    2015-03-01 
21:04:03.000000000 +0000
@@ -0,0 +1,77 @@
+Description: Enforce acceptable range for Diffie-Hellman server value
+ Florent Daigniere of Matta points out that RFC 4253 actually
+ _requires_ us to refuse to accept out-of-range values, though it isn't
+ completely clear to me why this should be a MUST on the receiving end.
+ .
+ Matta considers this to be a security vulnerability, on the grounds
+ that if a server should accidentally send an obviously useless value
+ such as 1 then we will fail to reject it and agree a key that an
+ eavesdropper could also figure out. Their id for this vulnerability is
+ MATTA-2015-002.
+Origin: backport, 
http://tartarus.org/~simon-git/gitweb/?p=putty.git;a=commitdiff;h=174476813f0ed94337aecc3e2d13a202a1dc2fa8
+Last-Update: 2015-03-01
+
+Index: b/ssh.c
+===================================================================
+--- a/ssh.c
++++ b/ssh.c
+@@ -6007,6 +6007,13 @@
+         }
+         ssh_pkt_getstring(pktin, &s->sigdata, &s->siglen);
+ 
++        {
++            const char *err = dh_validate_f(ssh->kex_ctx, s->f);
++            if (err) {
++                bombout(("key exchange reply failed validation: %s", err));
++                crStop(0);
++            }
++        }
+         s->K = dh_find_K(ssh->kex_ctx, s->f);
+ 
+         /* We assume everything from now on will be quick, and it might
+Index: b/ssh.h
+===================================================================
+--- a/ssh.h
++++ b/ssh.h
+@@ -470,6 +470,7 @@
+ void *dh_setup_gex(Bignum pval, Bignum gval);
+ void dh_cleanup(void *);
+ Bignum dh_create_e(void *, int nbits);
++const char *dh_validate_f(void *handle, Bignum f);
+ Bignum dh_find_K(void *, Bignum f);
+ 
+ int loadrsakey(const Filename *filename, struct RSAKey *key,
+Index: b/sshdh.c
+===================================================================
+--- a/sshdh.c
++++ b/sshdh.c
+@@ -219,6 +219,29 @@
+ }
+ 
+ /*
++ * DH stage 2-epsilon: given a number f, validate it to ensure it's in
++ * range. (RFC 4253 section 8: "Values of 'e' or 'f' that are not in
++ * the range [1, p-1] MUST NOT be sent or accepted by either side."
++ * Also, we rule out 1 and p-1 too, since that's easy to do and since
++ * they lead to obviously weak keys that even a passive eavesdropper
++ * can figure out.)
++ */
++const char *dh_validate_f(void *handle, Bignum f)
++{
++    struct dh_ctx *ctx = (struct dh_ctx *)handle;
++    if (bignum_cmp(f, One) <= 0) {
++        return "f value received is too small";
++    } else {
++        Bignum pm1 = bigsub(ctx->p, One);
++        int cmp = bignum_cmp(f, pm1);
++        freebn(pm1);
++        if (cmp >= 0)
++            return "f value received is too large";
++    }
++    return NULL;
++}
++
++/*
+  * DH stage 2: given a number f, compute K = f^x mod p.
+  */
+ Bignum dh_find_K(void *handle, Bignum f)
diff -Nru putty-0.62/debian/patches/private-key-not-wiped-2.patch 
putty-0.62/debian/patches/private-key-not-wiped-2.patch
--- putty-0.62/debian/patches/private-key-not-wiped-2.patch     1970-01-01 
01:00:00.000000000 +0100
+++ putty-0.62/debian/patches/private-key-not-wiped-2.patch     2015-03-01 
21:04:19.000000000 +0000
@@ -0,0 +1,60 @@
+Description: Add some missing memsets and sfrees
+ The absence of these could have prevented sensitive private key
+ information from being properly cleared out of memory that PuTTY tools
+ had finished with.
+ . 
+ Thanks to Patrick Coleman for spotting this and sending a patch.
+Origin: backport, 
http://tartarus.org/~simon-git/gitweb/?p=putty.git;a=commitdiff;h=65f69bca7363ceceeac515ae2a82b8f8adc6404d
+Bug: 
http://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/private-key-not-wiped-2.html
+Bug-Debian: http://bugs.debian.org/779488
+
+Index: b/sshpubk.c
+===================================================================
+--- a/sshpubk.c
++++ b/sshpubk.c
+@@ -839,6 +839,7 @@
+       goto error;
+     }
+     sfree(public_blob);
++    memset(private_blob, 0, private_blob_len);
+     sfree(private_blob);
+     sfree(encryption);
+     if (errorstr)
+@@ -859,8 +860,10 @@
+       sfree(mac);
+     if (public_blob)
+       sfree(public_blob);
+-    if (private_blob)
+-      sfree(private_blob);
++    if (private_blob) {
++        memset(private_blob, 0, private_blob_len);
++        sfree(private_blob);
++    }
+     if (errorstr)
+       *errorstr = error;
+     return ret;
+@@ -1144,8 +1147,14 @@
+     }
+ 
+     fp = f_open(*filename, "w", TRUE);
+-    if (!fp)
+-      return 0;
++    if (!fp) {
++        sfree(pub_blob);
++        memset(priv_blob, 0, priv_blob_len);
++        sfree(priv_blob);
++        memset(priv_blob_encrypted, 0, priv_blob_len);
++        sfree(priv_blob_encrypted);
++        return 0;
++    }
+     fprintf(fp, "PuTTY-User-Key-File-2: %s\n", key->alg->name);
+     fprintf(fp, "Encryption: %s\n", cipherstr);
+     fprintf(fp, "Comment: %s\n", key->comment);
+@@ -1162,6 +1171,7 @@
+     sfree(pub_blob);
+     memset(priv_blob, 0, priv_blob_len);
+     sfree(priv_blob);
++    memset(priv_blob_encrypted, 0, priv_blob_len);
+     sfree(priv_blob_encrypted);
+     return 1;
+ }
diff -Nru putty-0.62/debian/patches/series putty-0.62/debian/patches/series
--- putty-0.62/debian/patches/series    2013-08-07 10:09:08.000000000 +0100
+++ putty-0.62/debian/patches/series    2015-03-01 21:04:19.000000000 +0000
@@ -6,3 +6,6 @@
 vuln-bignum-division-by-zero.patch
 private-key-not-wiped.patch
 proactive-tightening.patch
+enforce-dh-range.patch
+ssh-1-key-load-length.patch
+private-key-not-wiped-2.patch
diff -Nru putty-0.62/debian/patches/ssh-1-key-load-length.patch 
putty-0.62/debian/patches/ssh-1-key-load-length.patch
--- putty-0.62/debian/patches/ssh-1-key-load-length.patch       1970-01-01 
01:00:00.000000000 +0100
+++ putty-0.62/debian/patches/ssh-1-key-load-length.patch       2015-03-01 
21:04:19.000000000 +0000
@@ -0,0 +1,22 @@
+Description: Fix an erroneous length field in SSH-1 key load
+ We incremented buf by a few bytes, so we must decrement the
+ corresponding length by the same amount, or else makekey() could
+ overrun.
+ . 
+ Thanks to Patrick Coleman for the patch.
+Origin: upstream, 
http://tartarus.org/~simon-git/gitweb/?p=putty.git;a=commitdiff;h=1f757928051b6d6ff231b2265bad2d263b0fe3ea
+Last-Update: 2015-03-01
+
+Index: b/sshpubk.c
+===================================================================
+--- a/sshpubk.c
++++ b/sshpubk.c
+@@ -67,7 +67,7 @@
+     i += 4;
+ 
+     /* Now the serious stuff. An ordinary SSH-1 public key. */
+-    i += makekey(buf + i, len, key, NULL, 1);
++    i += makekey(buf + i, len - i, key, NULL, 1);
+     if (i < 0)
+       goto end;                      /* overran */
+ 

Reply via email to