forked from I2P_Developers/i2p.i2p
i2cp.leaseSetEncType param:
Support comma-separated values, check param in session config, support stored EncTypes in private keys. Show types and multiple keys on LS debug page
This commit is contained in:
@ -25,6 +25,7 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
import net.i2p.crypto.EncType;
|
||||||
import net.i2p.crypto.SigType;
|
import net.i2p.crypto.SigType;
|
||||||
import net.i2p.data.DatabaseEntry;
|
import net.i2p.data.DatabaseEntry;
|
||||||
import net.i2p.data.DataHelper;
|
import net.i2p.data.DataHelper;
|
||||||
@ -33,6 +34,7 @@ import net.i2p.data.Hash;
|
|||||||
import net.i2p.data.Lease;
|
import net.i2p.data.Lease;
|
||||||
import net.i2p.data.LeaseSet;
|
import net.i2p.data.LeaseSet;
|
||||||
import net.i2p.data.LeaseSet2;
|
import net.i2p.data.LeaseSet2;
|
||||||
|
import net.i2p.data.PublicKey;
|
||||||
import net.i2p.data.router.RouterAddress;
|
import net.i2p.data.router.RouterAddress;
|
||||||
import net.i2p.data.router.RouterInfo;
|
import net.i2p.data.router.RouterInfo;
|
||||||
import net.i2p.router.RouterContext;
|
import net.i2p.router.RouterContext;
|
||||||
@ -533,8 +535,24 @@ class NetDbRenderer {
|
|||||||
buf.append("</td></tr>\n<tr><td colspan=\"2\">");
|
buf.append("</td></tr>\n<tr><td colspan=\"2\">");
|
||||||
//buf.append(dest.toBase32()).append("<br>");
|
//buf.append(dest.toBase32()).append("<br>");
|
||||||
buf.append("<b>Signature type:</b> ").append(dest.getSigningPublicKey().getType());
|
buf.append("<b>Signature type:</b> ").append(dest.getSigningPublicKey().getType());
|
||||||
if (type != DatabaseEntry.KEY_TYPE_META_LS2)
|
if (type == DatabaseEntry.KEY_TYPE_LEASESET) {
|
||||||
buf.append(" <b>Encryption Key:</b> ").append(ls.getEncryptionKey().toBase64().substring(0, 20)).append("…");
|
buf.append("</td></tr>\n<tr><td colspan=\"2\"><b>Encryption Key:</b> ELGAMAL_2048 ")
|
||||||
|
.append(ls.getEncryptionKey().toBase64().substring(0, 20))
|
||||||
|
.append("…");
|
||||||
|
} else if (type == DatabaseEntry.KEY_TYPE_LS2) {
|
||||||
|
LeaseSet2 ls2 = (LeaseSet2) ls;
|
||||||
|
for (PublicKey pk : ls2.getEncryptionKeys()) {
|
||||||
|
buf.append("</td></tr>\n<tr><td colspan=\"2\"><b>Encryption Key:</b> ");
|
||||||
|
EncType etype = pk.getType();
|
||||||
|
if (etype != null)
|
||||||
|
buf.append(etype);
|
||||||
|
else
|
||||||
|
buf.append("Unsupported type ").append(pk.getUnknownTypeCode());
|
||||||
|
buf.append(' ')
|
||||||
|
.append(pk.toBase64().substring(0, 20))
|
||||||
|
.append("…");
|
||||||
|
}
|
||||||
|
}
|
||||||
buf.append("</td></tr>\n<tr><td colspan=\"2\">");
|
buf.append("</td></tr>\n<tr><td colspan=\"2\">");
|
||||||
buf.append("<b>Routing Key:</b> ").append(ls.getRoutingKey().toBase64());
|
buf.append("<b>Routing Key:</b> ").append(ls.getRoutingKey().toBase64());
|
||||||
buf.append("</td></tr>");
|
buf.append("</td></tr>");
|
||||||
|
@ -11,6 +11,10 @@ package net.i2p.client.impl;
|
|||||||
|
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@ -90,8 +94,7 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
return true;
|
return true;
|
||||||
String s = session.getOptions().getProperty(PROP_LS_ENCTYPE);
|
String s = session.getOptions().getProperty(PROP_LS_ENCTYPE);
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
EncType type = EncType.parseEncType(s);
|
if (!s.equals("0") && !s.equals("ELGAMAL_2048"))
|
||||||
if (type != null && type != EncType.ELGAMAL_2048 && type.isAvailable())
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
s = session.getOptions().getProperty(PROP_LS_TYPE);
|
s = session.getOptions().getProperty(PROP_LS_TYPE);
|
||||||
@ -150,14 +153,14 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
//lease.setStartDate(msg.getStartDate());
|
//lease.setStartDate(msg.getStartDate());
|
||||||
leaseSet.addLease(lease);
|
leaseSet.addLease(lease);
|
||||||
}
|
}
|
||||||
signLeaseSet(leaseSet, session);
|
signLeaseSet(leaseSet, isLS2, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finish creating and signing the new LeaseSet
|
* Finish creating and signing the new LeaseSet
|
||||||
* @since 0.9.7
|
* @since 0.9.7
|
||||||
*/
|
*/
|
||||||
protected synchronized void signLeaseSet(LeaseSet leaseSet, I2PSessionImpl session) {
|
protected synchronized void signLeaseSet(LeaseSet leaseSet, boolean isLS2, I2PSessionImpl session) {
|
||||||
Destination dest = session.getMyDestination();
|
Destination dest = session.getMyDestination();
|
||||||
// also, if this session is connected to multiple routers, include other leases here
|
// also, if this session is connected to multiple routers, include other leases here
|
||||||
leaseSet.setDestination(dest);
|
leaseSet.setDestination(dest);
|
||||||
@ -165,11 +168,11 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
// reuse the old keys for the client
|
// reuse the old keys for the client
|
||||||
LeaseInfo li = _existingLeaseSets.get(dest);
|
LeaseInfo li = _existingLeaseSets.get(dest);
|
||||||
if (li == null) {
|
if (li == null) {
|
||||||
// [enctype:]b64 of private key
|
// [enctype:]b64,... of private keys
|
||||||
String spk = session.getOptions().getProperty(PROP_LS_PK);
|
String spk = session.getOptions().getProperty(PROP_LS_PK);
|
||||||
// [sigtype:]b64 of private key
|
// [sigtype:]b64 of private key
|
||||||
String sspk = session.getOptions().getProperty(PROP_LS_SPK);
|
String sspk = session.getOptions().getProperty(PROP_LS_SPK);
|
||||||
PrivateKey privKey = null;
|
List<PrivateKey> privKeys = new ArrayList<PrivateKey>(2);
|
||||||
SigningPrivateKey signingPrivKey = null;
|
SigningPrivateKey signingPrivKey = null;
|
||||||
if (spk != null && sspk != null) {
|
if (spk != null && sspk != null) {
|
||||||
boolean useOldKeys = true;
|
boolean useOldKeys = true;
|
||||||
@ -183,69 +186,69 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
else
|
else
|
||||||
useOldKeys = false;
|
useOldKeys = false;
|
||||||
}
|
}
|
||||||
colon = spk.indexOf(':');
|
|
||||||
// just ignore for now, no other types supported
|
|
||||||
if (colon >= 0)
|
|
||||||
spk = spk.substring(colon + 1);
|
|
||||||
if (useOldKeys) {
|
if (useOldKeys) {
|
||||||
try {
|
try {
|
||||||
signingPrivKey = new SigningPrivateKey(type);
|
signingPrivKey = new SigningPrivateKey(type);
|
||||||
signingPrivKey.fromBase64(sspk);
|
signingPrivKey.fromBase64(sspk);
|
||||||
} catch (DataFormatException iae) {
|
} catch (DataFormatException dfe) {
|
||||||
useOldKeys = false;
|
useOldKeys = false;
|
||||||
signingPrivKey = null;
|
signingPrivKey = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (useOldKeys) {
|
if (useOldKeys) {
|
||||||
try {
|
parsePrivateKeys(spk, privKeys);
|
||||||
privKey = new PrivateKey();
|
|
||||||
privKey.fromBase64(spk);
|
|
||||||
} catch (DataFormatException iae) {
|
|
||||||
privKey = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (privKeys.isEmpty() && !_existingLeaseSets.isEmpty()) {
|
||||||
if (privKey == null && !_existingLeaseSets.isEmpty()) {
|
// look for private keys from another dest using same pubkey
|
||||||
// look for keypair from another dest using same pubkey
|
|
||||||
PublicKey pk = dest.getPublicKey();
|
PublicKey pk = dest.getPublicKey();
|
||||||
for (Map.Entry<Destination, LeaseInfo> e : _existingLeaseSets.entrySet()) {
|
for (Map.Entry<Destination, LeaseInfo> e : _existingLeaseSets.entrySet()) {
|
||||||
if (pk.equals(e.getKey().getPublicKey())) {
|
if (pk.equals(e.getKey().getPublicKey())) {
|
||||||
privKey = e.getValue().getPrivateKey();
|
privKeys.addAll(e.getValue().getPrivateKeys());
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Creating new leaseInfo keys for " + dest + " with private key from " + e.getKey());
|
_log.debug("Creating new leaseInfo keys for " + dest + " with private key from " + e.getKey());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (privKey != null) {
|
if (!privKeys.isEmpty()) {
|
||||||
if (signingPrivKey != null) {
|
if (signingPrivKey != null) {
|
||||||
li = new LeaseInfo(privKey, signingPrivKey);
|
li = new LeaseInfo(privKeys, signingPrivKey);
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Creating new leaseInfo keys for " + dest + " WITH configured private keys");
|
_log.debug("Creating new leaseInfo keys for " + dest + " WITH configured private keys");
|
||||||
} else {
|
} else {
|
||||||
li = new LeaseInfo(privKey, dest);
|
li = new LeaseInfo(privKeys, dest);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
EncType type = EncType.ELGAMAL_2048;
|
List<EncType> types = new ArrayList<EncType>(2);
|
||||||
String senc = session.getOptions().getProperty(PROP_LS_ENCTYPE);
|
String senc = session.getOptions().getProperty(PROP_LS_ENCTYPE);
|
||||||
if (senc != null) {
|
if (senc != null) {
|
||||||
EncType newtype = EncType.parseEncType(senc);
|
String[] senca = DataHelper.split(senc, ",");
|
||||||
|
for (String sencaa : senca) {
|
||||||
|
EncType newtype = EncType.parseEncType(sencaa);
|
||||||
if (newtype != null) {
|
if (newtype != null) {
|
||||||
|
if (types.contains(newtype)) {
|
||||||
|
_log.error("Duplicate crypto type: " + newtype);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (newtype.isAvailable()) {
|
if (newtype.isAvailable()) {
|
||||||
type = newtype;
|
types.add(newtype);
|
||||||
if (_log.shouldDebug())
|
if (_log.shouldDebug())
|
||||||
_log.debug("Using crypto type: " + type);
|
_log.debug("Using crypto type: " + newtype);
|
||||||
} else {
|
} else {
|
||||||
_log.error("Unsupported crypto.encType: " + newtype);
|
_log.error("Unsupported crypto type: " + newtype);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_log.error("Bad crypto.encType: " + senc);
|
_log.error("Unsupported crypto type: " + sencaa);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
if (types.isEmpty()) {
|
||||||
if (_log.shouldDebug())
|
if (_log.shouldDebug())
|
||||||
_log.debug("Using default crypto type");
|
_log.debug("Using default crypto type");
|
||||||
|
types.add(EncType.ELGAMAL_2048);
|
||||||
}
|
}
|
||||||
li = new LeaseInfo(dest, type);
|
li = new LeaseInfo(dest, types);
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Creating new leaseInfo keys for " + dest + " without configured private keys");
|
_log.debug("Creating new leaseInfo keys for " + dest + " without configured private keys");
|
||||||
}
|
}
|
||||||
@ -256,8 +259,16 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
+ dest);
|
+ dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_ls2Type != DatabaseEntry.KEY_TYPE_META_LS2)
|
if (isLS2) {
|
||||||
|
LeaseSet2 ls2 = (LeaseSet2) leaseSet;
|
||||||
|
if (_ls2Type != DatabaseEntry.KEY_TYPE_META_LS2) {
|
||||||
|
for (PublicKey key : li.getPublicKeys()) {
|
||||||
|
ls2.addEncryptionKey(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
leaseSet.setEncryptionKey(li.getPublicKey());
|
leaseSet.setEncryptionKey(li.getPublicKey());
|
||||||
|
}
|
||||||
leaseSet.setSigningKey(li.getSigningPublicKey());
|
leaseSet.setSigningKey(li.getSigningPublicKey());
|
||||||
// SubSession options aren't updated via the gui, so use the primary options
|
// SubSession options aren't updated via the gui, so use the primary options
|
||||||
Properties opts;
|
Properties opts;
|
||||||
@ -325,17 +336,72 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param spk non-null [type:]b64[,[type:]b64]...
|
||||||
|
* @param privKeys out parameter
|
||||||
|
* @since 0.9.39
|
||||||
|
*/
|
||||||
|
private void parsePrivateKeys(String spkl, List<PrivateKey> privKeys) {
|
||||||
|
String[] spks = DataHelper.split(spkl, ",");
|
||||||
|
for (String spk : spks) {
|
||||||
|
int colon = spk.indexOf(':');
|
||||||
|
if (colon > 0) {
|
||||||
|
EncType type = EncType.parseEncType(spk.substring(0, colon));
|
||||||
|
if (type != null) {
|
||||||
|
if (type.isAvailable()) {
|
||||||
|
try {
|
||||||
|
PrivateKey privKey = new PrivateKey(type);
|
||||||
|
privKey.fromBase64(spk.substring(colon + 1));
|
||||||
|
privKeys.add(privKey);
|
||||||
|
if (_log.shouldDebug())
|
||||||
|
_log.debug("Using crypto type: " + type);
|
||||||
|
} catch (DataFormatException dfe) {
|
||||||
|
_log.error("Bad private key: " + spk, dfe);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_log.error("Unsupported crypto type: " + type);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_log.error("Unsupported crypto type: " + spk);
|
||||||
|
}
|
||||||
|
} else if (colon < 0) {
|
||||||
|
try {
|
||||||
|
PrivateKey privKey = new PrivateKey();
|
||||||
|
privKey.fromBase64(spk);
|
||||||
|
privKeys.add(privKey);
|
||||||
|
} catch (DataFormatException dfe) {
|
||||||
|
_log.error("Bad private key: " + spk, dfe);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_log.error("Empty crypto type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiple encryption keys supported, as of 0.9.39, for LS2
|
||||||
|
*/
|
||||||
private static class LeaseInfo {
|
private static class LeaseInfo {
|
||||||
private final PublicKey _pubKey;
|
private final List<PublicKey> _pubKeys;
|
||||||
private final PrivateKey _privKey;
|
private final List<PrivateKey> _privKeys;
|
||||||
private final SigningPublicKey _signingPubKey;
|
private final SigningPublicKey _signingPubKey;
|
||||||
private final SigningPrivateKey _signingPrivKey;
|
private final SigningPrivateKey _signingPrivKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New keys
|
* New keys
|
||||||
|
* @param types must be available
|
||||||
*/
|
*/
|
||||||
public LeaseInfo(Destination dest, EncType type) {
|
public LeaseInfo(Destination dest, List<EncType> types) {
|
||||||
|
if (types.size() > 1) {
|
||||||
|
Collections.sort(types, Collections.reverseOrder());
|
||||||
|
}
|
||||||
|
_privKeys = new ArrayList<PrivateKey>(types.size());
|
||||||
|
_pubKeys = new ArrayList<PublicKey>(types.size());
|
||||||
|
for (EncType type : types) {
|
||||||
KeyPair encKeys = KeyGenerator.getInstance().generatePKIKeys(type);
|
KeyPair encKeys = KeyGenerator.getInstance().generatePKIKeys(type);
|
||||||
|
_pubKeys.add(encKeys.getPublic());
|
||||||
|
_privKeys.add(encKeys.getPrivate());
|
||||||
|
}
|
||||||
// must be same type as the Destination's signing key
|
// must be same type as the Destination's signing key
|
||||||
SimpleDataStructure signKeys[];
|
SimpleDataStructure signKeys[];
|
||||||
try {
|
try {
|
||||||
@ -343,46 +409,67 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
} catch (GeneralSecurityException gse) {
|
} catch (GeneralSecurityException gse) {
|
||||||
throw new IllegalStateException(gse);
|
throw new IllegalStateException(gse);
|
||||||
}
|
}
|
||||||
_pubKey = encKeys.getPublic();
|
|
||||||
_privKey = encKeys.getPrivate();
|
|
||||||
_signingPubKey = (SigningPublicKey) signKeys[0];
|
_signingPubKey = (SigningPublicKey) signKeys[0];
|
||||||
_signingPrivKey = (SigningPrivateKey) signKeys[1];
|
_signingPrivKey = (SigningPrivateKey) signKeys[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Existing keys
|
* Existing keys
|
||||||
|
* @param privKeys all EncTypes must be available
|
||||||
* @since 0.9.18
|
* @since 0.9.18
|
||||||
*/
|
*/
|
||||||
public LeaseInfo(PrivateKey privKey, SigningPrivateKey signingPrivKey) {
|
public LeaseInfo(List<PrivateKey> privKeys, SigningPrivateKey signingPrivKey) {
|
||||||
_pubKey = KeyGenerator.getPublicKey(privKey);
|
if (privKeys.size() > 1) {
|
||||||
_privKey = privKey;
|
Collections.sort(privKeys, new PrivKeyComparator());
|
||||||
|
}
|
||||||
|
_privKeys = privKeys;
|
||||||
|
_pubKeys = new ArrayList<PublicKey>(privKeys.size());
|
||||||
|
for (PrivateKey privKey : privKeys) {
|
||||||
|
_pubKeys.add(KeyGenerator.getPublicKey(privKey));
|
||||||
|
}
|
||||||
_signingPubKey = KeyGenerator.getSigningPublicKey(signingPrivKey);
|
_signingPubKey = KeyGenerator.getSigningPublicKey(signingPrivKey);
|
||||||
_signingPrivKey = signingPrivKey;
|
_signingPrivKey = signingPrivKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Existing crypto key, new signing key
|
* Existing crypto keys, new signing key
|
||||||
|
* @param privKeys all EncTypes must be available
|
||||||
* @since 0.9.21
|
* @since 0.9.21
|
||||||
*/
|
*/
|
||||||
public LeaseInfo(PrivateKey privKey, Destination dest) {
|
public LeaseInfo(List<PrivateKey> privKeys, Destination dest) {
|
||||||
SimpleDataStructure signKeys[];
|
SimpleDataStructure signKeys[];
|
||||||
try {
|
try {
|
||||||
signKeys = KeyGenerator.getInstance().generateSigningKeys(dest.getSigningPublicKey().getType());
|
signKeys = KeyGenerator.getInstance().generateSigningKeys(dest.getSigningPublicKey().getType());
|
||||||
} catch (GeneralSecurityException gse) {
|
} catch (GeneralSecurityException gse) {
|
||||||
throw new IllegalStateException(gse);
|
throw new IllegalStateException(gse);
|
||||||
}
|
}
|
||||||
_pubKey = KeyGenerator.getPublicKey(privKey);
|
_privKeys = privKeys;
|
||||||
_privKey = privKey;
|
_pubKeys = new ArrayList<PublicKey>(privKeys.size());
|
||||||
|
for (PrivateKey privKey : privKeys) {
|
||||||
|
_pubKeys.add(KeyGenerator.getPublicKey(privKey));
|
||||||
|
}
|
||||||
_signingPubKey = (SigningPublicKey) signKeys[0];
|
_signingPubKey = (SigningPublicKey) signKeys[0];
|
||||||
_signingPrivKey = (SigningPrivateKey) signKeys[1];
|
_signingPrivKey = (SigningPrivateKey) signKeys[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return the first one if more than one */
|
||||||
public PublicKey getPublicKey() {
|
public PublicKey getPublicKey() {
|
||||||
return _pubKey;
|
return _pubKeys.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return the first one if more than one */
|
||||||
public PrivateKey getPrivateKey() {
|
public PrivateKey getPrivateKey() {
|
||||||
return _privKey;
|
return _privKeys.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 0.9.39 */
|
||||||
|
public List<PublicKey> getPublicKeys() {
|
||||||
|
return _pubKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 0.9.39 */
|
||||||
|
public List<PrivateKey> getPrivateKeys() {
|
||||||
|
return _privKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SigningPublicKey getSigningPublicKey() {
|
public SigningPublicKey getSigningPublicKey() {
|
||||||
@ -393,19 +480,14 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
return _signingPrivKey;
|
return _signingPrivKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public int hashCode() {
|
* Reverse order by enc type
|
||||||
return DataHelper.hashCode(_pubKey) + 7 * DataHelper.hashCode(_privKey) + 7 * 7
|
* @since 0.9.39
|
||||||
* DataHelper.hashCode(_signingPubKey) + 7 * 7 * 7 * DataHelper.hashCode(_signingPrivKey);
|
*/
|
||||||
}
|
private static class PrivKeyComparator implements Comparator<PrivateKey> {
|
||||||
|
public int compare(PrivateKey l, PrivateKey r) {
|
||||||
@Override
|
return r.getType().compareTo(l.getType());
|
||||||
public boolean equals(Object obj) {
|
}
|
||||||
if ((obj == null) || !(obj instanceof LeaseInfo)) return false;
|
|
||||||
LeaseInfo li = (LeaseInfo) obj;
|
|
||||||
return DataHelper.eq(_pubKey, li.getPublicKey()) && DataHelper.eq(_privKey, li.getPrivateKey())
|
|
||||||
&& DataHelper.eq(_signingPubKey, li.getSigningPublicKey())
|
|
||||||
&& DataHelper.eq(_signingPrivKey, li.getSigningPrivateKey());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,6 @@ class RequestVariableLeaseSetMessageHandler extends RequestLeaseSetMessageHandle
|
|||||||
}
|
}
|
||||||
leaseSet.addLease(lease);
|
leaseSet.addLease(lease);
|
||||||
}
|
}
|
||||||
signLeaseSet(leaseSet, session);
|
signLeaseSet(leaseSet, isLS2, session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import java.util.List;
|
|||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import net.i2p.CoreVersion;
|
import net.i2p.CoreVersion;
|
||||||
|
import net.i2p.crypto.EncType;
|
||||||
import net.i2p.crypto.SigType;
|
import net.i2p.crypto.SigType;
|
||||||
import net.i2p.data.DatabaseEntry;
|
import net.i2p.data.DatabaseEntry;
|
||||||
import net.i2p.data.DataHelper;
|
import net.i2p.data.DataHelper;
|
||||||
@ -268,6 +269,26 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
props.putAll(inProps);
|
props.putAll(inProps);
|
||||||
|
String senc = props.getProperty("i2cp.leaseSetEncType");
|
||||||
|
if (senc != null) {
|
||||||
|
String[] senca = DataHelper.split(senc, ",");
|
||||||
|
for (String sencaa : senca) {
|
||||||
|
EncType type = EncType.parseEncType(sencaa);
|
||||||
|
if (type != null) {
|
||||||
|
if (!type.isAvailable()) {
|
||||||
|
String msg = "Unsupported crypto type: " + type;
|
||||||
|
_log.error(msg);
|
||||||
|
_runner.disconnectClient(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String msg = "Unsupported crypto type: " + sencaa;
|
||||||
|
_log.error(msg);
|
||||||
|
_runner.disconnectClient(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if ("7".equals(props.getProperty("i2cp.leaseSetType"))) {
|
if ("7".equals(props.getProperty("i2cp.leaseSetType"))) {
|
||||||
// Prevent tunnel builds for Meta LS
|
// Prevent tunnel builds for Meta LS
|
||||||
// more TODO
|
// more TODO
|
||||||
|
Reference in New Issue
Block a user