diff --git a/router/java/src/net/i2p/router/CommSystemFacade.java b/router/java/src/net/i2p/router/CommSystemFacade.java index 22ea62f2d..8051f8f9a 100644 --- a/router/java/src/net/i2p/router/CommSystemFacade.java +++ b/router/java/src/net/i2p/router/CommSystemFacade.java @@ -21,7 +21,6 @@ import net.i2p.data.Hash; import net.i2p.data.router.RouterAddress; import net.i2p.data.router.RouterInfo; import net.i2p.router.transport.Transport; -import net.i2p.router.transport.crypto.DHSessionKeyBuilder; import net.i2p.router.transport.crypto.X25519KeyFactory; import net.i2p.util.Translate; @@ -207,12 +206,6 @@ public abstract class CommSystemFacade implements Service { */ public void unregisterTransport(Transport t) {} - /** - * Hook for pluggable transport creation. - * @since 0.9.16 - */ - public DHSessionKeyBuilder.Factory getDHFactory() { return null; } - /** * Factory for making X25519 key pairs. * @since 0.9.46 diff --git a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java index ca3e43f82..741c99014 100644 --- a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java +++ b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java @@ -27,7 +27,6 @@ import net.i2p.data.router.RouterInfo; import net.i2p.router.CommSystemFacade; import net.i2p.router.OutNetMessage; import net.i2p.router.RouterContext; -import net.i2p.router.transport.crypto.DHSessionKeyBuilder; import net.i2p.router.transport.crypto.X25519KeyFactory; import net.i2p.router.transport.udp.UDPTransport; import net.i2p.router.util.EventLog; @@ -452,16 +451,6 @@ public class CommSystemFacadeImpl extends CommSystemFacade { _manager.stopAndUnregister(t); } - /** - * Hook for pluggable transport creation. - * - * @since 0.9.16 - */ - @Override - public DHSessionKeyBuilder.Factory getDHFactory() { - return _manager.getDHFactory(); - } - /** * Factory for making X25519 key pairs. * @since 0.9.46 diff --git a/router/java/src/net/i2p/router/transport/TransportManager.java b/router/java/src/net/i2p/router/transport/TransportManager.java index 916d1e4f0..39278ae38 100644 --- a/router/java/src/net/i2p/router/transport/TransportManager.java +++ b/router/java/src/net/i2p/router/transport/TransportManager.java @@ -40,7 +40,6 @@ import net.i2p.router.CommSystemFacade.Status; import net.i2p.router.OutNetMessage; import net.i2p.router.RouterContext; import static net.i2p.router.transport.Transport.AddressSource.*; -import net.i2p.router.transport.crypto.DHSessionKeyBuilder; import net.i2p.router.transport.crypto.X25519KeyFactory; import net.i2p.router.transport.ntcp.NTCPTransport; import net.i2p.router.transport.udp.UDPTransport; @@ -75,7 +74,6 @@ public class TransportManager implements TransportEventListener { private final RouterContext _context; private final UPnPManager _upnpManager; private final SimpleTimer2.TimedEvent _upnpRefresher; - private final DHSessionKeyBuilder.PrecalcRunner _dhThread; private final X25519KeyFactory _xdhThread; private final boolean _enableUDP; private final boolean _enableNTCP1; @@ -123,7 +121,6 @@ public class TransportManager implements TransportEventListener { _enableUDP = _context.getBooleanPropertyDefaultTrue(PROP_ENABLE_UDP); _enableNTCP1 = false; boolean enableNTCP2 = isNTCPEnabled(context); - _dhThread = (_enableUDP || enableNTCP2) ? new DHSessionKeyBuilder.PrecalcRunner(context) : null; // always created, even if NTCP2 is not enabled, because ratchet needs it _xdhThread = new X25519KeyFactory(context); _msgIDBloomXor = _context.random().nextLong(I2NPMessage.MAX_ID_VALUE); @@ -221,16 +218,6 @@ public class TransportManager implements TransportEventListener { _context.router().rebuildRouterInfo(); } - /** - * Hook for pluggable transport creation. - * - * @return null if both NTCP1 and SSU are disabled - * @since 0.9.16 - */ - DHSessionKeyBuilder.Factory getDHFactory() { - return _dhThread; - } - /** * Factory for making X25519 key pairs. * @since 0.9.46 @@ -263,7 +250,7 @@ public class TransportManager implements TransportEventListener { initializeAddress(udp); } if (isNTCPEnabled(_context)) { - Transport ntcp = new NTCPTransport(_context, null, _xdhThread); + Transport ntcp = new NTCPTransport(_context, _xdhThread); addTransport(ntcp); initializeAddress(ntcp); if (udp != null) { @@ -435,8 +422,6 @@ public class TransportManager implements TransportEventListener { } synchronized void startListening() { - if (_dhThread != null && _dhThread.getState() == Thread.State.NEW) - _dhThread.start(); if (_xdhThread != null && _xdhThread.getState() == Thread.State.NEW) _xdhThread.start(); // For now, only start UPnP if we have no publicly-routable addresses @@ -504,8 +489,6 @@ public class TransportManager implements TransportEventListener { */ synchronized void shutdown() { stopListening(); - if (_dhThread != null) - _dhThread.shutdown(); if (_xdhThread != null) _xdhThread.shutdown(); Addresses.clearCaches(); diff --git a/router/java/src/net/i2p/router/transport/crypto/DHSessionKeyBuilder.java b/router/java/src/net/i2p/router/transport/crypto/DHSessionKeyBuilder.java deleted file mode 100644 index 11a6deb3f..000000000 --- a/router/java/src/net/i2p/router/transport/crypto/DHSessionKeyBuilder.java +++ /dev/null @@ -1,620 +0,0 @@ -package net.i2p.router.transport.crypto; - -/* - * free (adj.): unencumbered; not under the control of others - * Written by jrandom in 2003 and released into the public domain - * with no warranty of any kind, either expressed or implied. - * It probably won't make your computer catch on fire, or eat - * your children, but it might. Use at your own risk. - * - */ - -//import java.io.InputStream; -//import java.io.OutputStream; -import java.math.BigInteger; -import java.security.InvalidKeyException; -import java.util.concurrent.LinkedBlockingQueue; - -import net.i2p.I2PAppContext; -import net.i2p.I2PException; -import net.i2p.crypto.CryptoConstants; -import net.i2p.crypto.SHA256Generator; -import net.i2p.crypto.SigUtil; -import net.i2p.data.ByteArray; -//import net.i2p.data.DataHelper; -import net.i2p.data.SessionKey; -import net.i2p.util.I2PThread; -import net.i2p.util.Log; -import net.i2p.util.NativeBigInteger; -import net.i2p.util.RandomSource; -import net.i2p.util.SystemVersion; - -/** - * Generate a new session key through a diffie hellman exchange. This uses the - * constants defined in CryptoConstants, which causes the exchange to create a - * 256 bit session key. - * - * This class precalcs a set of values on its own thread. - * Whenever the pool has - * less than the minimum, it fills it up again to the max. There is a delay after - * each precalculation so that the CPU isn't hosed during startup. - * These three parameters are controlled by java environmental variables and - * can be adjusted via: - * -Dcrypto.dh.precalc.min=40 -Dcrypto.dh.precalc.max=100 -Dcrypto.dh.precalc.delay=60000 - * - * (delay is milliseconds) - * - * To disable precalculation, set min to 0 - * - * @since 0.9 moved from net.i2p.crypto - * - * @author jrandom - */ -public class DHSessionKeyBuilder { - - // the data of importance - private final BigInteger _myPrivateValue; - private final BigInteger _myPublicValue; - private BigInteger _peerValue; - private SessionKey _sessionKey; - private final ByteArray _extraExchangedBytes; // bytes after the session key from the DH exchange - - private final static String PROP_DH_PRECALC_MIN = "crypto.dh.precalc.min"; - private final static String PROP_DH_PRECALC_MAX = "crypto.dh.precalc.max"; - private final static String PROP_DH_PRECALC_DELAY = "crypto.dh.precalc.delay"; - private final static int DEFAULT_DH_PRECALC_MIN = 20; - private final static int DEFAULT_DH_PRECALC_MAX = 60; - private final static int DEFAULT_DH_PRECALC_DELAY = 25; - - /** - * Create a new public/private value pair for the DH exchange. - * Only for internal use and unit tests. - * Others should get instances from PrecalcRunner.getBuilder() - */ - DHSessionKeyBuilder() { - this(I2PAppContext.getGlobalContext()); - } - - /** - * Create a new public/private value pair for the DH exchange. - * Only for internal use and unit tests. - * Others should get instances from PrecalcRunner.getBuilder() - */ - DHSessionKeyBuilder(I2PAppContext ctx) { - _myPrivateValue = new NativeBigInteger(ctx.keyGenerator().getElGamalExponentSize(), ctx.random()); - _myPublicValue = CryptoConstants.elgg.modPow(_myPrivateValue, CryptoConstants.elgp); - _extraExchangedBytes = new ByteArray(); - } - - /** - * Conduct a DH exchange over the streams, returning the resulting data. - * - * unused - * @return exchanged data - * @throws IOException if there is an error (but does not close the streams - */ -/**** - public static DHSessionKeyBuilder exchangeKeys(InputStream in, OutputStream out) throws IOException { - DHSessionKeyBuilder builder = new DHSessionKeyBuilder(); - - // send: X - writeBigI(out, builder.getMyPublicValue()); - - // read: Y - BigInteger Y = readBigI(in); - if (Y == null) return null; - try { - builder.setPeerPublicValue(Y); - return builder; - } catch (InvalidPublicParameterException ippe) { - if (_log.shouldLog(Log.ERROR)) - _log.error("Key exchange failed (hostile peer?)", ippe); - return null; - } - } -****/ - - /** - * unused - */ -/**** - private static BigInteger readBigI(InputStream in) throws IOException { - byte Y[] = new byte[256]; - int read = DataHelper.read(in, Y); - if (read != 256) { - return null; - } - return new NativeBigInteger(1, Y); - } -****/ - - /** - * Write out the integer as a 256 byte value. This left pads with 0s so - * to keep in 2s complement, and if it is already 257 bytes (due to - * the sign bit) ignore that first byte. - * - * unused - */ -/**** - private static void writeBigI(OutputStream out, BigInteger val) throws IOException { - byte x[] = val.toByteArray(); - for (int i = x.length; i < 256; i++) - out.write(0); - if (x.length == 257) - out.write(x, 1, 256); - else if (x.length == 256) - out.write(x); - else if (x.length > 257) - throw new IllegalArgumentException("Value is too large! length="+x.length); - - out.flush(); - } -****/ - - /** - * Retrieve the private value used by the local participant in the DH exchange - * unused - */ -/* - public BigInteger getMyPrivateValue() { - return _myPrivateValue; - } -*/ - - /** - * Retrieve the public value used by the local participant in the DH exchange, - */ - public BigInteger getMyPublicValue() { - return _myPublicValue; - } - - /** - * Return a 256 byte representation of our public key, with leading 0s - * if necessary. - * - */ - public byte[] getMyPublicValueBytes() { - return toByteArray(getMyPublicValue()); - } - - /** - * @return exactly 256 bytes - * @throws IllegalArgumentException if requires more than 256 bytes - */ - private static final byte[] toByteArray(BigInteger bi) { - try { - return SigUtil.rectify(bi, 256); - } catch (InvalidKeyException ike) { - throw new IllegalArgumentException(ike); - } - } - - /** - * Specify the value given by the peer for use in the session key negotiation - * @throws IllegalStateException if already set - */ - public synchronized void setPeerPublicValue(BigInteger peerVal) throws InvalidPublicParameterException { - if (_peerValue != null) { - if (!_peerValue.equals(peerVal)) - throw new IllegalStateException(); - return; - } - validatePublic(peerVal); - _peerValue = peerVal; - } - - /** - * @param val 256 bytes - */ - public void setPeerPublicValue(byte val[]) throws InvalidPublicParameterException { - if (val.length != 256) - throw new IllegalArgumentException("Peer public value must be exactly 256 bytes"); - setPeerPublicValue(new NativeBigInteger(1, val)); - } - - public synchronized BigInteger getPeerPublicValue() { - return _peerValue; - } - - /** - * Return a 256 byte representation of his public key, with leading 0s - * if necessary. - * - */ - public byte[] getPeerPublicValueBytes() { - return toByteArray(getPeerPublicValue()); - } - - /** - * Retrieve the session key, calculating it if necessary (and if possible). - * - * @return session key exchanged, or null if the exchange is not complete - */ - public synchronized SessionKey getSessionKey() { - if (_sessionKey != null) return _sessionKey; - if (_peerValue != null) { - _sessionKey = calculateSessionKey(_myPrivateValue, _peerValue); - } else { - //System.err.println("Not ready yet.. privateValue and peerValue must be set (" - // + (_myPrivateValue != null ? "set" : "null") + "," - // + (_peerValue != null ? "set" : "null") + ")"); - } - return _sessionKey; - } - - /** - * Retrieve the extra bytes beyond the session key resulting from the DH exchange. - * If there aren't enough bytes (with all of them being consumed by the 32 byte key), - * the SHA256 of the key itself is used - but that won't ever happen. - * - * Used only by UDP. getData() will be non-null and have at least 32 bytes after call to getSessionKey() - * - * @return non-null (but rv.getData() may be null) - */ - public ByteArray getExtraBytes() { - return _extraExchangedBytes; - } - - /** - * Calculate a session key based on the private value and the public peer value. - * - * This is the first 32 bytes of the exchanged key (nominally 256 bytes), - * EXCEPT that the first byte will be zero if the most significant bit was a 1 - * (Java BigInteger.toByteArray() format) - * - * Side effect - sets extraExchangedBytes to the next 32 bytes. - */ - private final SessionKey calculateSessionKey(BigInteger myPrivateValue, BigInteger publicPeerValue) { - long start = System.currentTimeMillis(); - SessionKey key = new SessionKey(); - BigInteger exchangedKey = publicPeerValue.modPow(myPrivateValue, CryptoConstants.elgp); - // surprise! leading zero byte half the time! - // probably was a mistake, too late now... - byte buf[] = exchangedKey.toByteArray(); - byte val[] = new byte[SessionKey.KEYSIZE_BYTES]; - if (buf.length < 2 * SessionKey.KEYSIZE_BYTES) { - // UDP requires at least 32 bytes in _extraExchangedBytes for the mac key - // Won't ever happen, typ buf is 256 or 257 bytes - System.arraycopy(buf, 0, val, 0, Math.min(buf.length, SessionKey.KEYSIZE_BYTES)); - byte remaining[] = new byte[SessionKey.KEYSIZE_BYTES]; // == Hash.HASH_LENGTH - // non-caching version - SHA256Generator.getInstance().calculateHash(buf, 0, buf.length, remaining, 0); - _extraExchangedBytes.setData(remaining); - //if (_log.shouldLog(Log.DEBUG)) - // _log.debug("Storing " + remaining.length + " bytes from the DH exchange by SHA256 the session key"); - } else { - // Will always be here, typ buf is 256 or 257 bytes - System.arraycopy(buf, 0, val, 0, SessionKey.KEYSIZE_BYTES); - // feed the extra bytes into the PRNG - RandomSource.getInstance().harvester().feedEntropy("DH", buf, val.length, buf.length-val.length); - byte remaining[] = new byte[buf.length - val.length]; - System.arraycopy(buf, val.length, remaining, 0, remaining.length); - _extraExchangedBytes.setData(remaining); - //if (_log.shouldLog(Log.DEBUG)) - // _log.debug("Storing " + remaining.length + " bytes from the end of the DH exchange"); - } - key.setData(val); - long end = System.currentTimeMillis(); - long diff = end - start; - - I2PAppContext.getGlobalContext().statManager().addRateData("crypto.dhCalculateSessionTime", diff); - //if (diff > 1000) { - // if (_log.shouldLog(Log.WARN)) _log.warn("Generating session key took too long (" + diff + " ms"); - //} else { - // if (_log.shouldLog(Log.DEBUG)) _log.debug("Generating session key " + diff + " ms"); - //} - return key; - } - - /** - * rfc2631: - * The following algorithm MAY be used to validate a received public key y. - * - * 1. Verify that y lies within the interval [2,p-1]. If it does not, - * the key is invalid. - * 2. Compute y^q mod p. If the result == 1, the key is valid. - * Otherwise the key is invalid. - */ - private static final void validatePublic(BigInteger publicValue) throws InvalidPublicParameterException { - int cmp = publicValue.compareTo(NativeBigInteger.ONE); - if (cmp <= 0) - throw new InvalidPublicParameterException("Public value is below two: " + publicValue.toString()); - - cmp = publicValue.compareTo(CryptoConstants.elgp); - if (cmp >= 0) - throw new InvalidPublicParameterException("Public value is above p-1: " + publicValue.toString()); - - // todo: - // whatever validation needs to be done to mirror the rfc's part 2 (we don't have a q, so can't do - // if (NativeBigInteger.ONE.compareTo(publicValue.modPow(q, CryptoConstants.elgp)) != 0) - // throw new InvalidPublicParameterException("Invalid public value with y^q mod p != 1"); - // - } - - /* - private static void testValidation() { - NativeBigInteger bi = new NativeBigInteger("-3416069082912684797963255430346582466254460710249795973742848334283491150671563023437888953432878859472362439146158925287289114133666004165938814597775594104058593692562989626922979416277152479694258099203456493995467386903611666213773085025718340335205240293383622352894862685806192183268523899615405287022135356656720938278415659792084974076416864813957028335830794117802560169423133816961503981757298122040391506600117301607823659479051969827845787626261515313227076880722069706394405554113103165334903531980102626092646197079218895216346725765704256096661045699444128316078549709132753443706200863682650825635513"); - try { - validatePublic(bi); - System.err.println("valid?!"); - } catch (InvalidPublicParameterException ippe) { - System.err.println("Ok, invalid. cool"); - } - - byte val[] = bi.toByteArray(); - System.out.println("Len: " + val.length + " first is ok? " + ( (val[0] & 0x80) == 1) - + "\n" + DataHelper.toString(val, 64)); - NativeBigInteger bi2 = new NativeBigInteger(1, val); - try { - validatePublic(bi2); - System.out.println("valid"); - } catch (InvalidPublicParameterException ippe) { - System.out.println("invalid"); - } - } - */ - -/****** - public static void main(String args[]) { - //if (true) { testValidation(); return; } - - RandomSource.getInstance().nextBoolean(); // warm it up - try { - Thread.sleep(20 * 1000); - } catch (InterruptedException ie) { // nop - } - I2PAppContext ctx = new I2PAppContext(); - _log.debug("\n\n\n\nBegin test\n"); - long negTime = 0; - try { - for (int i = 0; i < 5; i++) { - long startNeg = System.currentTimeMillis(); - DHSessionKeyBuilder builder1 = new DHSessionKeyBuilder(); - DHSessionKeyBuilder builder2 = new DHSessionKeyBuilder(); - BigInteger pub1 = builder1.getMyPublicValue(); - builder2.setPeerPublicValue(pub1); - BigInteger pub2 = builder2.getMyPublicValue(); - builder1.setPeerPublicValue(pub2); - SessionKey key1 = builder1.getSessionKey(); - SessionKey key2 = builder2.getSessionKey(); - long endNeg = System.currentTimeMillis(); - negTime += endNeg - startNeg; - - if (!key1.equals(key2)) - _log.error("**ERROR: Keys do not match"); - else - _log.debug("**Success: Keys match"); - - byte iv[] = new byte[16]; - RandomSource.getInstance().nextBytes(iv); - String origVal = "1234567890123456"; // 16 bytes max using AESEngine - byte enc[] = new byte[16]; - byte dec[] = new byte[16]; - ctx.aes().encrypt(origVal.getBytes(), 0, enc, 0, key1, iv, 16); - ctx.aes().decrypt(enc, 0, dec, 0, key2, iv, 16); - String tranVal = new String(dec); - if (origVal.equals(tranVal)) - _log.debug("**Success: D(E(val)) == val"); - else - _log.error("**ERROR: D(E(val)) != val [val=(" + tranVal + "), origVal=(" + origVal + ")"); - } - } catch (InvalidPublicParameterException ippe) { - _log.error("Invalid dh", ippe); - } - _log.debug("Negotiation time for 5 runs: " + negTime + " @ " + negTime / 5l + "ms each"); - try { - Thread.sleep(2000); - } catch (InterruptedException ie) { // nop - } - } -******/ - - /** - * @since 0.9 - */ - public interface Factory { - /** - * Construct a new DH key builder - * or pulls a prebuilt one from the queue. - */ - public DHSessionKeyBuilder getBuilder(); - - /** - * Return an unused DH key builder - * to be put back onto the queue for reuse. - * - * @param builder must not have a peerPublicValue set - * @since 0.9.16 - */ - public void returnUnused(DHSessionKeyBuilder builder); - } - - /** - * Try to keep DH pairs at the ready. - * It's important to do this in a separate thread, because if we run out, - * the pairs are generated in the NTCP Pumper thread, - * and it can fall behind. - */ - public static class PrecalcRunner extends I2PThread implements Factory { - private final I2PAppContext _context; - private final Log _log; - private final int _minSize; - private final int _maxSize; - private final int _calcDelay; - private final LinkedBlockingQueue _builders; - private volatile boolean _isRunning; - - /** check periodically whether we have less than the minimum */ - private long _checkDelay = 10 * 1000; - - public PrecalcRunner(I2PAppContext ctx) { - super("DH Precalc"); - _context = ctx; - _log = ctx.logManager().getLog(DHSessionKeyBuilder.class); - ctx.statManager().createRateStat("crypto.dhGeneratePublicTime", "How long it takes to create x and X", "Encryption", new long[] { 60*60*1000 }); - ctx.statManager().createRateStat("crypto.dhCalculateSessionTime", "How long it takes to create the session key", "Encryption", new long[] { 60*60*1000 }); - ctx.statManager().createRateStat("crypto.DHUsed", "Need a DH from the queue", "Encryption", new long[] { 60*60*1000 }); - ctx.statManager().createRateStat("crypto.DHReused", "Unused DH requeued", "Encryption", new long[] { 60*60*1000 }); - ctx.statManager().createRateStat("crypto.DHEmpty", "DH queue empty", "Encryption", new long[] { 60*60*1000 }); - - // add to the defaults for every 128MB of RAM, up to 512MB - long maxMemory = SystemVersion.getMaxMemory(); - int factor = (int) Math.max(1l, Math.min(4l, 1 + (maxMemory / (128*1024*1024l)))); - if (SystemVersion.isSlow()) - factor *= 2; - int defaultMin = DEFAULT_DH_PRECALC_MIN * factor; - int defaultMax = DEFAULT_DH_PRECALC_MAX * factor; - _minSize = ctx.getProperty(PROP_DH_PRECALC_MIN, defaultMin); - _maxSize = ctx.getProperty(PROP_DH_PRECALC_MAX, defaultMax); - _calcDelay = ctx.getProperty(PROP_DH_PRECALC_DELAY, DEFAULT_DH_PRECALC_DELAY); - - if (_log.shouldLog(Log.DEBUG)) - _log.debug("DH Precalc (minimum: " + _minSize + " max: " + _maxSize + ", delay: " - + _calcDelay + ")"); - _builders = new LinkedBlockingQueue(_maxSize); - if (!SystemVersion.isWindows()) - setPriority(Thread.NORM_PRIORITY - 1); - } - - /** - * Note that this stops the singleton precalc thread. - * You don't want to do this if there are multiple routers in the JVM. - * Fix this if you care. See Router.shutdown(). - * @since 0.8.8 - */ - public void shutdown() { - _isRunning = false; - this.interrupt(); - _builders.clear(); - } - - public void run() { - try { - run2(); - } catch (IllegalStateException ise) { - if (_isRunning) - throw ise; - // else ignore, thread can be slow to shutdown on Android, - // PRNG gets stopped first and throws ISE - } - } - - private void run2() { - _isRunning = true; - while (_isRunning) { - //long start = System.currentTimeMillis(); - int startSize = getSize(); - // Adjust delay - if (startSize <= (_minSize * 2 / 3) && _checkDelay > 1000) - _checkDelay -= 1000; - else if (startSize > (_minSize * 3 / 2) && _checkDelay < 60*1000) - _checkDelay += 1000; - if (startSize < _minSize) { - // fill all the way up, do the check here so we don't - // throw away one when full in addValues() - while (getSize() < _maxSize && _isRunning) { - long curStart = System.currentTimeMillis(); - if (!addBuilder(precalc())) - break; - long curCalc = System.currentTimeMillis() - curStart; - // for some relief... - if (!interrupted()) { - try { - Thread.sleep(Math.min(200, Math.max(10, _calcDelay + (curCalc * 3)))); - } catch (InterruptedException ie) {} - } - } - } - //long end = System.currentTimeMillis(); - //int numCalc = curSize - startSize; - //if (numCalc > 0) { - // if (_log.shouldLog(Log.DEBUG)) - // _log.debug("Precalced " + numCalc + " to " + curSize + " in " - // + (end - start - CALC_DELAY * numCalc) + "ms (not counting " - // + (CALC_DELAY * numCalc) + "ms relief). now sleeping"); - //} - if (!_isRunning) - break; - try { - Thread.sleep(_checkDelay); - } catch (InterruptedException ie) { // nop - } - } - } - - /** - * Construct a new DH key builder - * or pulls a prebuilt one from the queue. - * - * @since 0.9 moved from DHSKB - */ - public DHSessionKeyBuilder getBuilder() { - _context.statManager().addRateData("crypto.DHUsed", 1); - DHSessionKeyBuilder builder = _builders.poll(); - if (builder == null) { - if (_log.shouldLog(Log.INFO)) _log.info("No more builders, creating one now"); - _context.statManager().addRateData("crypto.DHEmpty", 1); - builder = precalc(); - // stop sleeping, wake up, make some more - this.interrupt(); - } - return builder; - } - - private DHSessionKeyBuilder precalc() { - long start = System.currentTimeMillis(); - DHSessionKeyBuilder builder = new DHSessionKeyBuilder(_context); - long end = System.currentTimeMillis(); - long diff = end - start; - _context.statManager().addRateData("crypto.dhGeneratePublicTime", diff); - if (diff > 1000) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Took more than a second (" + diff + "ms) to generate local DH value"); - } else { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Took " + diff + "ms to generate local DH value"); - } - return builder; - } - - /** - * Return an unused DH key builder - * to be put back onto the queue for reuse. - * - * @param builder must not have a peerPublicValue set - * @since 0.9.16 - */ - public void returnUnused(DHSessionKeyBuilder builder) { -/* - if (builder.getPeerPublicValue() != null) { - _log.error("builder returned used", new Exception()); - return; - } - if (_builders.offer(builder)) - _context.statManager().addRateData("crypto.DHReused", 1); -*/ - } - - /** @return true if successful, false if full */ - private final boolean addBuilder(DHSessionKeyBuilder builder) { - return _builders.offer(builder); - } - - private final int getSize() { - return _builders.size(); - } - - } - - public static class InvalidPublicParameterException extends I2PException { - public InvalidPublicParameterException() { - super(); - } - public InvalidPublicParameterException(String msg) { - super(msg); - } - /** @since 0.9.35 */ - public InvalidPublicParameterException(String msg, Throwable t) { - super(msg, t); - } - } -} diff --git a/router/java/src/net/i2p/router/transport/ntcp/InboundEstablishState.java b/router/java/src/net/i2p/router/transport/ntcp/InboundEstablishState.java index 92d230c4a..7a71a5ceb 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/InboundEstablishState.java +++ b/router/java/src/net/i2p/router/transport/ntcp/InboundEstablishState.java @@ -31,7 +31,6 @@ import net.i2p.data.router.RouterInfo; import net.i2p.router.Router; import net.i2p.router.RouterContext; import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade; -import net.i2p.router.transport.crypto.DHSessionKeyBuilder; import static net.i2p.router.transport.ntcp.OutboundNTCP2State.*; import net.i2p.util.Addresses; import net.i2p.util.ByteArrayStream; diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java index bc90c6b1f..1ff410e4d 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java @@ -50,7 +50,6 @@ import net.i2p.router.transport.TransportImpl; import net.i2p.router.transport.TransportManager; import net.i2p.router.transport.TransportUtil; import static net.i2p.router.transport.TransportUtil.IPv6Config.*; -import net.i2p.router.transport.crypto.DHSessionKeyBuilder; import net.i2p.router.transport.crypto.X25519KeyFactory; import net.i2p.router.transport.udp.UDPTransport; import net.i2p.router.util.DecayingHashSet; @@ -146,10 +145,9 @@ public class NTCPTransport extends TransportImpl { private final String _b64Ntcp2StaticIV; /** - * @param dh unused, ignored * @param xdh null to disable NTCP2 */ - public NTCPTransport(RouterContext ctx, DHSessionKeyBuilder.Factory dh, X25519KeyFactory xdh) { + public NTCPTransport(RouterContext ctx, X25519KeyFactory xdh) { super(ctx); _xdhFactory = xdh; _log = ctx.logManager().getLog(getClass()); diff --git a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java index b423fb110..3942d6e90 100644 --- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java +++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java @@ -40,7 +40,6 @@ import net.i2p.router.OutNetMessage; import net.i2p.router.Router; import net.i2p.router.RouterContext; import net.i2p.router.transport.TransportUtil; -import net.i2p.router.transport.crypto.DHSessionKeyBuilder; import static net.i2p.router.transport.udp.InboundEstablishState.InboundState.*; import static net.i2p.router.transport.udp.OutboundEstablishState.OutboundState.*; import static net.i2p.router.transport.udp.OutboundEstablishState2.IntroState.*; diff --git a/router/java/test/junit/net/i2p/router/transport/crypto/DHSessionKeyBuilderTest.java b/router/java/test/junit/net/i2p/router/transport/crypto/DHSessionKeyBuilderTest.java deleted file mode 100644 index 190e048d6..000000000 --- a/router/java/test/junit/net/i2p/router/transport/crypto/DHSessionKeyBuilderTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package net.i2p.router.transport.crypto; - -/* - * free (adj.): unencumbered; not under the control of others - * Written by jrandom in 2003 and released into the public domain - * with no warranty of any kind, either expressed or implied. - * It probably won't make your computer catch on fire, or eat - * your children, but it might. Use at your own risk. - * - */ - -import java.math.BigInteger; - -import junit.framework.TestCase; -import net.i2p.I2PAppContext; -import net.i2p.data.DataHelper; -import net.i2p.data.SessionKey; -import net.i2p.util.RandomSource; - -public class DHSessionKeyBuilderTest extends TestCase { - public void testDHSessionKeyBuilder(){ - I2PAppContext ctx = new I2PAppContext(); - for (int i = 0; i < 5; i++) { - DHSessionKeyBuilder builder1 = new DHSessionKeyBuilder(); - DHSessionKeyBuilder builder2 = new DHSessionKeyBuilder(); - BigInteger pub1 = builder1.getMyPublicValue(); - BigInteger pub2 = builder2.getMyPublicValue(); - try { - builder2.setPeerPublicValue(pub1); - builder1.setPeerPublicValue(pub2); - } catch (DHSessionKeyBuilder.InvalidPublicParameterException ippe) { - assertTrue(ippe.getMessage(), true); - } - SessionKey key1 = builder1.getSessionKey(); - SessionKey key2 = builder2.getSessionKey(); - - assertEquals(key1, key2); - - byte iv[] = new byte[16]; - RandomSource.getInstance().nextBytes(iv); - String origVal = "1234567890123456"; // 16 bytes max using AESEngine - byte enc[] = new byte[16]; - byte dec[] = new byte[16]; - ctx.aes().encrypt(DataHelper.getASCII(origVal), 0, enc, 0, key1, iv, 16); - ctx.aes().decrypt(enc, 0, dec, 0, key2, iv, 16); - String tranVal = new String(dec); - assertEquals(origVal, tranVal); - } - } -}