2006-02-15 jrandom

* Merged in the i2p_0_6_1_10_PRE branch to the trunk, so CVS HEAD is no
      longer backwards compatible (and should not be used until 0.6.1.1 is
      out)
This commit is contained in:
jrandom
2006-02-15 05:33:17 +00:00
committed by zzz
parent 1374ea0ea1
commit 113fbc1df3
127 changed files with 2687 additions and 1309 deletions

View File

@@ -17,7 +17,8 @@ import net.i2p.data.*;
* bytes 168-183: reply IV
* byte 184: flags
* bytes 185-188: request time (in hours since the epoch)
* bytes 189-222: uninterpreted / random padding
* bytes 189-192: next message ID
* bytes 193-222: uninterpreted / random padding
* </pre>
*
*/
@@ -57,6 +58,7 @@ public class BuildRequestRecord {
private static final int OFF_REPLY_IV = OFF_REPLY_KEY + SessionKey.KEYSIZE_BYTES;
private static final int OFF_FLAG = OFF_REPLY_IV + IV_SIZE;
private static final int OFF_REQ_TIME = OFF_FLAG + 1;
private static final int OFF_SEND_MSG_ID = OFF_REQ_TIME + 4;
/** what tunnel ID should this receive messages on */
public long readReceiveTunnelId() {
@@ -135,7 +137,14 @@ public class BuildRequestRecord {
public long readRequestTime() {
return DataHelper.fromLong(_data.getData(), _data.getOffset() + OFF_REQ_TIME, 4) * 60l * 60l * 1000l;
}
/**
* What message ID should we send the request to the next hop with. If this is the outbound tunnel endpoint,
* this specifies the message ID with which the reply should be sent.
*/
public long readReplyMessageId() {
return DataHelper.fromLong(_data.getData(), _data.getOffset() + OFF_SEND_MSG_ID, 4);
}
/**
* Encrypt the record to the specified peer. The result is formatted as: <pre>
* bytes 0-15: SHA-256-128 of the current hop's identity (the toPeer parameter)
@@ -144,7 +153,7 @@ public class BuildRequestRecord {
*/
public void encryptRecord(I2PAppContext ctx, PublicKey toKey, Hash toPeer, byte out[], int outOffset) {
System.arraycopy(toPeer.getData(), 0, out, outOffset, PEER_SIZE);
byte preEncr[] = new byte[OFF_REQ_TIME + 4 + PADDING_SIZE];
byte preEncr[] = new byte[OFF_SEND_MSG_ID + 4 + PADDING_SIZE];
System.arraycopy(_data.getData(), _data.getOffset(), preEncr, 0, preEncr.length);
byte encrypted[] = ctx.elGamalEngine().encrypt(preEncr, toKey);
// the elg engine formats it kind of weird, giving 257 bytes for each part rather than 256, so
@@ -175,7 +184,7 @@ public class BuildRequestRecord {
}
}
private static final int PADDING_SIZE = 33;
private static final int PADDING_SIZE = 29;
/**
* Populate this instance with data. A new buffer is created to contain the data, with the
@@ -185,6 +194,7 @@ public class BuildRequestRecord {
* @param peer current hop's identity
* @param nextTunnelId id for the next hop, or where we send the reply (if we are the outbound endpoint)
* @param nextHop next hop's identity, or where we send the reply (if we are the outbound endpoint)
* @param nextMsgId message ID to use when sending on to the next hop (or for the reply)
* @param layerKey tunnel layer key to be used by the peer
* @param ivKey tunnel IV key to be used by the peer
* @param replyKey key to be used when encrypting the reply to this build request
@@ -192,12 +202,12 @@ public class BuildRequestRecord {
* @param isInGateway are we the gateway of an inbound tunnel?
* @param isOutEndpoint are we the endpoint of an outbound tunnel?
*/
public void createRecord(I2PAppContext ctx, long receiveTunnelId, Hash peer, long nextTunnelId, Hash nextHop,
public void createRecord(I2PAppContext ctx, long receiveTunnelId, Hash peer, long nextTunnelId, Hash nextHop, long nextMsgId,
SessionKey layerKey, SessionKey ivKey, SessionKey replyKey, byte iv[], boolean isInGateway,
boolean isOutEndpoint) {
if ( (_data == null) || (_data.getData() != null) )
_data = new ByteArray();
byte buf[] = new byte[OFF_REQ_TIME+4+PADDING_SIZE];
byte buf[] = new byte[OFF_SEND_MSG_ID+4+PADDING_SIZE];
_data.setData(buf);
/* bytes 0-3: tunnel ID to receive messages as
@@ -210,7 +220,8 @@ public class BuildRequestRecord {
* bytes 168-183: reply IV
* byte 184: flags
* bytes 185-188: request time (in hours since the epoch)
* bytes 189-222: uninterpreted / random padding
* bytes 189-192: next message ID
* bytes 193-222: uninterpreted / random padding
*/
DataHelper.toLong(buf, OFF_RECV_TUNNEL, 4, receiveTunnelId);
System.arraycopy(peer.getData(), 0, buf, OFF_OUR_IDENT, Hash.HASH_LENGTH);
@@ -227,9 +238,10 @@ public class BuildRequestRecord {
long truncatedHour = ctx.clock().now();
truncatedHour /= (60l*60l*1000l);
DataHelper.toLong(buf, OFF_REQ_TIME, 4, truncatedHour);
DataHelper.toLong(buf, OFF_SEND_MSG_ID, 4, nextMsgId);
byte rnd[] = new byte[PADDING_SIZE];
ctx.random().nextBytes(rnd);
System.arraycopy(rnd, 0, buf, OFF_REQ_TIME+4, rnd.length);
System.arraycopy(rnd, 0, buf, OFF_SEND_MSG_ID+4, rnd.length);
byte wroteIV[] = readReplyIV();
if (!DataHelper.eq(iv, wroteIV))

View File

@@ -2,6 +2,7 @@ package net.i2p.data.i2np;
import net.i2p.I2PAppContext;
import net.i2p.data.*;
import net.i2p.util.Log;
/**
* Read and write the reply to a tunnel build message record.
@@ -11,13 +12,18 @@ public class BuildResponseRecord {
/**
* Create a new encrypted response
*/
public byte[] create(I2PAppContext ctx, int status, SessionKey replyKey, byte replyIV[]) {
public byte[] create(I2PAppContext ctx, int status, SessionKey replyKey, byte replyIV[], long responseMessageId) {
Log log = ctx.logManager().getLog(BuildResponseRecord.class);
byte rv[] = new byte[TunnelBuildReplyMessage.RECORD_SIZE];
ctx.random().nextBytes(rv);
DataHelper.toLong(rv, TunnelBuildMessage.RECORD_SIZE-1, 1, status);
// rv = AES(SHA256(padding+status) + padding + status, replyKey, replyIV)
ctx.sha().calculateHash(rv, Hash.HASH_LENGTH, rv.length - Hash.HASH_LENGTH, rv, 0);
if (log.shouldLog(Log.DEBUG))
log.debug(responseMessageId + ": before encrypt: " + Base64.encode(rv, 0, 128) + " with " + replyKey.toBase64() + "/" + Base64.encode(replyIV));
ctx.aes().encrypt(rv, 0, rv, 0, replyKey, replyIV, rv.length);
if (log.shouldLog(Log.DEBUG))
log.debug(responseMessageId + ": after encrypt: " + Base64.encode(rv, 0, 128));
return rv;
}
}

View File

@@ -33,14 +33,15 @@ public class TunnelBuildMessage extends I2NPMessageImpl {
for (int i = 0; i < RECORD_COUNT; i++) {
int off = offset + (i * RECORD_SIZE);
int len = RECORD_SIZE;
setRecord(i, new ByteArray(data, off, len));
byte rec[] = new byte[RECORD_SIZE];
System.arraycopy(data, off, rec, 0, RECORD_SIZE);
setRecord(i, new ByteArray(rec)); //new ByteArray(data, off, len));
}
}
protected int writeMessageBody(byte[] out, int curIndex) throws I2NPMessageException {
int remaining = out.length - (curIndex + calculateWrittenLength());
if (remaining <= 0)
if (remaining < 0)
throw new I2NPMessageException("Not large enough (too short by " + remaining + ")");
for (int i = 0; i < RECORD_COUNT; i++) {
System.arraycopy(_records[i].getData(), _records[i].getOffset(), out, curIndex, RECORD_SIZE);

View File

@@ -35,13 +35,16 @@ public class TunnelBuildReplyMessage extends I2NPMessageImpl {
for (int i = 0; i < RECORD_COUNT; i++) {
int off = offset + (i * RECORD_SIZE);
int len = RECORD_SIZE;
setRecord(i, new ByteArray(data, off, len));
byte rec[] = new byte[RECORD_SIZE];
System.arraycopy(data, off, rec, 0, RECORD_SIZE);
setRecord(i, new ByteArray(rec));
//setRecord(i, new ByteArray(data, off, len));
}
}
protected int writeMessageBody(byte[] out, int curIndex) throws I2NPMessageException {
int remaining = out.length - (curIndex + calculateWrittenLength());
if (remaining <= 0)
if (remaining < 0)
throw new I2NPMessageException("Not large enough (too short by " + remaining + ")");
for (int i = 0; i < RECORD_COUNT; i++) {
System.arraycopy(_records[i].getData(), _records[i].getOffset(), out, curIndex, RECORD_SIZE);