Ratchet: Fix tagset remaining calculation

More efficient tag insantiation
Debug page fixes
Javadoc fixes
Minor cleanups
This commit is contained in:
zzz
2020-04-19 10:59:32 +00:00
parent ae199581be
commit 73886d06e8
5 changed files with 56 additions and 56 deletions

View File

@ -670,21 +670,6 @@ public final class ECIESAEADEngine {
* No new session key
* This is the one called from GarlicMessageBuilder and is the primary entry point.
*
* Re: padded size: The AEAD block adds at least 39 bytes of overhead to the data, and
* that is included in the minimum size calculation.
*
* In the router, we always use garlic messages. A garlic message with a single
* clove and zero data is about 84 bytes, so that's 123 bytes minimum. So any paddingSize
* <= 128 is a no-op as every message will be at least 128 bytes
* (Streaming, if used, adds more overhead).
*
* Outside the router, with a client using its own message format, the minimum size
* is 48, so any paddingSize <= 48 is a no-op.
*
* Not included in the minimum is a 32-byte session tag for an existing session,
* or a 514-byte ECIES block and several 32-byte session tags for a new session.
* So the returned encrypted data will be at least 32 bytes larger than paddedSize.
*
* @param target public key to which the data should be encrypted.
* @param priv local private key to encrypt with, from the leaseset
* @param callback may be null, if non-null an ack will be requested (except NS/NSR)

View File

@ -177,8 +177,7 @@ public class MuxedSKM extends SessionKeyManager {
public SessionKey consumeTag(SessionTag tag) {
SessionKey rv = _elg.consumeTag(tag);
if (rv == null) {
long stag = RatchetPayload.fromLong8(tag.getData(), 0);
RatchetSessionTag rstag = new RatchetSessionTag(stag);
RatchetSessionTag rstag = new RatchetSessionTag(tag.getData());
rv = _ec.consumeTag(rstag);
}
return rv;

View File

@ -75,7 +75,7 @@ public class RatchetSKM extends SessionKeyManager implements SessionTagListener
private static final int MIN_RCV_WINDOW_NSR = 12;
private static final int MAX_RCV_WINDOW_NSR = 24;
private static final int MIN_RCV_WINDOW_ES = 32;
private static final int MAX_RCV_WINDOW_ES = 96;
private static final int MAX_RCV_WINDOW_ES = 160;
private static final byte[] ZEROLEN = new byte[0];
private static final String INFO_0 = "SessionReplyTags";
@ -744,14 +744,21 @@ public class RatchetSKM extends SessionKeyManager implements SessionTagListener
sets.addAll(e.getValue());
Collections.sort(sets, comp);
totalSets += sets.size();
buf.append("<tr><td><b>Public key:</b> ").append(skey.toBase64()).append("</td>" +
buf.append("<tr><td><b>From public key:</b> ").append(toString(skey)).append("</td>" +
"<td><b>Sets:</b> ").append(sets.size()).append("</td></tr>" +
"<tr class=\"expiry\"><td colspan=\"2\"><ul>");
for (RatchetTagSet ts : sets) {
int size = ts.size();
total += size;
buf.append("<li><b>ID: ").append(ts.getID())
.append('/').append(ts.getDebugID());
buf.append("<li><b>ID: ");
int id = ts.getID();
if (id == RatchetTagSet.DEBUG_IB_NSR)
buf.append("NSR");
else if (id == RatchetTagSet.DEBUG_SINGLE_ES)
buf.append("ES");
else
buf.append(id);
buf.append('/').append(ts.getDebugID());
// inbound sets are multi-column, keep it short
//buf.append(" created:</b> ").append(DataHelper.formatTime(ts.getCreated()))
// .append(" <b>last use:</b> ").append(DataHelper.formatTime(ts.getDate()));
@ -760,7 +767,7 @@ public class RatchetSKM extends SessionKeyManager implements SessionTagListener
buf.append(" expires in:</b> ").append(DataHelper.formatDuration2(expires)).append(" with ");
else
buf.append(" expired:</b> ").append(DataHelper.formatDuration2(0 - expires)).append(" ago with ");
buf.append(size).append('/').append(ts.remaining()).append(" tags remaining</li>");
buf.append(size).append('+').append(ts.remaining() - size).append(" tags remaining</li>");
}
buf.append("</ul></td></tr>\n");
out.write(buf.toString());
@ -782,19 +789,24 @@ public class RatchetSKM extends SessionKeyManager implements SessionTagListener
sets.addAll(sess.getTagSets());
Collections.sort(sets, comp);
totalSets += sets.size();
buf.append("<tr class=\"debug_outboundtarget\"><td><div class=\"debug_targetinfo\"><b>Target public key:</b> ").append(toString(sess.getTarget())).append("<br>" +
buf.append("<tr class=\"debug_outboundtarget\"><td><div class=\"debug_targetinfo\"><b>To public key:</b> ").append(toString(sess.getTarget())).append("<br>" +
"<b>Established:</b> ").append(DataHelper.formatDuration2(now - sess.getEstablishedDate())).append(" ago<br>" +
"<b>Last Used:</b> ").append(DataHelper.formatDuration2(now - sess.getLastUsedDate())).append(" ago<br>");
SessionKey sk = sess.getCurrentKey();
if (sk != null)
buf.append("<b>Session key:</b> ").append(sk.toBase64());
buf.append("</div></td>" +
"<td><b># Sets:</b> ").append(sess.getTagSets().size()).append("</td></tr>" +
"<td><b>Sets:</b> ").append(sets.size()).append("</td></tr>" +
"<tr><td colspan=\"2\"><ul>");
for (RatchetTagSet ts : sets) {
int size = ts.remaining();
buf.append("<li><b>ID: ").append(ts.getID())
.append('/').append(ts.getDebugID())
buf.append("<li><b>ID: ");
int id = ts.getID();
if (id == RatchetTagSet.DEBUG_OB_NSR)
buf.append("NSR");
else
buf.append(id);
buf.append('/').append(ts.getDebugID())
.append(" created:</b> ").append(DataHelper.formatTime(ts.getCreated()))
.append(" <b>last use:</b> ").append(DataHelper.formatTime(ts.getDate()));
long expires = ts.getExpiration() - now;

View File

@ -17,8 +17,11 @@ public class RatchetSessionTag {
_data = val;
}
/**
* @param val will copy the first 8 bytes. Reference will not be kept.
*/
public RatchetSessionTag(byte val[]) {
if (val.length != LENGTH)
if (val.length < LENGTH)
throw new IllegalArgumentException();
_data = RatchetPayload.fromLong8(val, 0);
}

View File

@ -82,8 +82,8 @@ class RatchetTagSet implements TagSetHandle {
private static final int TAGLEN = RatchetSessionTag.LENGTH;
private static final int MAX = 65535;
private static final boolean TEST_RATCHET = false;
// 2 * max streaming window
private static final int LOW = TEST_RATCHET ? (MAX - 100) : 256;
// 4 * max streaming window
private static final int LOW = TEST_RATCHET ? (MAX - 100) : 512;
static final int DEBUG_OB_NSR = 0x10001;
static final int DEBUG_IB_NSR = 0x10002;
static final int DEBUG_SINGLE_ES = 0x10003;
@ -291,27 +291,23 @@ class RatchetTagSet implements TagSetHandle {
* unused tags generated
* @return 0 for outbound
*/
public int size() {
public synchronized int size() {
return _sessionTags != null ? _sessionTags.size() : 0;
}
/**
* tags remaining
* @return 0 - 65535
* @return 0 - 65536
*/
public int remaining() {
int nextKey;
public synchronized int remaining() {
int nextKey = _lastTag + 1;
if (_sessionTags != null) {
// IB
if (_sessionTags.size() <= 0)
nextKey = 0;
else
nextKey = _sessionTags.keyAt(0);
nextKey -= _sessionTags.size();
} else {
// OB
nextKey = _lastTag + 1;
}
return MAX - nextKey;
return MAX + 1 - nextKey;
}
/**
@ -362,19 +358,6 @@ class RatchetTagSet implements TagSetHandle {
return new SessionKey(_nextRootKey);
}
/**
* first tag still available, or null
* inbound only
* testing only
*/
private RatchetSessionTag getFirstTag() {
if (_sessionTags == null)
throw new IllegalStateException("Outbound tagset");
if (_sessionTags.size() <= 0)
return null;
return _sessionTags.valueAt(0);
}
/**
* inbound only
* @return associated SessionKey or null if not found.
@ -383,7 +366,6 @@ class RatchetTagSet implements TagSetHandle {
if (_sessionTags == null)
throw new IllegalStateException("Outbound tagset");
// linear search for tag
// == not equals
int idx = _sessionTags.indexOfValueByValue(tag);
if (idx < 0) {
Log log = I2PAppContext.getGlobalContext().logManager().getLog(RatchetTagSet.class);
@ -430,6 +412,9 @@ class RatchetTagSet implements TagSetHandle {
}
}
/**
* inbound only
*/
private void addTags(int usedTagNumber) {
// add as many as we need to maintain minSize from the tag used
int remaining = _lastTag - usedTagNumber;
@ -474,6 +459,9 @@ class RatchetTagSet implements TagSetHandle {
}
}
/**
* inbound only
*/
private void storeNextTag() {
RatchetSessionTag tag = consumeNext();
if (tag == null)
@ -494,10 +482,8 @@ class RatchetTagSet implements TagSetHandle {
return null;
byte[] tmp = new byte[32];
hkdf.calculate(_sesstag_ck, _sesstag_constant, INFO_4, _sesstag_ck, tmp, 0);
byte[] tag = new byte[TAGLEN];
System.arraycopy(tmp, 0, tag, 0, TAGLEN);
_lastTag++;
return new RatchetSessionTag(tag);
return new RatchetSessionTag(tmp);
}
/**
@ -590,6 +576,21 @@ class RatchetTagSet implements TagSetHandle {
return buf.toString();
}
/**
* first tag still available, or null
* inbound only
* testing only
*/
/****
private RatchetSessionTag getFirstTag() {
if (_sessionTags == null)
throw new IllegalStateException("Outbound tagset");
if (_sessionTags.size() <= 0)
return null;
return _sessionTags.valueAt(0);
}
****/
/**
* tags still available
* inbound only