Author: jolantern
Date: 2007-12-07 00:03:30 +0000 (Fri, 07 Dec 2007)
New Revision: 16385

Removed:
   branches/legacy/unstable/lib/
Modified:
   branches/legacy/unstable/
   branches/legacy/unstable/src/freenet/Version.java
   branches/legacy/unstable/src/freenet/crypt/DiffieHellman.java
   branches/legacy/unstable/src/freenet/session/FnpLink.java
Log:
contrib:
* added as external reference (rev 16289)

lib:
* Created and removed by build.xml, so removed from SVN

src/freenet/crypt/DiffieHellman.java, src/freenet/session/FnpLink.java:
* Diffie-Hellman security fix from stable

src/freenet/Version.java:
* Bumping build number



Property changes on: branches/legacy/unstable
___________________________________________________________________
Name: svn:externals
   + contrib -r16289 https://emu.freenetproject.org/svn/branches/legacy/contrib


Modified: branches/legacy/unstable/src/freenet/Version.java
===================================================================
--- branches/legacy/unstable/src/freenet/Version.java   2007-12-07 00:02:31 UTC 
(rev 16384)
+++ branches/legacy/unstable/src/freenet/Version.java   2007-12-07 00:03:30 UTC 
(rev 16385)
@@ -21,7 +21,7 @@
        public static String altProtocolVersion = "1.52";

        /** The build number of the current revision */
-       public static final int buildNumber = 60277;
+       public static final int buildNumber = 60278;

        /** Oldest build of Fred we will talk to */
        public static final int lastGoodBuild = 60235;

Modified: branches/legacy/unstable/src/freenet/crypt/DiffieHellman.java
===================================================================
--- branches/legacy/unstable/src/freenet/crypt/DiffieHellman.java       
2007-12-07 00:02:31 UTC (rev 16384)
+++ branches/legacy/unstable/src/freenet/crypt/DiffieHellman.java       
2007-12-07 00:03:30 UTC (rev 16385)
@@ -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,51 @@
        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/unstable/src/freenet/session/FnpLink.java
===================================================================
--- branches/legacy/unstable/src/freenet/session/FnpLink.java   2007-12-07 
00:02:31 UTC (rev 16384)
+++ branches/legacy/unstable/src/freenet/session/FnpLink.java   2007-12-07 
00:03:30 UTC (rev 16385)
@@ -74,8 +74,8 @@
        // augmented
        // with debug logging and timings

-       //profiling
-       //WARNING:remove before release
+       // profiling
+       // WARNING:remove before release
        public static volatile int instances = 0;

        private static final Object profLock = new Object();
@@ -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);
@@ -547,8 +552,8 @@
                setInputStream(c, rawIn);
                Ya = (DSAIdentity) DSAIdentity.read(in);
                if(logDEBUG)
-                   Core.logger.log(this, "Read Ya: 
"+Ya.fingerprintToString()+": y="+
-                           Ya.getYAsHexString()+", group: "+Ya.getGroup(), 
Logger.DEBUG);
+                       Core.logger.log(this, "Read Ya: 
"+Ya.fingerprintToString()+": y="+
+                               Ya.getYAsHexString()+", group: "+Ya.getGroup(), 
Logger.DEBUG);
                byte[] Yabytes = Ya.asBytes();
                
//System.err.println(freenet.support.HexUtil.bytesToHex(Yabytes));
                //System.err.println(Ya.toString());
@@ -558,8 +563,8 @@
                M = new NativeBigInteger(1, ctx.digest());
                DSASignature sigYaCaCb = DSASignature.read(in);
                if(logDEBUG)
-                   Core.logger.log(this, "Read signature: "+sigYaCaCb+", M 
should be: "+M+
-                           ", Ya="+Ya.fingerprintToString(), Logger.DEBUG);
+                       Core.logger.log(this, "Read signature: "+sigYaCaCb+", M 
should be: "+M+
+                               ", Ya="+Ya.fingerprintToString(), Logger.DEBUG);
                if (!DSA.verify(Ya, sigYaCaCb, M)) {
                        String err = "Remote does not posess the private key to 
the public key it offered";
                        throw new 
AuthenticationFailedException(conn.getPeerAddress(), err);
@@ -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)
@@ -675,9 +686,9 @@
                //System.err.println("LALA " + pubMe.toString());
                pubMe.writeForWire(out);
                if(logDEBUG)
-                   Core.logger.log(this, "Written pubMe: 
"+pubMe.fingerprintToString()+
-                           ": y="+pubMe.getYAsHexString()+", 
"+pubMe.getGroup().toString(),
-                           Logger.DEBUG);
+                       Core.logger.log(this, "Written pubMe: 
"+pubMe.fingerprintToString()+
+                               ": y="+pubMe.getYAsHexString()+", 
"+pubMe.getGroup().toString(),
+                               Logger.DEBUG);
                long writtenPKTime = System.currentTimeMillis();
                long wplen = writtenPKTime - writtenIVTime;
                if (logDEBUG || wplen > 500)
@@ -707,7 +718,7 @@
                if (logDEBUG || wsiglen > 500)
                        Core.logger.log(this, "Written sig in " + wsiglen, 
wsiglen > 500 ? Logger.MINOR : Logger.DEBUG);
                if(logDEBUG)
-                   Core.logger.log(this, "Sig: "+sigYaCaCb+", M: "+M+" for 
"+pubMe.fingerprintToString(), Logger.DEBUG);
+                       Core.logger.log(this, "Sig: "+sigYaCaCb+", M: "+M+" for 
"+pubMe.fingerprintToString(), Logger.DEBUG);

                out.flush();
                long flushedAgainTime = System.currentTimeMillis();


Reply via email to