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();
