forked from I2P_Developers/i2p.i2p
Data: Fix LS2 size(), fix Meta LS2, fix date rouding
This commit is contained in:
@ -187,7 +187,8 @@ public class LeaseSet extends DatabaseEntry {
|
|||||||
public void addLease(Lease lease) {
|
public void addLease(Lease lease) {
|
||||||
if (lease == null) throw new IllegalArgumentException("erm, null lease");
|
if (lease == null) throw new IllegalArgumentException("erm, null lease");
|
||||||
if (lease.getGateway() == null) throw new IllegalArgumentException("erm, lease has no gateway");
|
if (lease.getGateway() == null) throw new IllegalArgumentException("erm, lease has no gateway");
|
||||||
if (lease.getTunnelId() == null) throw new IllegalArgumentException("erm, lease has no tunnel");
|
if (getType() != KEY_TYPE_META_LS2 && lease.getTunnelId() == null)
|
||||||
|
throw new IllegalArgumentException("erm, lease has no tunnel");
|
||||||
if (_signature != null)
|
if (_signature != null)
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
if (_leases.size() >= MAX_LEASES)
|
if (_leases.size() >= MAX_LEASES)
|
||||||
|
@ -324,8 +324,10 @@ public class LeaseSet2 extends LeaseSet {
|
|||||||
_destination.writeBytes(out);
|
_destination.writeBytes(out);
|
||||||
if (_published <= 0)
|
if (_published <= 0)
|
||||||
_published = Clock.getInstance().now();
|
_published = Clock.getInstance().now();
|
||||||
DataHelper.writeLong(out, 4, _published / 1000);
|
long pub1k = _published / 1000;
|
||||||
DataHelper.writeLong(out, 2, (_expires - _published) / 1000);
|
DataHelper.writeLong(out, 4, pub1k);
|
||||||
|
// Divide separately to prevent rounding errors
|
||||||
|
DataHelper.writeLong(out, 2, ((_expires / 1000) - pub1k));
|
||||||
DataHelper.writeLong(out, 2, _flags);
|
DataHelper.writeLong(out, 2, _flags);
|
||||||
if (isOffline())
|
if (isOffline())
|
||||||
writeOfflineBytes(out);
|
writeOfflineBytes(out);
|
||||||
@ -359,11 +361,14 @@ public class LeaseSet2 extends LeaseSet {
|
|||||||
@Override
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
int rv = _destination.size()
|
int rv = _destination.size()
|
||||||
+ _encryptionKey.length()
|
+ 10
|
||||||
+ 11
|
|
||||||
+ (_leases.size() * 40);
|
+ (_leases.size() * 40);
|
||||||
|
for (PublicKey key : getEncryptionKeys()) {
|
||||||
|
rv += 4;
|
||||||
|
rv += key.length();
|
||||||
|
}
|
||||||
if (isOffline())
|
if (isOffline())
|
||||||
rv += 2 + _transientSigningPublicKey.length() + _offlineSignature.length();
|
rv += 6 + _transientSigningPublicKey.length() + _offlineSignature.length();
|
||||||
if (_options != null && !_options.isEmpty()) {
|
if (_options != null && !_options.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
rv += DataHelper.toProperties(_options).length;
|
rv += DataHelper.toProperties(_options).length;
|
||||||
@ -382,7 +387,7 @@ public class LeaseSet2 extends LeaseSet {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void addLease(Lease lease) {
|
public void addLease(Lease lease) {
|
||||||
if (!(lease instanceof Lease2))
|
if (getType() == KEY_TYPE_LS2 && !(lease instanceof Lease2))
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
super.addLease(lease);
|
super.addLease(lease);
|
||||||
_expires = _lastExpiration;
|
_expires = _lastExpiration;
|
||||||
@ -590,6 +595,8 @@ public class LeaseSet2 extends LeaseSet {
|
|||||||
ls2.writeBytes(out2);
|
ls2.writeBytes(out2);
|
||||||
out2.close();
|
out2.close();
|
||||||
java.io.ByteArrayInputStream in = new java.io.ByteArrayInputStream(out.toByteArray());
|
java.io.ByteArrayInputStream in = new java.io.ByteArrayInputStream(out.toByteArray());
|
||||||
|
System.out.println("Size calculated: " + (ls2.size() + ls2.getSignature().length()));
|
||||||
|
System.out.println("Size to read in: " + in.available());
|
||||||
LeaseSet2 ls3 = new LeaseSet2();
|
LeaseSet2 ls3 = new LeaseSet2();
|
||||||
ls3.readBytes(in);
|
ls3.readBytes(in);
|
||||||
System.out.println("Read back: " + ls3);
|
System.out.println("Read back: " + ls3);
|
||||||
|
@ -79,4 +79,15 @@ public class MetaLease extends Lease {
|
|||||||
return (int) _end.getTime() ^ DataHelper.hashCode(_gateway)
|
return (int) _end.getTime() ^ DataHelper.hashCode(_gateway)
|
||||||
^ _cost;
|
^ _cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder buf = new StringBuilder(128);
|
||||||
|
buf.append("[Meta Lease: ");
|
||||||
|
buf.append("\n\tEnd Date: ").append(_end);
|
||||||
|
buf.append("\n\tTarget: ").append(_gateway);
|
||||||
|
buf.append("\n\tCost: ").append(_cost);
|
||||||
|
buf.append("]");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package net.i2p.data;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import net.i2p.crypto.SigType;
|
import net.i2p.crypto.SigType;
|
||||||
|
|
||||||
@ -24,6 +25,22 @@ public class MetaLeaseSet extends LeaseSet2 {
|
|||||||
return KEY_TYPE_META_LS2;
|
return KEY_TYPE_META_LS2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws UnsupportedOperationException always
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setEncryptionKey(PublicKey key) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws UnsupportedOperationException always
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void addEncryptionKey(PublicKey key) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This does NOT validate the signature
|
* This does NOT validate the signature
|
||||||
*
|
*
|
||||||
@ -64,7 +81,7 @@ public class MetaLeaseSet extends LeaseSet2 {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void writeBytesWithoutSig(OutputStream out) throws DataFormatException, IOException {
|
protected void writeBytesWithoutSig(OutputStream out) throws DataFormatException, IOException {
|
||||||
if (_destination == null || _encryptionKey == null)
|
if (_destination == null)
|
||||||
throw new DataFormatException("Not enough data to write out a LeaseSet");
|
throw new DataFormatException("Not enough data to write out a LeaseSet");
|
||||||
// LS2 header
|
// LS2 header
|
||||||
writeHeader(out);
|
writeHeader(out);
|
||||||
@ -88,10 +105,10 @@ public class MetaLeaseSet extends LeaseSet2 {
|
|||||||
@Override
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
int rv = _destination.size()
|
int rv = _destination.size()
|
||||||
+ 2
|
+ 10
|
||||||
+ (_leases.size() * 40);
|
+ (_leases.size() * 40);
|
||||||
if (isOffline())
|
if (isOffline())
|
||||||
rv += 2 + _transientSigningPublicKey.length() + _offlineSignature.length();
|
rv += 6 + _transientSigningPublicKey.length() + _offlineSignature.length();
|
||||||
if (_options != null && !_options.isEmpty()) {
|
if (_options != null && !_options.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
rv += DataHelper.toProperties(_options).length;
|
rv += DataHelper.toProperties(_options).length;
|
||||||
@ -101,6 +118,8 @@ public class MetaLeaseSet extends LeaseSet2 {
|
|||||||
} else {
|
} else {
|
||||||
rv += 2;
|
rv += 2;
|
||||||
}
|
}
|
||||||
|
// revocations TODO
|
||||||
|
// rv += 32 * numRevocations
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,16 +143,13 @@ public class MetaLeaseSet extends LeaseSet2 {
|
|||||||
return
|
return
|
||||||
DataHelper.eq(_signature, ls.getSignature())
|
DataHelper.eq(_signature, ls.getSignature())
|
||||||
&& DataHelper.eq(_leases, ls._leases)
|
&& DataHelper.eq(_leases, ls._leases)
|
||||||
&& DataHelper.eq(getEncryptionKey(), ls.getEncryptionKey())
|
|
||||||
&& DataHelper.eq(_destination, ls.getDestination());
|
&& DataHelper.eq(_destination, ls.getDestination());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** the destination has enough randomness in it to use it by itself for speed */
|
/** the destination has enough randomness in it to use it by itself for speed */
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
if (_destination == null)
|
return super.hashCode();
|
||||||
return 0;
|
|
||||||
return _destination.hashCode();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -147,6 +163,13 @@ public class MetaLeaseSet extends LeaseSet2 {
|
|||||||
buf.append("\n\tOffline Signature: ").append(_offlineSignature);
|
buf.append("\n\tOffline Signature: ").append(_offlineSignature);
|
||||||
}
|
}
|
||||||
buf.append("\n\tOptions: ").append((_options != null) ? _options.size() : 0);
|
buf.append("\n\tOptions: ").append((_options != null) ? _options.size() : 0);
|
||||||
|
if (_options != null && !_options.isEmpty()) {
|
||||||
|
for (Map.Entry<Object, Object> e : _options.entrySet()) {
|
||||||
|
String key = (String) e.getKey();
|
||||||
|
String val = (String) e.getValue();
|
||||||
|
buf.append("\n\t\t[").append(key).append("] = [").append(val).append("]");
|
||||||
|
}
|
||||||
|
}
|
||||||
buf.append("\n\tSignature: ").append(_signature);
|
buf.append("\n\tSignature: ").append(_signature);
|
||||||
buf.append("\n\tPublished: ").append(new java.util.Date(_published));
|
buf.append("\n\tPublished: ").append(new java.util.Date(_published));
|
||||||
buf.append("\n\tExpires: ").append(new java.util.Date(_expires));
|
buf.append("\n\tExpires: ").append(new java.util.Date(_expires));
|
||||||
@ -156,4 +179,78 @@ public class MetaLeaseSet extends LeaseSet2 {
|
|||||||
buf.append("]");
|
buf.append("]");
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
if (args.length != 1) {
|
||||||
|
System.out.println("Usage: MetaLeaseSet privatekeyfile.dat");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
java.io.File f = new java.io.File(args[0]);
|
||||||
|
PrivateKeyFile pkf = new PrivateKeyFile(f);
|
||||||
|
pkf.createIfAbsent(SigType.EdDSA_SHA512_Ed25519);
|
||||||
|
System.out.println("Online test");
|
||||||
|
java.io.File f2 = new java.io.File("online-metals2.dat");
|
||||||
|
test(pkf, f2, false);
|
||||||
|
System.out.println("Offline test");
|
||||||
|
f2 = new java.io.File("offline-metals2.dat");
|
||||||
|
test(pkf, f2, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void test(PrivateKeyFile pkf, java.io.File outfile, boolean offline) throws Exception {
|
||||||
|
net.i2p.util.RandomSource rand = net.i2p.util.RandomSource.getInstance();
|
||||||
|
long now = System.currentTimeMillis() + 5*60*1000;
|
||||||
|
MetaLeaseSet ls2 = new MetaLeaseSet();
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
MetaLease l2 = new MetaLease();
|
||||||
|
now += 10000;
|
||||||
|
l2.setEndDate(new java.util.Date(now));
|
||||||
|
byte[] gw = new byte[32];
|
||||||
|
rand.nextBytes(gw);
|
||||||
|
l2.setGateway(new Hash(gw));
|
||||||
|
l2.setCost(i * 5);
|
||||||
|
ls2.addLease(l2);
|
||||||
|
}
|
||||||
|
java.util.Properties opts = new java.util.Properties();
|
||||||
|
opts.setProperty("foo", "bar");
|
||||||
|
opts.setProperty("test", "bazzle");
|
||||||
|
ls2.setOptions(opts);
|
||||||
|
ls2.setDestination(pkf.getDestination());
|
||||||
|
SigningPrivateKey spk = pkf.getSigningPrivKey();
|
||||||
|
if (offline) {
|
||||||
|
now += 365*24*60*60*1000L;
|
||||||
|
SimpleDataStructure transKeys[] = net.i2p.crypto.KeyGenerator.getInstance().generateSigningKeys(SigType.EdDSA_SHA512_Ed25519);
|
||||||
|
SigningPublicKey transientPub = (SigningPublicKey) transKeys[0];
|
||||||
|
SigningPrivateKey transientPriv = (SigningPrivateKey) transKeys[1];
|
||||||
|
Signature sig = offlineSign(now, transientPub, spk);
|
||||||
|
ls2.setOfflineSignature(now, transientPub, sig);
|
||||||
|
ls2.sign(transientPriv);
|
||||||
|
} else {
|
||||||
|
ls2.sign(spk);
|
||||||
|
}
|
||||||
|
System.out.println("Created: " + ls2);
|
||||||
|
if (!ls2.verifySignature())
|
||||||
|
System.out.println("Verify FAILED");
|
||||||
|
java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
|
||||||
|
ls2.writeBytes(out);
|
||||||
|
java.io.OutputStream out2 = new java.io.FileOutputStream(outfile);
|
||||||
|
ls2.writeBytes(out2);
|
||||||
|
out2.close();
|
||||||
|
java.io.ByteArrayInputStream in = new java.io.ByteArrayInputStream(out.toByteArray());
|
||||||
|
System.out.println("Size calculated: " + (ls2.size() + ls2.getSignature().length()));
|
||||||
|
System.out.println("Size to read in: " + in.available());
|
||||||
|
LeaseSet2 ls3 = new MetaLeaseSet();
|
||||||
|
ls3.readBytes(in);
|
||||||
|
System.out.println("Read back: " + ls3);
|
||||||
|
if (!ls3.verifySignature()) {
|
||||||
|
System.out.println("Verify FAILED");
|
||||||
|
System.out.println("Wrote out");
|
||||||
|
byte[] b2 = ls2.toByteArray();
|
||||||
|
System.out.println(net.i2p.util.HexDump.dump(b2));
|
||||||
|
System.out.println("Read in");
|
||||||
|
byte[] b3 = ls3.toByteArray();
|
||||||
|
System.out.println(net.i2p.util.HexDump.dump(b3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
****/
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user