Router: Move ElGamalAESEngine from core to router

Client end-to-end crypto removed 13 years ago
Not used by any client, app, or plugin.
This commit is contained in:
zzz
2018-11-23 13:04:28 +00:00
parent 5c0c69c654
commit 535f2daab0
6 changed files with 72 additions and 89 deletions

View File

@ -13,7 +13,6 @@ import net.i2p.client.naming.NamingService;
import net.i2p.crypto.AESEngine; import net.i2p.crypto.AESEngine;
import net.i2p.crypto.CryptixAESEngine; import net.i2p.crypto.CryptixAESEngine;
import net.i2p.crypto.DSAEngine; import net.i2p.crypto.DSAEngine;
import net.i2p.crypto.ElGamalAESEngine;
import net.i2p.crypto.ElGamalEngine; import net.i2p.crypto.ElGamalEngine;
import net.i2p.crypto.HMAC256Generator; import net.i2p.crypto.HMAC256Generator;
import net.i2p.crypto.HMACGenerator; import net.i2p.crypto.HMACGenerator;
@ -74,7 +73,6 @@ public class I2PAppContext {
protected SessionKeyManager _sessionKeyManager; protected SessionKeyManager _sessionKeyManager;
private NamingService _namingService; private NamingService _namingService;
private ElGamalEngine _elGamalEngine; private ElGamalEngine _elGamalEngine;
private ElGamalAESEngine _elGamalAESEngine;
private AESEngine _AESEngine; private AESEngine _AESEngine;
private LogManager _logManager; private LogManager _logManager;
private HMACGenerator _hmac; private HMACGenerator _hmac;
@ -94,7 +92,6 @@ public class I2PAppContext {
protected volatile boolean _sessionKeyManagerInitialized; protected volatile boolean _sessionKeyManagerInitialized;
private volatile boolean _namingServiceInitialized; private volatile boolean _namingServiceInitialized;
private volatile boolean _elGamalEngineInitialized; private volatile boolean _elGamalEngineInitialized;
private volatile boolean _elGamalAESEngineInitialized;
private volatile boolean _AESEngineInitialized; private volatile boolean _AESEngineInitialized;
private volatile boolean _logManagerInitialized; private volatile boolean _logManagerInitialized;
private volatile boolean _hmacInitialized; private volatile boolean _hmacInitialized;
@ -120,7 +117,7 @@ public class I2PAppContext {
private final ClientAppManager _appManager; private final ClientAppManager _appManager;
// split up big lock on this to avoid deadlocks // split up big lock on this to avoid deadlocks
private final Object _lock1 = new Object(), _lock2 = new Object(), _lock3 = new Object(), _lock4 = new Object(), private final Object _lock1 = new Object(), _lock2 = new Object(), _lock3 = new Object(), _lock4 = new Object(),
_lock5 = new Object(), _lock6 = new Object(), _lock7 = new Object(), _lock8 = new Object(), _lock5 = new Object(), _lock7 = new Object(), _lock8 = new Object(),
_lock9 = new Object(), _lock10 = new Object(), _lock11 = new Object(), _lock12 = new Object(), _lock9 = new Object(), _lock10 = new Object(), _lock11 = new Object(), _lock12 = new Object(),
_lock13 = new Object(), _lock14 = new Object(), _lock16 = new Object(), _lock13 = new Object(), _lock14 = new Object(), _lock16 = new Object(),
_lock17 = new Object(), _lock18 = new Object(), _lock19 = new Object(), _lock20 = new Object(); _lock17 = new Object(), _lock18 = new Object(), _lock19 = new Object(), _lock20 = new Object();
@ -682,27 +679,6 @@ public class I2PAppContext {
} }
} }
/**
* Access the ElGamal/AES+SessionTag engine for this context. The algorithm
* makes use of the context's sessionKeyManager to coordinate transparent
* access to the sessionKeys and sessionTags, as well as the context's elGamal
* engine (which in turn keeps stats, etc).
*
*/
public ElGamalAESEngine elGamalAESEngine() {
if (!_elGamalAESEngineInitialized)
initializeElGamalAESEngine();
return _elGamalAESEngine;
}
private void initializeElGamalAESEngine() {
synchronized (_lock6) {
if (_elGamalAESEngine == null)
_elGamalAESEngine = new ElGamalAESEngine(this);
_elGamalAESEngineInitialized = true;
}
}
/** /**
* Ok, I'll admit it. there is no good reason for having a context specific * Ok, I'll admit it. there is no good reason for having a context specific
* AES engine. We dont really keep stats on it, since its just too fast to * AES engine. We dont really keep stats on it, since its just too fast to

View File

@ -164,7 +164,7 @@ class I2CPMessageProducer {
} }
msg.setSessionId(sid); msg.setSessionId(sid);
msg.setNonce(nonce); msg.setNonce(nonce);
Payload data = createPayload(dest, payload, null, null, null, null); Payload data = createPayload(payload);
msg.setPayload(data); msg.setPayload(data);
session.sendMessage(msg); session.sendMessage(msg);
} }
@ -191,7 +191,7 @@ class I2CPMessageProducer {
} }
msg.setSessionId(sid); msg.setSessionId(sid);
msg.setNonce(nonce); msg.setNonce(nonce);
Payload data = createPayload(dest, payload, null, null, null, null); Payload data = createPayload(payload);
msg.setPayload(data); msg.setPayload(data);
session.sendMessage(msg); session.sendMessage(msg);
} }
@ -300,42 +300,15 @@ class I2CPMessageProducer {
} }
/** /**
* Should we include the I2CP end to end crypto (which is in addition to any * Create a new payload.
* garlic crypto added by the router) * No more end-to-end encryption, just set the "encrypted" data to the payload.
*
*/ */
static final boolean END_TO_END_CRYPTO = false; private static Payload createPayload(byte[] payload) throws I2PSessionException {
/**
* Create a new signed payload and send it off to the destination
*
* @param tag unused - no end-to-end crypto
* @param tags unused - no end-to-end crypto
* @param key unused - no end-to-end crypto
* @param newKey unused - no end-to-end crypto
*/
private Payload createPayload(Destination dest, byte[] payload, SessionTag tag, SessionKey key, Set<SessionTag> tags,
SessionKey newKey) throws I2PSessionException {
if (dest == null) throw new I2PSessionException("No destination specified");
if (payload == null) throw new I2PSessionException("No payload specified"); if (payload == null) throw new I2PSessionException("No payload specified");
Payload data = new Payload(); Payload data = new Payload();
if (!END_TO_END_CRYPTO) {
data.setEncryptedData(payload); data.setEncryptedData(payload);
return data; return data;
} }
// no padding at this level
// the garlic may pad, and the tunnels may pad, and the transports may pad
int size = payload.length;
byte encr[] = _context.elGamalAESEngine().encrypt(payload, dest.getPublicKey(), key, tags, tag, newKey, size);
// yes, in an intelligent component, newTags would be queued for confirmation along with key, and
// generateNewTags would only generate tags if necessary
data.setEncryptedData(encr);
//_log.debug("Encrypting the payload to public key " + dest.getPublicKey().toBase64() + "\nPayload: "
// + data.calculateHash());
return data;
}
/** /**
* Send an abuse message to the router * Send an abuse message to the router

View File

@ -79,7 +79,7 @@ public class AESEngine {
int size = Hash.HASH_LENGTH int size = Hash.HASH_LENGTH
+ 4 // sizeof(payload) + 4 // sizeof(payload)
+ payload.length; + payload.length;
int padding = ElGamalAESEngine.getPaddingSize(size, paddedSize); int padding = getPaddingSize(size, paddedSize);
byte data[] = new byte[size + padding]; byte data[] = new byte[size + padding];
_context.sha().calculateHash(iv, 0, 16, data, 0); _context.sha().calculateHash(iv, 0, 16, data, 0);
@ -89,7 +89,7 @@ public class AESEngine {
cur += 4; cur += 4;
System.arraycopy(payload, 0, data, cur, payload.length); System.arraycopy(payload, 0, data, cur, payload.length);
cur += payload.length; cur += payload.length;
byte paddingData[] = ElGamalAESEngine.getPadding(_context, size, paddedSize); byte paddingData[] = getPadding(_context, size, paddedSize);
System.arraycopy(paddingData, 0, data, cur, paddingData.length); System.arraycopy(paddingData, 0, data, cur, paddingData.length);
encrypt(data, 0, data, 0, sessionKey, iv, data.length); encrypt(data, 0, data, 0, sessionKey, iv, data.length);
@ -183,6 +183,43 @@ public class AESEngine {
System.arraycopy(payload, inIndex, rv, outIndex, rv.length - outIndex); System.arraycopy(payload, inIndex, rv, outIndex, rv.length - outIndex);
} }
/**
* Return random bytes for padding the data to a mod 16 size so that it is
* at least minPaddedSize
*
* Public for ElGamalAESEngine.
* Not a public API, not for external use.
*
* @since 0.9.38 moved from ElGamalAESEngine
*/
public final static byte[] getPadding(I2PAppContext context, int curSize, long minPaddedSize) {
int size = getPaddingSize(curSize, minPaddedSize);
byte rv[] = new byte[size];
context.random().nextBytes(rv);
return rv;
}
/**
* Return size for padding the data to a mod 16 size so that it is
* at least minPaddedSize
*
* Public for ElGamalAESEngine.
* Not a public API, not for external use.
*
* @since 0.9.38 moved from ElGamalAESEngine
*/
public final static int getPaddingSize(int curSize, long minPaddedSize) {
int diff = 0;
if (curSize < minPaddedSize) {
diff = (int) minPaddedSize - curSize;
}
int numPadding = diff;
if (((curSize + diff) % 16) != 0) numPadding += (16 - ((curSize + diff) % 16));
return numPadding;
}
/****** /******
public static void main(String args[]) { public static void main(String args[]) {
I2PAppContext ctx = new I2PAppContext(); I2PAppContext ctx = new I2PAppContext();

View File

@ -15,6 +15,7 @@ import net.i2p.data.router.RouterInfo;
import net.i2p.data.router.RouterKeyGenerator; import net.i2p.data.router.RouterKeyGenerator;
import net.i2p.internal.InternalClientManager; import net.i2p.internal.InternalClientManager;
import net.i2p.router.client.ClientManagerFacadeImpl; import net.i2p.router.client.ClientManagerFacadeImpl;
import net.i2p.router.crypto.ElGamalAESEngine;
import net.i2p.router.crypto.TransientSessionKeyManager; import net.i2p.router.crypto.TransientSessionKeyManager;
import net.i2p.router.dummy.*; import net.i2p.router.dummy.*;
import net.i2p.router.message.GarlicMessageParser; import net.i2p.router.message.GarlicMessageParser;
@ -68,6 +69,7 @@ public class RouterContext extends I2PAppContext {
private RouterAppManager _appManager; private RouterAppManager _appManager;
private RouterKeyGenerator _routingKeyGenerator; private RouterKeyGenerator _routingKeyGenerator;
private GarlicMessageParser _garlicMessageParser; private GarlicMessageParser _garlicMessageParser;
private ElGamalAESEngine _elGamalAESEngine;
private final Set<Runnable> _finalShutdownTasks; private final Set<Runnable> _finalShutdownTasks;
// split up big lock on this to avoid deadlocks // split up big lock on this to avoid deadlocks
private volatile boolean _initialized; private volatile boolean _initialized;
@ -211,6 +213,7 @@ public class RouterContext extends I2PAppContext {
_clientManagerFacade = new DummyClientManagerFacade(this); _clientManagerFacade = new DummyClientManagerFacade(this);
// internal client manager is null // internal client manager is null
} }
_elGamalAESEngine = new ElGamalAESEngine(this);
_garlicMessageParser = new GarlicMessageParser(this); _garlicMessageParser = new GarlicMessageParser(this);
_clientMessagePool = new ClientMessagePool(this); _clientMessagePool = new ClientMessagePool(this);
_jobQueue = new JobQueue(this); _jobQueue = new JobQueue(this);
@ -667,4 +670,16 @@ public class RouterContext extends I2PAppContext {
public GarlicMessageParser garlicMessageParser() { public GarlicMessageParser garlicMessageParser() {
return _garlicMessageParser; return _garlicMessageParser;
} }
/**
* Access the ElGamal/AES+SessionTag engine for this context. The algorithm
* makes use of the context's sessionKeyManager to coordinate transparent
* access to the sessionKeys and sessionTags, as well as the context's elGamal
* engine (which in turn keeps stats, etc).
*
* @since 0.9.38 moved from superclass (app context)
*/
public ElGamalAESEngine elGamalAESEngine() {
return _elGamalAESEngine;
}
} }

