Author: toad
Date: 2007-11-12 23:53:28 +0000 (Mon, 12 Nov 2007)
New Revision: 15773

Modified:
   branches/legacy/stable/src/freenet/Version.java
   branches/legacy/stable/src/freenet/crypt/DiffieHellman.java
   branches/legacy/stable/src/freenet/session/FnpLink.java
Log:
Apply patch from frost to fix weak keys bug in 0.5 (stable build 5108)

Modified: branches/legacy/stable/src/freenet/Version.java
===================================================================
--- branches/legacy/stable/src/freenet/Version.java     2007-11-11 22:47:19 UTC 
(rev 15772)
+++ branches/legacy/stable/src/freenet/Version.java     2007-11-12 23:53:28 UTC 
(rev 15773)
@@ -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;

Modified: branches/legacy/stable/src/freenet/crypt/DiffieHellman.java
===================================================================
--- branches/legacy/stable/src/freenet/crypt/DiffieHellman.java 2007-11-11 
22:47:19 UTC (rev 15772)
+++ branches/legacy/stable/src/freenet/crypt/DiffieHellman.java 2007-11-12 
23:53:28 UTC (rev 15773)
@@ -36,6 +36,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();
@@ -132,13 +135,55 @@
        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;
        }

+       
+       
 }

Modified: branches/legacy/stable/src/freenet/session/FnpLink.java
===================================================================
--- branches/legacy/stable/src/freenet/session/FnpLink.java     2007-11-11 
22:47:19 UTC (rev 15772)
+++ branches/legacy/stable/src/freenet/session/FnpLink.java     2007-11-12 
23:53:28 UTC (rev 15773)
@@ -497,6 +497,11 @@
             rawOut.flush();
         }
         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);
@@ -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)


Reply via email to