forked from I2P_Developers/i2p.i2p
Data: Add support for LS2 multiple encryption keys (proposal 123)
This commit is contained in:
@@ -4,6 +4,10 @@ import java.io.ByteArrayOutputStream;
|
|||||||
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.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
@@ -35,9 +39,12 @@ public class LeaseSet2 extends LeaseSet {
|
|||||||
protected Properties _options;
|
protected Properties _options;
|
||||||
// only used for unknown types; else use _encryptionKey.getType()
|
// only used for unknown types; else use _encryptionKey.getType()
|
||||||
private int _encType;
|
private int _encType;
|
||||||
|
// only used if more than one key, otherwise null
|
||||||
|
private List<PublicKey> _encryptionKeys;
|
||||||
|
|
||||||
private static final int FLAG_OFFLINE_KEYS = 1;
|
private static final int FLAG_OFFLINE_KEYS = 1;
|
||||||
private static final int FLAG_UNPUBLISHED = 2;
|
private static final int FLAG_UNPUBLISHED = 2;
|
||||||
|
private static final int MAX_KEYS = 8;
|
||||||
|
|
||||||
public LeaseSet2() {
|
public LeaseSet2() {
|
||||||
super();
|
super();
|
||||||
@@ -59,6 +66,36 @@ public class LeaseSet2 extends LeaseSet {
|
|||||||
return _options.getProperty(opt);
|
return _options.getProperty(opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an encryption key.
|
||||||
|
*/
|
||||||
|
public void addEncryptionKey(PublicKey key) {
|
||||||
|
if (_encryptionKey == null) {
|
||||||
|
setEncryptionKey(key);
|
||||||
|
} else {
|
||||||
|
if (_encryptionKeys == null) {
|
||||||
|
_encryptionKeys = new ArrayList<PublicKey>(4);
|
||||||
|
_encryptionKeys.add(_encryptionKey);
|
||||||
|
} else {
|
||||||
|
if (_encryptionKeys.size() >= MAX_KEYS)
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
_encryptionKeys.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns all the keys. getEncryptionKey() returns the first one.
|
||||||
|
* @return not a copy, do not modify, null if none
|
||||||
|
*/
|
||||||
|
public List<PublicKey> getEncryptionKeys() {
|
||||||
|
if (_encryptionKeys != null)
|
||||||
|
return _encryptionKeys;
|
||||||
|
if (_encryptionKey != null)
|
||||||
|
return Collections.singletonList(_encryptionKey);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure a set of options or statistics that the router can expose.
|
* Configure a set of options or statistics that the router can expose.
|
||||||
* Makes a copy.
|
* Makes a copy.
|
||||||
@@ -193,18 +230,27 @@ public class LeaseSet2 extends LeaseSet {
|
|||||||
readHeader(in);
|
readHeader(in);
|
||||||
// LS2 part
|
// LS2 part
|
||||||
_options = DataHelper.readProperties(in);
|
_options = DataHelper.readProperties(in);
|
||||||
_encType = (int) DataHelper.readLong(in, 2);
|
int numKeys = in.read();
|
||||||
int encLen = (int) DataHelper.readLong(in, 2);
|
if (numKeys <= 0 || numKeys > MAX_KEYS)
|
||||||
// TODO
|
throw new DataFormatException("Bad key count: " + numKeys);
|
||||||
if (_encType == 0) {
|
if (numKeys > 1)
|
||||||
_encryptionKey = PublicKey.create(in);
|
_encryptionKeys = new ArrayList<PublicKey>(numKeys);
|
||||||
} else {
|
for (int i = 0; i < numKeys; i++) {
|
||||||
EncType type = EncType.getByCode(_encType);
|
_encType = (int) DataHelper.readLong(in, 2);
|
||||||
// type will be null if unknown
|
int encLen = (int) DataHelper.readLong(in, 2);
|
||||||
byte[] encKey = new byte[encLen];
|
// TODO
|
||||||
DataHelper.read(in, encKey);
|
if (_encType == 0) {
|
||||||
// this will throw IAE if type is non-null and length is wrong
|
_encryptionKey = PublicKey.create(in);
|
||||||
_encryptionKey = new PublicKey(type, encKey);
|
} else {
|
||||||
|
EncType type = EncType.getByCode(_encType);
|
||||||
|
// type will be null if unknown
|
||||||
|
byte[] encKey = new byte[encLen];
|
||||||
|
DataHelper.read(in, encKey);
|
||||||
|
// this will throw IAE if type is non-null and length is wrong
|
||||||
|
_encryptionKey = new PublicKey(type, encKey);
|
||||||
|
}
|
||||||
|
if (numKeys > 1)
|
||||||
|
_encryptionKeys.add(_encryptionKey);
|
||||||
}
|
}
|
||||||
int numLeases = in.read();
|
int numLeases = in.read();
|
||||||
if (numLeases > MAX_LEASES)
|
if (numLeases > MAX_LEASES)
|
||||||
@@ -246,14 +292,18 @@ public class LeaseSet2 extends LeaseSet {
|
|||||||
} else {
|
} else {
|
||||||
DataHelper.writeLong(out, 2, 0);
|
DataHelper.writeLong(out, 2, 0);
|
||||||
}
|
}
|
||||||
EncType type = _encryptionKey.getType();
|
List<PublicKey> keys = getEncryptionKeys();
|
||||||
if (type != null) {
|
out.write((byte) keys.size());
|
||||||
DataHelper.writeLong(out, 2, type.getCode());
|
for (PublicKey key : keys) {
|
||||||
} else {
|
EncType type = key.getType();
|
||||||
DataHelper.writeLong(out, 2, _encType);
|
if (type != null) {
|
||||||
|
DataHelper.writeLong(out, 2, type.getCode());
|
||||||
|
} else {
|
||||||
|
DataHelper.writeLong(out, 2, _encType);
|
||||||
|
}
|
||||||
|
DataHelper.writeLong(out, 2, key.length());
|
||||||
|
key.writeBytes(out);
|
||||||
}
|
}
|
||||||
DataHelper.writeLong(out, 2, _encryptionKey.length());
|
|
||||||
_encryptionKey.writeBytes(out);
|
|
||||||
out.write((byte) _leases.size());
|
out.write((byte) _leases.size());
|
||||||
for (Lease lease : _leases) {
|
for (Lease lease : _leases) {
|
||||||
lease.writeBytes(out);
|
lease.writeBytes(out);
|
||||||
@@ -433,13 +483,25 @@ public class LeaseSet2 extends LeaseSet {
|
|||||||
StringBuilder buf = new StringBuilder(128);
|
StringBuilder buf = new StringBuilder(128);
|
||||||
buf.append("[LeaseSet2: ");
|
buf.append("[LeaseSet2: ");
|
||||||
buf.append("\n\tDestination: ").append(_destination);
|
buf.append("\n\tDestination: ").append(_destination);
|
||||||
buf.append("\n\tEncryptionKey: ").append(_encryptionKey);
|
List<PublicKey> keys = getEncryptionKeys();
|
||||||
|
int sz = keys.size();
|
||||||
|
buf.append("\n\tEncryption Keys: ").append(sz);
|
||||||
|
for (int i = 0; i < sz; i++) {
|
||||||
|
buf.append("\n\tEncryptionKey ").append(i).append(": ").append(keys.get(i));
|
||||||
|
}
|
||||||
if (isOffline()) {
|
if (isOffline()) {
|
||||||
buf.append("\n\tTransient Key: ").append(_transientSigningPublicKey);
|
buf.append("\n\tTransient Key: ").append(_transientSigningPublicKey);
|
||||||
buf.append("\n\tTransient Expires: ").append(new java.util.Date(_transientExpires));
|
buf.append("\n\tTransient Expires: ").append(new java.util.Date(_transientExpires));
|
||||||
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));
|
||||||
@@ -465,10 +527,10 @@ public class LeaseSet2 extends LeaseSet {
|
|||||||
PrivateKeyFile pkf = new PrivateKeyFile(f);
|
PrivateKeyFile pkf = new PrivateKeyFile(f);
|
||||||
pkf.createIfAbsent(SigType.EdDSA_SHA512_Ed25519);
|
pkf.createIfAbsent(SigType.EdDSA_SHA512_Ed25519);
|
||||||
System.out.println("Online test");
|
System.out.println("Online test");
|
||||||
java.io.File f2 = new java.io.File("online-leaseset.dat");
|
java.io.File f2 = new java.io.File("online-ls2.dat");
|
||||||
test(pkf, f2, false);
|
test(pkf, f2, false);
|
||||||
System.out.println("Offline test");
|
System.out.println("Offline test");
|
||||||
f2 = new java.io.File("offline-leaseset.dat");
|
f2 = new java.io.File("offline-ls2.dat");
|
||||||
test(pkf, f2, true);
|
test(pkf, f2, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -494,10 +556,13 @@ public class LeaseSet2 extends LeaseSet {
|
|||||||
ls2.setDestination(pkf.getDestination());
|
ls2.setDestination(pkf.getDestination());
|
||||||
SimpleDataStructure encKeys[] = net.i2p.crypto.KeyGenerator.getInstance().generatePKIKeys();
|
SimpleDataStructure encKeys[] = net.i2p.crypto.KeyGenerator.getInstance().generatePKIKeys();
|
||||||
PublicKey pubKey = (PublicKey) encKeys[0];
|
PublicKey pubKey = (PublicKey) encKeys[0];
|
||||||
ls2.setEncryptionKey(pubKey);
|
ls2.addEncryptionKey(pubKey);
|
||||||
|
net.i2p.crypto.KeyPair encKeys2 = net.i2p.crypto.KeyGenerator.getInstance().generatePKIKeys(net.i2p.crypto.EncType.ECIES_X25519);
|
||||||
|
pubKey = encKeys2.getPublic();
|
||||||
|
ls2.addEncryptionKey(pubKey);
|
||||||
SigningPrivateKey spk = pkf.getSigningPrivKey();
|
SigningPrivateKey spk = pkf.getSigningPrivKey();
|
||||||
if (offline) {
|
if (offline) {
|
||||||
now += 100000;
|
now += 365*24*60*60*1000L;
|
||||||
SimpleDataStructure transKeys[] = net.i2p.crypto.KeyGenerator.getInstance().generateSigningKeys(SigType.EdDSA_SHA512_Ed25519);
|
SimpleDataStructure transKeys[] = net.i2p.crypto.KeyGenerator.getInstance().generateSigningKeys(SigType.EdDSA_SHA512_Ed25519);
|
||||||
SigningPublicKey transientPub = (SigningPublicKey) transKeys[0];
|
SigningPublicKey transientPub = (SigningPublicKey) transKeys[0];
|
||||||
SigningPrivateKey transientPriv = (SigningPrivateKey) transKeys[1];
|
SigningPrivateKey transientPriv = (SigningPrivateKey) transKeys[1];
|
||||||
|
|||||||
Reference in New Issue
Block a user