* Javadocs

* Base64: comment out some unused methods
* Remove huge whitespace in CryptoConstants
* ElGamalAESEngine:
  - Reduce rates
  - Check number of tags earlier
This commit is contained in:
zzz
2010-08-30 17:51:49 +00:00
parent c035ef6eb7
commit 91bcf947df
14 changed files with 193 additions and 48 deletions

View File

@ -23,7 +23,7 @@ import net.i2p.data.SessionKey;
* byte 184: flags
* bytes 185-188: request time (in hours since the epoch)
* bytes 189-192: next message ID
* bytes 193-222: uninterpreted / random padding
* bytes 193-221: uninterpreted / random padding
* </pre>
*
*/
@ -226,7 +226,7 @@ public class BuildRequestRecord {
* byte 184: flags
* bytes 185-188: request time (in hours since the epoch)
* bytes 189-192: next message ID
* bytes 193-222: uninterpreted / random padding
* bytes 193-221: uninterpreted / random padding
*/
DataHelper.toLong(buf, OFF_RECV_TUNNEL, 4, receiveTunnelId);
System.arraycopy(peer.getData(), 0, buf, OFF_OUR_IDENT, Hash.HASH_LENGTH);

View File

@ -35,6 +35,7 @@ public class GarlicMessageBuilder {
/**
* This was 100 since 0.6.1.10 (50 before that). It's important because:
* <pre>
* - Tags are 32 bytes. So it previously added 3200 bytes to an initial message.
* - Too many tags adds a huge overhead to short-duration connections
* (like http, datagrams, etc.)
@ -43,14 +44,17 @@ public class GarlicMessageBuilder {
* - This reduces the effective maximum datagram size because the client
* doesn't know when tags will be bundled, so the tag size must be
* subtracted from the maximum I2NP size or transport limit.
* </pre>
*
* Issues with too small a value:
* <pre>
* - When tags are sent, a reply leaseset (~1KB) is always bundled.
* Maybe don't need to bundle more than every minute or so
* rather than every time?
* - Does the number of tags (and the threshold of 20) limit the effective
* streaming lib window size? Should the threshold and the number of
* sent tags be variable based on the message rate?
* </pre>
*
* We have to be very careful if we implement an adaptive scheme,
* since the key manager is per-router, not per-local-dest.
@ -218,6 +222,7 @@ public class GarlicMessageBuilder {
byte cloveSet[] = buildCloveSet(ctx, config);
// TODO - 128 is the minimum padded size - should it be more? less? random?
byte encData[] = ctx.elGamalAESEngine().encrypt(cloveSet, target, encryptKey, wrappedTags, encryptTag, 128);
msg.setData(encData);
msg.setMessageExpiration(config.getExpiration());

View File

@ -20,7 +20,7 @@ import net.i2p.router.message.PayloadGarlicConfig;
import net.i2p.util.Log;
/**
* Method an class for garlic encrypting outbound netdb traffic,
* Method and class for garlic encrypting outbound netdb traffic,
* including management of the ElGamal/AES tags
*
* @since 0.7.10

View File

@ -29,18 +29,45 @@ import net.i2p.router.Router;
import net.i2p.router.RouterContext;
import net.i2p.util.Log;
/*
/**
* Handle the 4-phase establishment, which is as follows:
*
* <pre>
*
* Alice contacts Bob
* =========================================================
*
* Message 1 (Session Request):
* X+(H(X) xor Bob.identHash)----------------------------->
*
* Message 2 (Session Created):
* <----------------------------------------Y+E(H(X+Y)+tsB, sk, Y[239:255])
* E(#+Alice.identity+tsA+padding+S(X+Y+Bob.identHash+tsA+tsB+padding), sk, hX_xor_Bob.identHash[16:31])--->
*
* Message 3 (Session Confirm A):
* E(sz+Alice.identity+tsA+padding+S(X+Y+Bob.identHash+tsA+tsB), sk, hX_xor_Bob.identHash[16:31])--->
*
* Message 4 (Session Confirm B):
* <----------------------E(S(X+Y+Alice.identHash+tsA+tsB)+padding, sk, prev)
*
* Key:
*
* X, Y: 256 byte DH keys
* H(): 32 byte SHA256 Hash
* E(data, session key, IV): AES256 Encrypt
* S(): 40 byte DSA Signature
* tsA, tsB: timestamps (4 bytes, seconds since epoch)
* sk: 32 byte Session key
* sz: 2 byte size of Alice identity to follow
*
* </pre>
*
*
* Alternately, when Bob receives a connection, it could be a
* check connection (perhaps prompted by Bob asking for someone
* to verify his listener). check connections are formatted per
* {@link #isCheckInfo()}
* isCheckInfo()
* NOTE: Check info is unused.
*
*/
public class EstablishState {
private RouterContext _context;
@ -57,7 +84,9 @@ public class EstablishState {
// alice receives (and bob sends)
private byte _Y[];
private transient byte _e_hXY_tsB[];
/** Bob's Timestamp in seconds */
private transient long _tsB;
/** Alice's Timestamp in seconds */
private transient long _tsA;
private transient byte _e_bobSig[];
@ -98,9 +127,6 @@ public class EstablishState {
_log = ctx.logManager().getLog(getClass());
_transport = transport;
_con = con;
_verified = false;
_corrupt = false;
_confirmWritten = false;
_dh = new DHSessionKeyBuilder();
if (_con.isInbound()) {
_X = new byte[256];
@ -116,10 +142,7 @@ public class EstablishState {
_prevEncrypted = new byte[16];
_curEncrypted = new byte[16];
_curEncryptedOffset = 0;
_curDecrypted = new byte[16];
_received = 0;
}
/**
@ -150,7 +173,10 @@ public class EstablishState {
public boolean getFailedBySkew() { return _failedBySkew; }
/** we are Bob, so receive these bytes as part of an inbound connection */
/**
* we are Bob, so receive these bytes as part of an inbound connection
* This method receives messages 1 and 3, and sends messages 2 and 4.
*/
private void receiveInbound(ByteBuffer src) {
if (_log.shouldLog(Log.DEBUG))
_log.debug(prefix()+"Receiving inbound: prev received=" + _received + " src.remaining=" + src.remaining());
@ -311,7 +337,10 @@ public class EstablishState {
}
}
/** we are Alice, so receive these bytes as part of an outbound connection */
/**
* We are Alice, so receive these bytes as part of an outbound connection.
* This method receives messages 2 and 4, and sends message 3.
*/
private void receiveOutbound(ByteBuffer src) {
if (_log.shouldLog(Log.DEBUG)) _log.debug(prefix()+"Receive outbound " + src + " received=" + _received);
@ -498,8 +527,10 @@ public class EstablishState {
public boolean isComplete() { return _verified; }
/**
* we are establishing an outbound connection, so prepare ourselves by
* We are Alice.
* We are establishing an outbound connection, so prepare ourselves by
* queueing up the write of the first part of the handshake
* This method sends message #1 to Bob.
*/
public void prepareOutbound() {
if (_received <= 0) {
@ -516,7 +547,9 @@ public class EstablishState {
}
/**
* make sure the signatures are correct, and if they are, update the
* We are Bob. Verify message #3 from Alice, then send message #4 to Alice.
*
* Make sure the signatures are correct, and if they are, update the
* NIOConnection with the session key / peer ident / clock skew / iv.
* The NIOConnection itself is responsible for registering with the
* transport
@ -623,6 +656,9 @@ public class EstablishState {
}
}
/**
* We are Bob. Send message #4 to Alice.
*/
private void sendInboundConfirm(RouterIdentity alice, long tsA) {
// send Alice E(S(X+Y+Alice.identHash+tsA+tsB), sk, prev)
byte toSign[] = new byte[256+256+32+4+4];

View File

@ -607,6 +607,7 @@ public class PacketBuilder {
// pad here if we want. maybe randomized?
// pad up so we're on the encryption boundary
// TODO: why not random data?
if ( (off % 16) != 0)
off += 16 - (off % 16);
packet.getPacket().setLength(off);