Author: nextgens
Date: 2007-10-24 09:19:44 +0000 (Wed, 24 Oct 2007)
New Revision: 15518

Modified:
   trunk/freenet/src/freenet/crypt/DiffieHellman.java
   trunk/freenet/src/freenet/node/FNPPacketMangler.java
Log:
JFK:
        Strengthen the verification of DH parameters.

See http://securitytracker.com/alerts/2005/Aug/1014739.html for details

Modified: trunk/freenet/src/freenet/crypt/DiffieHellman.java
===================================================================
--- trunk/freenet/src/freenet/crypt/DiffieHellman.java  2007-10-24 08:30:18 UTC 
(rev 15517)
+++ trunk/freenet/src/freenet/crypt/DiffieHellman.java  2007-10-24 09:19:44 UTC 
(rev 15518)
@@ -6,6 +6,7 @@

 package freenet.crypt;

+import java.math.BigInteger;
 import java.util.Random;
 import java.util.Stack;

@@ -36,6 +37,9 @@
        private static Object precalcerWaitObj = new Object();

        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();
@@ -139,10 +143,52 @@
        private static NativeBigInteger[] genParams() {
                NativeBigInteger params[] = new NativeBigInteger[2];
                // Don't need NativeBigInteger?
-               params[0] = new NativeBigInteger(256, r);
-               params[1] = (NativeBigInteger) group.getG().modPow(params[0], 
group.getP());
+               
+               do {
+                       params[0] = new NativeBigInteger(256, r);
+                       params[1] = (NativeBigInteger) 
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
+        */
+       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)) {
+                       Logger.error(caller, "The provided exponential contains 
"+zerosCount+" zeros and "+onesCount+" ones wich is unacceptable!");
+                       return false;
+               }
+               
+               //TODO: Shall we test if p-1 = -1 here ?
+               
+               // Ensure that g^x > 2^24
+               if(MIN_EXPONENTIAL_VALUE.compareTo(exponential) > -1) {
+                       Logger.error(caller, "The provided exponential is 
smaller than 2^24 which is unacceptable!");
+                       return false;
+               }
+               // Ensure that g^x < (p - 2^24)
+               if(MAX_EXPONENTIAL_VALUE.compareTo(exponential) < 1) {
+                       Logger.error(DiffieHellman.class, "The provided 
exponential is bigger than (p - 2^24) which is unacceptable!");
+                       return false;
+               }
+               
+               return true;
+       }

        public static DHGroup getGroup() {
                return group;

Modified: trunk/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/FNPPacketMangler.java        2007-10-24 
08:30:18 UTC (rev 15517)
+++ trunk/freenet/src/freenet/node/FNPPacketMangler.java        2007-10-24 
09:19:44 UTC (rev 15518)
@@ -492,10 +492,10 @@
                byte[] hisExponential = new 
byte[DiffieHellman.modulusLengthInBytes()];
                System.arraycopy(payload, offset, hisExponential, 0, 
DiffieHellman.modulusLengthInBytes());
                NativeBigInteger _hisExponential = new 
NativeBigInteger(1,hisExponential);
-               if(_hisExponential.compareTo(NativeBigInteger.ONE) > 0) {
+               if(DiffieHellman.checkDHExponentialValidity(this.getClass(), 
_hisExponential)) {
                        sendJFKMessage2(nonceInitiator, hisExponential, pn, 
replyTo);
                }else
-                       Logger.error(this, "We can't accept the exponential 
"+pn+" sent us; it's smaller than 1!!");
+                       Logger.error(this, "We can't accept the exponential 
"+pn+" sent us!!");

                long t2=System.currentTimeMillis();
                if((t2-t1)>500)
@@ -671,8 +671,8 @@
                        return;
                }

-               if(_hisExponential.compareTo(NativeBigInteger.ONE) < 1) {
-                       Logger.error(this, "We can't accept the exponential 
"+pn+" sent us; it's smaller than 1!!");
+               if(!DiffieHellman.checkDHExponentialValidity(this.getClass(), 
_hisExponential)) {
+                       Logger.error(this, "We can't accept the exponential 
"+pn+" sent us!!");
                        return;
                }



Reply via email to