We will distribute a fixed release shortly.
On Fri, Nov 02, 2007 at 05:10:07AM +0100, Nomen Nescio wrote:
> (please excuse me if this is a duplicate)
>
> Toad,
>
> Recently a message by you was xposted to 0.5 about a crypto weakness you
> folks discovered in 0.7 that 0.5 is also subject to.
>
> After some discussion, one individual came up with a patch and procedure for
> fixing this on 0.5. While a lot will simply use that patch and build new
> freenet.jar executables, there are some who aren't up to it for whatever
> reason.
>
> Given the patch and the msg announcing it, would you be willing to create an
> 'official' freenet 0.5 build 5108 and make it available at the same place
> where the old 0.5 stuff is at http://downloads.freenetproject.org/ ?
>
> BTW- I know you and other freenet devs haven't been in the habit of doing so
> but would you also be willing to include a digital signature of some kind?
> At least an SHA-1 hash, preferably a detached pgp signature.
>
> Thanks
>
> Here's the message I mentioned, followed by the patch:
>
>
> ----- Jack O'Lantern ----- 2007.10.31 - 20:36:40GMT -----
>
> Happy Hallowe'en folks,
>
> a certain Toad recently informed us that the Diffie-Hellman key exchange in
> freenet 0.5 has been b0rked for about two years and we please bob for the
> solution to the issue ourselves. So, here goes...
>
> 1. obtain a JDK (sun5 works), svn, ant and junit.
>
> 2. obtain the source:
> $ svn co http://freenet.googlecode.com/svn/branches/legacy/stable/
> freenet-0.5-5108
> $ cd freenet-0.5-5108
> $ svn co http://freenet.googlecode.com/svn/branches/legacy/contrib/ contrib
>
> 3. copy freenet-ext.jar from your freenet directory into the newly created
> freenet-0.5-5108 directory (freenet-ext.jar remains unchanged)
>
> 4. obtain the patch I crafted:
> freenet:CHK at
> Sm50039W8Gt8kzLyMloGB6pvjkQNAwI,xYB4spgd2g1ZtJIYN0lfeg/freenet_dh.patch
>
> 5. Examine this patch closely. You don't know me. You never know beforehand
> if you're about to be tricked or treated, or handled by an incompetent person.
> This patch does the following things:
> a. creates a method to check for weak Diffie-Hellman exponents (imported
> from freenet 0.7)
> b. there are *extremely* few weak exponentials in the number space, so
> accidental creation of a weak exponential is *extremely* unlikely;
> nevertheless, the patch adds code to prevent creating weak exponents
> (imported from freenet 0.7)
> c. adds code to abort a Diffie-Hellman key exchange if our peer ("Bob")
> uses a weak key (logs an error) (two instances)
> d. bumps the build number up to 5108. I feel it's justified that we users
> hijack the build numbering scheme as the developers don't maintain it anymore.
>
> 6. If you're satisfied, copy this patch into the freenet-0.5-5108 directory.
>
> 7. Apply the patch:
> $ patch -p1 < freenet_dh.patch
>
> 8. Build freenet.jar
> $ CLASSPATH=freenet-ext.jar ant distclean dist
>
> 9. Make a backup of your old freenet.jar (freenet-ext.jar remains in place).
>
> 10. Copy the newly built freenet.jar to your freenet directory.
> $ cp lib/freenet.jar /path/to/freenet/dir
>
> 11. Restart freenet
>
> That's it. Enjoy your shiny new freenet build.
>
> It would be great if someone in contact with the freenet 0.7 developers could
> communicate the patch to them. I'm just a user, and some official
> acknowledgement that the patch does indeed fix *all* instances of weak
> Diffie-Hellman handling is appreciated because, you know, the comments in the
> freenet source are not exactly abundant and it's not easy for a newcomer to
> find one's way through.
>
> EOM
>
> Here's the patch:
> diff -Naur freenet-0.5-5107/build.xml freenet-0.5-5108/build.xml
> --- freenet-0.5-5107/build.xml 2007-10-31 18:12:46.000000000 +0100
> +++ freenet-0.5-5108/build.xml 2007-10-31 18:22:13.000000000 +0100
> @@ -22,8 +22,8 @@
> <property name="freenet-ext.location"
> location="${lib}/freenet-ext.jar"/>
> <!-- this is where the Contrib directory is supposed to be. Override
> this
> if necessary -->
> - <property name="contrib.location" location=".."/>
> - <property name="servlet.location"
> location="${contrib.location}/Contrib/freenet_ext/build_dir"/>
> + <property name="contrib.location" location="."/>
> + <property name="servlet.location"
> location="${contrib.location}/contrib/freenet_ext/build_dir"/>
>
> <!-- =======================================================================
> -->
> <target name="env"
> diff -Naur freenet-0.5-5107/src/freenet/crypt/DiffieHellman.java
> freenet-0.5-5108/src/freenet/crypt/DiffieHellman.java
> --- freenet-0.5-5107/src/freenet/crypt/DiffieHellman.java 2007-10-31
> 18:08:57.000000000 +0100
> +++ freenet-0.5-5108/src/freenet/crypt/DiffieHellman.java 2007-10-31
> 18:21:34.000000000 +0100
> @@ -11,6 +11,7 @@
> import java.util.Stack;
>
> import freenet.Core;
> +import freenet.support.Logger;
>
> public class DiffieHellman {
>
> @@ -37,6 +38,9 @@
>
> private static Thread precalcThread;
>
> + public static final BigInteger MIN_EXPONENTIAL_VALUE = new
> BigInteger("2").pow(24);
> + public static final BigInteger MAX_EXPONENTIAL_VALUE =
> group.getP().subtract(MIN_EXPONENTIAL_VALUE);
> +
> static {
> precalcThread = new PrecalcBufferFill();
> precalcThread.start();
> @@ -132,11 +136,53 @@
> private static BigInteger[] genParams() {
> BigInteger params[] = new BigInteger[2];
> // Don't need NativeBigInteger?
> - params[0] = new BigInteger(256, r);
> - params[1] = group.getG().modPow(params[0], group.getP());
> +
> + do {
> + params[0] = new BigInteger(256, r);
> + params[1] = group.getG().modPow(params[0],
> group.getP());
> + }
> while(!DiffieHellman.checkDHExponentialValidity(DiffieHellman.class,
> params[1]));
> +
> return params;
> }
>
> + /**
> + * Check the validity of a DH exponential
> + *
> + * @param a BigInteger: The exponential to test
> + * @return a boolean: whether the DH exponential provided is acceptable
> or not
> + *
> + * @see http://securitytracker.com/alerts/2005/Aug/1014739.html
> + * @see http://www.it.iitb.ac.in/~praj/acads/netsec/FinalReport.pdf
> + */
> + public static boolean checkDHExponentialValidity(Class caller,
> BigInteger exponential) {
> + int onesCount=0, zerosCount=0;
> +
> + // Ensure that we have at least 16 bits of each gender
> + for(int i=0; i < exponential.bitLength(); i++)
> + if(exponential.testBit(i))
> + onesCount++;
> + else
> + zerosCount++;
> + if((onesCount<16) || (zerosCount<16)) {
> + Core.logger.log(caller, "The provided exponential
> contains "+zerosCount+" zeros and "+onesCount+" ones wich is unacceptable!",
> Logger.ERROR);
> + return false;
> + }
> +
> + // Ensure that g^x > 2^24
> + if(MIN_EXPONENTIAL_VALUE.compareTo(exponential) > -1) {
> + Core.logger.log(caller, "The provided exponential is
> smaller than 2^24 which is unacceptable!", Logger.ERROR);
> + return false;
> + }
> + // Ensure that g^x < (p-2^24)
> + if(MAX_EXPONENTIAL_VALUE.compareTo(exponential) < 1) {
> + Core.logger.log(caller, "The provided exponential is
> bigger than (p - 2^24) which is unacceptable!", Logger.ERROR);
> + return false;
> + }
> +
> + return true;
> +
> + }
> +
> public static DHGroup getGroup() {
> return group;
> }
> diff -Naur freenet-0.5-5107/src/freenet/session/FnpLink.java
> freenet-0.5-5108/src/freenet/session/FnpLink.java
> --- freenet-0.5-5107/src/freenet/session/FnpLink.java 2007-10-31
> 18:05:39.000000000 +0100
> +++ freenet-0.5-5108/src/freenet/session/FnpLink.java 2007-10-31
> 18:21:53.000000000 +0100
> @@ -498,6 +498,11 @@
> }
> Ca = Util.readMPI(rawIn);
>
> + if(!DiffieHellman.checkDHExponentialValidity(this.getClass(), Ca)) {
> + String err = "Cannot accept remote exponential. WARNING: WITH
> HIGH PROBABILITY, THIS WAS A DELIBERATE ATTACK!";
> + throw new NegotiationFailedException(conn.getPeerAddress(),
> err);
> + }
> +
> Z = Ca.modPow(R, DiffieHellman.getGroup().getP());
> byte[] kent = Util.MPIbytes(Z);
> Util.makeKey(kent, k, 0, k.length);
> @@ -646,6 +651,12 @@
> }
>
> Cb = Util.readMPI(rawIn);
> +
> + if(!DiffieHellman.checkDHExponentialValidity(this.getClass(), Cb)) {
> + String err = "Cannot accept remote exponential. WARNING: WITH
> HIGH PROBABILITY, THIS WAS A DELIBERATE ATTACK!";
> + throw new NegotiationFailedException(conn.getPeerAddress(),
> err);
> + }
> +
> long readMPITime = System.currentTimeMillis();
> long readmpilen = readMPITime - readByteTime;
> if (logDEBUG || readmpilen > 500)
> diff -Naur freenet-0.5-5107/src/freenet/Version.java
> freenet-0.5-5108/src/freenet/Version.java
> --- freenet-0.5-5107/src/freenet/Version.java 2007-10-31 18:12:35.000000000
> +0100
> +++ freenet-0.5-5108/src/freenet/Version.java 2007-10-31 18:21:24.000000000
> +0100
> @@ -20,7 +20,7 @@
> public static String protocolVersion = "STABLE-1.51";
>
> /** The build number of the current revision */
> - public static final int buildNumber = 5107;
> + public static final int buildNumber = 5108;
>
> /** Oldest build of Fred we will talk to */
> public static final int lastGoodBuild = 5099;
> _______________________________________________
> Support mailing list
> Support at freenetproject.org
> http://news.gmane.org/gmane.network.freenet.support
> Unsubscribe at http://emu.freenetproject.org/cgi-bin/mailman/listinfo/support
> Or mailto:support-request at freenetproject.org?subject=unsubscribe