Hi,

it took me some time but I managed to subscribe to
this list through TOR. I've sent and canceled a
previous message, sorry for the confusion.

I've attached a patch for freenet 0.5. It fixes the
Diffie-Hellman exponential weakness. I hope I caught
every instance of this weakness in the code. Please
apply this patch and build freenet 0.5-5108.

"Nomen Nescio" kindly posted the patch to the support
list in the form in which I posted it on [EMAIL PROTECTED]
0.5. The only difference in the attached patch is that
the build.xml file remains unchanged, so you can use
your own build process.

Jack

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 
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;
_______________________________________________
Devl mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/devl

Reply via email to