View File

@ -1,4 +1,4 @@
package net.i2p.crypto; package net.i2p.router.crypto;
/* /*
* free (adj.): unencumbered; not under the control of others * free (adj.): unencumbered; not under the control of others
@ -16,6 +16,8 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
import net.i2p.crypto.AESEngine;
import net.i2p.crypto.SessionKeyManager;
import net.i2p.data.DataFormatException; import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper; import net.i2p.data.DataHelper;
import net.i2p.data.Hash; import net.i2p.data.Hash;
@ -31,6 +33,8 @@ import net.i2p.util.SimpleByteCache;
* supplied keys and data. * supplied keys and data.
* *
* No, this does not extend AESEngine or CryptixAESEngine. * No, this does not extend AESEngine or CryptixAESEngine.
*
* @since 0.9.38 moved from net.i2p.crypto
*/ */
public final class ElGamalAESEngine { public final class ElGamalAESEngine {
private final Log _log; private final Log _log;
@ -649,7 +653,7 @@ public final class ElGamalAESEngine {
+ Hash.HASH_LENGTH + Hash.HASH_LENGTH
+ (newKey == null ? 1 : 1 + SessionKey.KEYSIZE_BYTES) + (newKey == null ? 1 : 1 + SessionKey.KEYSIZE_BYTES)
+ data.length; + data.length;
int totalSize = size + getPaddingSize(size, paddedSize); int totalSize = size + AESEngine.getPaddingSize(size, paddedSize);
byte aesData[] = new byte[totalSize + prefixBytes]; byte aesData[] = new byte[totalSize + prefixBytes];
@ -683,7 +687,7 @@ public final class ElGamalAESEngine {
cur += data.length; cur += data.length;
//_log.debug("raw data written: " + len); //_log.debug("raw data written: " + len);
byte padding[] = getPadding(_context, size, paddedSize); byte padding[] = AESEngine.getPadding(_context, size, paddedSize);
//_log.debug("padding length: " + padding.length); //_log.debug("padding length: " + padding.length);
System.arraycopy(padding, 0, aesData, cur, padding.length); System.arraycopy(padding, 0, aesData, cur, padding.length);
cur += padding.length; cur += padding.length;
@ -696,28 +700,6 @@ public final class ElGamalAESEngine {
return aesData; return aesData;
} }
/**
* Return random bytes for padding the data to a mod 16 size so that it is
* at least minPaddedSize
*
*/
final static byte[] getPadding(I2PAppContext context, int curSize, long minPaddedSize) {
int size = getPaddingSize(curSize, minPaddedSize);
byte rv[] = new byte[size];
context.random().nextBytes(rv);
return rv;
}
final static int getPaddingSize(int curSize, long minPaddedSize) {
int diff = 0;
if (curSize < minPaddedSize) {
diff = (int) minPaddedSize - curSize;
}
int numPadding = diff;
if (((curSize + diff) % 16) != 0) numPadding += (16 - ((curSize + diff) % 16));
return numPadding;
}
/**** /****
public static void main(String args[]) { public static void main(String args[]) {

View File

@ -10,7 +10,6 @@ package net.i2p.router.message;
import java.util.Date; import java.util.Date;
import net.i2p.I2PAppContext;
import net.i2p.crypto.SessionKeyManager; import net.i2p.crypto.SessionKeyManager;
import net.i2p.data.Certificate; import net.i2p.data.Certificate;
import net.i2p.data.DataFormatException; import net.i2p.data.DataFormatException;
@ -18,6 +17,7 @@ import net.i2p.data.DataHelper;
import net.i2p.data.PrivateKey; import net.i2p.data.PrivateKey;
import net.i2p.data.i2np.GarlicClove; import net.i2p.data.i2np.GarlicClove;
import net.i2p.data.i2np.GarlicMessage; import net.i2p.data.i2np.GarlicMessage;
import net.i2p.router.RouterContext;
import net.i2p.util.Log; import net.i2p.util.Log;
/** /**
@ -27,7 +27,7 @@ import net.i2p.util.Log;
*/ */
public class GarlicMessageParser { public class GarlicMessageParser {
private final Log _log; private final Log _log;
private final I2PAppContext _context; private final RouterContext _context;
/** /**
* Huge limit just to reduce chance of trouble. Typ. usage is 3. * Huge limit just to reduce chance of trouble. Typ. usage is 3.
@ -35,7 +35,7 @@ public class GarlicMessageParser {
*/ */
private static final int MAX_CLOVES = 32; private static final int MAX_CLOVES = 32;
public GarlicMessageParser(I2PAppContext context) { public GarlicMessageParser(RouterContext context) {
_context = context; _context = context;
_log = _context.logManager().getLog(GarlicMessageParser.class); _log = _context.logManager().getLog(GarlicMessageParser.class);
} }