forked from I2P_Developers/i2p.i2p
Ratchet: TagSet cleanups
Tag.toBase64() optimization Javadoc fixes
This commit is contained in:
@ -304,8 +304,7 @@ public class DatabaseLookupMessage extends FastI2NPMessageImpl {
|
|||||||
* Preliminary, not fully supported, see proposal 154.
|
* Preliminary, not fully supported, see proposal 154.
|
||||||
*
|
*
|
||||||
* @throws IllegalStateException if key or tag previously set, to protect saved checksum
|
* @throws IllegalStateException if key or tag previously set, to protect saved checksum
|
||||||
* @param encryptKey non-null
|
* @param pubKey non-null
|
||||||
* @param encryptTag non-null
|
|
||||||
* @since 0.9.46
|
* @since 0.9.46
|
||||||
*/
|
*/
|
||||||
public void setReplySession(PublicKey pubKey) {
|
public void setReplySession(PublicKey pubKey) {
|
||||||
|
@ -67,7 +67,6 @@ class RatchetPayload {
|
|||||||
public void gotAck(int id, int n);
|
public void gotAck(int id, int n);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param di may be null
|
|
||||||
* @since 0.9.46
|
* @since 0.9.46
|
||||||
*/
|
*/
|
||||||
public void gotAckRequest();
|
public void gotAckRequest();
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
package net.i2p.router.crypto.ratchet;
|
package net.i2p.router.crypto.ratchet;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import net.i2p.data.Base64;
|
import net.i2p.data.Base64;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 8 bytes, usually of random data.
|
* 8 bytes of random data.
|
||||||
* Does not extend SessionTag or DataStructure to save space
|
* Does not extend SessionTag or DataStructure to save space
|
||||||
*
|
*
|
||||||
* @since 0.9.44
|
* @since 0.9.44
|
||||||
@ -25,18 +23,38 @@ public class RatchetSessionTag {
|
|||||||
_data = RatchetPayload.fromLong8(val, 0);
|
_data = RatchetPayload.fromLong8(val, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return data as a byte array
|
||||||
|
*/
|
||||||
public byte[] getData() {
|
public byte[] getData() {
|
||||||
byte[] rv = new byte[LENGTH];
|
byte[] rv = new byte[LENGTH];
|
||||||
RatchetPayload.toLong8(rv, 0, _data);
|
RatchetPayload.toLong8(rv, 0, _data);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return data as a long value
|
||||||
|
* @since 0.9.46
|
||||||
|
*/
|
||||||
|
public long getLong() {
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
public int length() {
|
public int length() {
|
||||||
return LENGTH;
|
return LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 12 chars */
|
||||||
public String toBase64() {
|
public String toBase64() {
|
||||||
return Base64.encode(getData());
|
// for efficiency
|
||||||
|
//return Base64.encode(getData());
|
||||||
|
StringBuilder buf = new StringBuilder(12);
|
||||||
|
for (int i = 58; i > 0; i -= 6) {
|
||||||
|
buf.append(Base64.ALPHABET_I2P.charAt(((int) (_data >> i)) & 0x3f));
|
||||||
|
}
|
||||||
|
buf.append(Base64.ALPHABET_I2P.charAt(((int) (_data << 2)) & 0x3c));
|
||||||
|
buf.append('=');
|
||||||
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,10 +74,20 @@ public class RatchetSessionTag {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder buf = new StringBuilder(64);
|
StringBuilder buf = new StringBuilder(33);
|
||||||
buf.append("[RatchetSessionTag: ");
|
buf.append("[RatchetSessionTag: ");
|
||||||
buf.append(toBase64());
|
buf.append(toBase64());
|
||||||
buf.append(']');
|
buf.append(']');
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// test toBase64()
|
||||||
|
long l = net.i2p.util.RandomSource.getInstance().nextLong();
|
||||||
|
RatchetSessionTag tag = new RatchetSessionTag(l);
|
||||||
|
System.out.println(tag.toBase64());
|
||||||
|
System.out.println(Base64.encode(tag.getData()));
|
||||||
|
}
|
||||||
|
****/
|
||||||
}
|
}
|
||||||
|
@ -227,7 +227,9 @@ class RatchetTagSet implements TagSetHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The identifier for the session.
|
* The root key for the tag set.
|
||||||
|
* Used to match the OB and IB ES tagset 0, where both
|
||||||
|
* will have the same root key.
|
||||||
* Not used for cryptographic operations after setup.
|
* Not used for cryptographic operations after setup.
|
||||||
*/
|
*/
|
||||||
public SessionKey getAssociatedKey() {
|
public SessionKey getAssociatedKey() {
|
||||||
@ -285,11 +287,6 @@ class RatchetTagSet implements TagSetHandle {
|
|||||||
return _created + Math.min(_timeout, RatchetSKM.SESSION_PENDING_DURATION_MS);
|
return _created + Math.min(_timeout, RatchetSKM.SESSION_PENDING_DURATION_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** for debugging */
|
|
||||||
public int getOriginalSize() {
|
|
||||||
return _originalSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* unused tags generated
|
* unused tags generated
|
||||||
* @return 0 for outbound
|
* @return 0 for outbound
|
||||||
@ -365,22 +362,6 @@ class RatchetTagSet implements TagSetHandle {
|
|||||||
return new SessionKey(_nextRootKey);
|
return new SessionKey(_nextRootKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* tags still available
|
|
||||||
* inbound only
|
|
||||||
* testing only
|
|
||||||
*/
|
|
||||||
private List<RatchetSessionTag> getTags() {
|
|
||||||
if (_sessionTags == null)
|
|
||||||
return Collections.emptyList();
|
|
||||||
int sz = _sessionTags.size();
|
|
||||||
List<RatchetSessionTag> rv = new ArrayList<RatchetSessionTag>(sz);
|
|
||||||
for (int i = 0; i < sz; i++) {
|
|
||||||
rv.add(_sessionTags.valueAt(i));
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* first tag still available, or null
|
* first tag still available, or null
|
||||||
* inbound only
|
* inbound only
|
||||||
@ -407,8 +388,8 @@ class RatchetTagSet implements TagSetHandle {
|
|||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
Log log = I2PAppContext.getGlobalContext().logManager().getLog(RatchetTagSet.class);
|
Log log = I2PAppContext.getGlobalContext().logManager().getLog(RatchetTagSet.class);
|
||||||
if (log.shouldWarn())
|
if (log.shouldWarn())
|
||||||
log.warn("Tag not found " + Base64.encode(tag.getData()) +
|
log.warn("Tag not found " + tag.toBase64() +
|
||||||
" Remaining tags: " + getTags(), new Exception());
|
" in:\n" + toString(), new Exception());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
_acked = true;
|
_acked = true;
|
||||||
@ -443,7 +424,7 @@ class RatchetTagSet implements TagSetHandle {
|
|||||||
// dup or some other error
|
// dup or some other error
|
||||||
Log log = I2PAppContext.getGlobalContext().logManager().getLog(RatchetTagSet.class);
|
Log log = I2PAppContext.getGlobalContext().logManager().getLog(RatchetTagSet.class);
|
||||||
if (log.shouldWarn())
|
if (log.shouldWarn())
|
||||||
log.warn("No key found for tag " + Base64.encode(tag.getData()) + " at index " + idx +
|
log.warn("No key found for tag " + tag.toBase64() + " at index " + idx +
|
||||||
" tagnum = " + tagnum + " lastkey = " + _lastKey, new Exception());
|
" tagnum = " + tagnum + " lastkey = " + _lastKey, new Exception());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -540,14 +521,9 @@ class RatchetTagSet implements TagSetHandle {
|
|||||||
return new SessionKeyAndNonce(key, _id, _lastKey, _remoteKey);
|
return new SessionKeyAndNonce(key, _id, _lastKey, _remoteKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* For outbound only, call when we can use it.
|
|
||||||
*/
|
|
||||||
public void setAcked() { _acked = true; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For inbound, returns true after first consume() call.
|
* For inbound, returns true after first consume() call.
|
||||||
* For outbound, returns true after set.
|
* For outbound, returns true after first consumeNextKey() call.
|
||||||
*/
|
*/
|
||||||
public boolean getAcked() { return _acked; }
|
public boolean getAcked() { return _acked; }
|
||||||
|
|
||||||
@ -584,11 +560,11 @@ class RatchetTagSet implements TagSetHandle {
|
|||||||
PublicKey pk = getRemoteKey();
|
PublicKey pk = getRemoteKey();
|
||||||
if (pk != null)
|
if (pk != null)
|
||||||
buf.append("\nRemote Public Key: ").append(pk.toBase64());
|
buf.append("\nRemote Public Key: ").append(pk.toBase64());
|
||||||
buf.append("\nRoot Key: ").append(_key.toBase64());
|
buf.append("\nRoot Key: ").append(_key.toBase64());
|
||||||
if (_tagsetKey != null)
|
if (_tagsetKey != null)
|
||||||
buf.append("\nTagset Key: ").append(_tagsetKey.toBase64());
|
buf.append("\nTagset Key: ").append(_tagsetKey.toBase64());
|
||||||
if (_nextKey != null)
|
if (_nextKey != null)
|
||||||
buf.append("\nNext Key: ").append(_nextKey);
|
buf.append("\nNext Key: ").append(_nextKey);
|
||||||
int sz = size();
|
int sz = size();
|
||||||
buf.append("\nSize: ").append(sz)
|
buf.append("\nSize: ").append(sz)
|
||||||
.append(" Orig: ").append(_originalSize)
|
.append(" Orig: ").append(_originalSize)
|
||||||
@ -601,36 +577,52 @@ class RatchetTagSet implements TagSetHandle {
|
|||||||
RatchetSessionTag tag = _sessionTags.valueAt(i);
|
RatchetSessionTag tag = _sessionTags.valueAt(i);
|
||||||
if (tag == null)
|
if (tag == null)
|
||||||
continue;
|
continue;
|
||||||
buf.append("\n " + n + '\t' + Base64.encode(tag.getData()));
|
buf.append("\n ").append(n).append('\t').append(tag.toBase64());
|
||||||
if (_sessionKeys != null) {
|
if (_sessionKeys != null) {
|
||||||
byte[] key = _sessionKeys.get(n);
|
byte[] key = _sessionKeys.get(n);
|
||||||
if (key != null)
|
if (key != null)
|
||||||
buf.append('\t' + Base64.encode(key));
|
buf.append('\t').append(Base64.encode(key));
|
||||||
else
|
else
|
||||||
buf.append("\tdeferred");
|
buf.append("\tTBD");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tags still available
|
||||||
|
* inbound only
|
||||||
|
* testing only
|
||||||
|
*/
|
||||||
/****
|
/****
|
||||||
|
private List<RatchetSessionTag> getTags() {
|
||||||
|
if (_sessionTags == null)
|
||||||
|
return Collections.emptyList();
|
||||||
|
int sz = _sessionTags.size();
|
||||||
|
List<RatchetSessionTag> rv = new ArrayList<RatchetSessionTag>(sz);
|
||||||
|
for (int i = 0; i < sz; i++) {
|
||||||
|
rv.add(_sessionTags.valueAt(i));
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SessionKey k1 = new SessionKey(new byte[32]);
|
SessionKey k1 = new SessionKey(new byte[32]);
|
||||||
SessionKey k2 = new SessionKey(new byte[32]);
|
SessionKey k2 = new SessionKey(new byte[32]);
|
||||||
System.out.println("Send test");
|
System.out.println("Send test");
|
||||||
HKDF hkdf = new HKDF(I2PAppContext.getGlobalContext());
|
HKDF hkdf = new HKDF(I2PAppContext.getGlobalContext());
|
||||||
RatchetTagSet rts = new RatchetTagSet(hkdf, k1, k2, 0, 0);
|
RatchetTagSet rts = new RatchetTagSet(hkdf, k1, k2, 0, 0, 0);
|
||||||
System.out.println("TAGNUM\tTAG\t\tKEY");
|
System.out.println("TAGNUM\tTAG\t\tKEY");
|
||||||
for (int i = 0; i < 20; i++) {
|
for (int i = 0; i < 20; i++) {
|
||||||
RatchetSessionTag tag = rts.consumeNext();
|
RatchetSessionTag tag = rts.consumeNext();
|
||||||
SessionKey key = rts.consumeNextKey();
|
SessionKey key = rts.consumeNextKey();
|
||||||
System.out.println(i + "\t" + Base64.encode(tag.getData()) + '\t' + Base64.encode(key.getData()));
|
System.out.println(i + "\t" + tag.toBase64() + '\t' + key.toBase64());
|
||||||
}
|
}
|
||||||
System.out.println("Size now: " + rts.size());
|
System.out.println("Size now: " + rts.size());
|
||||||
System.out.println("");
|
System.out.println("");
|
||||||
System.out.println("Receive test in-order");
|
System.out.println("Receive test in-order");
|
||||||
rts = new RatchetTagSet(hkdf, null, (PublicKey) null, k1, k2, 0, 0, 10, 50);
|
rts = new RatchetTagSet(hkdf, null, (PublicKey) null, k1, k2, 0, 0, 0, 10, 50);
|
||||||
System.out.println("Size now: " + rts.size());
|
System.out.println("Size now: " + rts.size());
|
||||||
List<RatchetSessionTag> tags = rts.getTags();
|
List<RatchetSessionTag> tags = rts.getTags();
|
||||||
int j = 0;
|
int j = 0;
|
||||||
@ -638,22 +630,22 @@ class RatchetTagSet implements TagSetHandle {
|
|||||||
for (RatchetSessionTag tag : tags) {
|
for (RatchetSessionTag tag : tags) {
|
||||||
SessionKey key = rts.consume(tag);
|
SessionKey key = rts.consume(tag);
|
||||||
if (key != null)
|
if (key != null)
|
||||||
System.out.println(j++ + "\t" + Base64.encode(tag.getData()) + '\t' + Base64.encode(key.getData()));
|
System.out.println(j++ + "\t" + tag.toBase64() + '\t' + key.toBase64());
|
||||||
else
|
else
|
||||||
System.out.println(j++ + "\t" + Base64.encode(tag.getData()) + "\t NOT FOUND");
|
System.out.println(j++ + "\t" + tag.toBase64() + "\t NOT FOUND");
|
||||||
}
|
}
|
||||||
for (int i = 11; i <= 20; i++) {
|
for (int i = 11; i <= 20; i++) {
|
||||||
RatchetSessionTag tag = rts.getFirstTag();
|
RatchetSessionTag tag = rts.getFirstTag();
|
||||||
SessionKey key = rts.consume(tag);
|
SessionKey key = rts.consume(tag);
|
||||||
if (key != null)
|
if (key != null)
|
||||||
System.out.println(i + "\t" + Base64.encode(tag.getData()) + '\t' + Base64.encode(key.getData()));
|
System.out.println(i + "\t" + tag.toBase64() + '\t' + key.toBase64());
|
||||||
else
|
else
|
||||||
System.out.println(i + "\t" + Base64.encode(tag.getData()) + "\t NOT FOUND");
|
System.out.println(i + "\t" + tag.toBase64() + "\t NOT FOUND");
|
||||||
}
|
}
|
||||||
System.out.println("Size now: " + rts.size());
|
System.out.println("Size now: " + rts.size());
|
||||||
System.out.println("");
|
System.out.println("");
|
||||||
System.out.println("Receive test out of order");
|
System.out.println("Receive test out of order");
|
||||||
rts = new RatchetTagSet(hkdf, null, (PublicKey) null, k1, k2, 0, 0, 10, 50);
|
rts = new RatchetTagSet(hkdf, null, (PublicKey) null, k1, k2, 0, 0, 0, 10, 50);
|
||||||
System.out.println("Size now: " + rts.size());
|
System.out.println("Size now: " + rts.size());
|
||||||
tags = rts.getTags();
|
tags = rts.getTags();
|
||||||
List<RatchetSessionTag> origtags = new ArrayList<RatchetSessionTag>(tags);
|
List<RatchetSessionTag> origtags = new ArrayList<RatchetSessionTag>(tags);
|
||||||
|
Reference in New Issue
Block a user