forked from I2P_Developers/i2p.i2p
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:
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user