forked from I2P_Developers/i2p.i2p
I2CP: Fix issues with persisted leaseset private keys
- Don't generate revocation key for LS2 - Fix generation of persistent revocation key for LS1 - Fix persistent private keys without persistent revocation key - Don't put unconfigured private keys in leaseset - Don't strip i2cp.leaseSetPrivateKey from config before it's used
This commit is contained in:
@ -841,18 +841,33 @@ public class TunnelConfig {
|
|||||||
_context.random().nextBytes(rk);
|
_context.random().nextBytes(rk);
|
||||||
config.setProperty(p, Base64.encode(rk));
|
config.setProperty(p, Base64.encode(rk));
|
||||||
}
|
}
|
||||||
|
|
||||||
// As of 0.9.18, add persistent leaseset keys if not present
|
// As of 0.9.18, add persistent leaseset keys if not present
|
||||||
// but only if we know the sigtype
|
// but only if we know the sigtype
|
||||||
p = OPT + "i2cp.leaseSetSigningPrivateKey";
|
String senc = config.getProperty(OPT + "i2cp.leaseSetEncType", "0");
|
||||||
if (_dest != null && !config.containsKey(p)) {
|
String slstyp = config.getProperty(OPT + "i2cp.leaseSetType", "0");
|
||||||
try {
|
if (senc.equals("0") && slstyp.equals("0")) {
|
||||||
SigType type = _dest.getSigType();
|
// only for LS1
|
||||||
SimpleDataStructure keys[] = KeyGenerator.getInstance().generateSigningKeys(type);
|
p = OPT + "i2cp.leaseSetSigningPrivateKey";
|
||||||
config.setProperty(p, type.name() + ':' + keys[1].toBase64());
|
if (!config.containsKey(p)) {
|
||||||
} catch (GeneralSecurityException gse) {
|
SigType type;
|
||||||
// so much for that
|
if (_dest != null) {
|
||||||
|
type = _dest.getSigType();
|
||||||
|
} else {
|
||||||
|
String ssigtyp = config.getProperty(OPT + "i2cp.destination.sigType", "0");
|
||||||
|
type = SigType.parseSigType(ssigtyp);
|
||||||
|
}
|
||||||
|
if (type != null) {
|
||||||
|
try {
|
||||||
|
SimpleDataStructure keys[] = KeyGenerator.getInstance().generateSigningKeys(type);
|
||||||
|
config.setProperty(p, type.name() + ':' + keys[1].toBase64());
|
||||||
|
} catch (GeneralSecurityException gse) {
|
||||||
|
// so much for that
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// persistent LS encryption keys
|
// persistent LS encryption keys
|
||||||
// multiple types as of 0.9.46, add missing ones
|
// multiple types as of 0.9.46, add missing ones
|
||||||
p = OPT + "i2cp.leaseSetPrivateKey";
|
p = OPT + "i2cp.leaseSetPrivateKey";
|
||||||
@ -860,7 +875,6 @@ public class TunnelConfig {
|
|||||||
// normalize it first to make the code below easier
|
// normalize it first to make the code below easier
|
||||||
if (skeys != null && skeys.length() > 0 && !skeys.contains(":"))
|
if (skeys != null && skeys.length() > 0 && !skeys.contains(":"))
|
||||||
config.setProperty(p, "ELGAMAL_2048:" + skeys);
|
config.setProperty(p, "ELGAMAL_2048:" + skeys);
|
||||||
String senc = config.getProperty(OPT + "i2cp.leaseSetEncType", "0");
|
|
||||||
String[] senca = DataHelper.split(senc, ",");
|
String[] senca = DataHelper.split(senc, ",");
|
||||||
// for each configured enc type, generate a key if we don't have it
|
// for each configured enc type, generate a key if we don't have it
|
||||||
for (int i = 0; i < senca.length; i++) {
|
for (int i = 0; i < senca.length; i++) {
|
||||||
|
@ -9,7 +9,9 @@ package net.i2p.client.impl;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -64,7 +66,7 @@ class I2CPMessageProducer {
|
|||||||
// Note that some are listed for both client and server side, don't include those below.
|
// Note that some are listed for both client and server side, don't include those below.
|
||||||
private static final String[] CLIENT_SIDE_OPTIONS = new String[] {
|
private static final String[] CLIENT_SIDE_OPTIONS = new String[] {
|
||||||
"i2cp.closeIdleTime", "i2cp.closeOnIdle", "i2cp.encryptLeaseSet",
|
"i2cp.closeIdleTime", "i2cp.closeOnIdle", "i2cp.encryptLeaseSet",
|
||||||
"i2cp.gzip", "i2cp.leaseSetKey", "i2cp.leaseSetPrivateKey",
|
I2PClient.PROP_GZIP, "i2cp.leaseSetKey", "i2cp.leaseSetPrivateKey",
|
||||||
"i2cp.leaseSetSigningPrivateKey", "i2cp.reduceIdleTime", "i2cp.reduceOnIdle",
|
"i2cp.leaseSetSigningPrivateKey", "i2cp.reduceIdleTime", "i2cp.reduceOnIdle",
|
||||||
I2PClient.PROP_ENABLE_SSL, I2PClient.PROP_TCP_HOST, I2PClient.PROP_TCP_PORT,
|
I2PClient.PROP_ENABLE_SSL, I2PClient.PROP_TCP_HOST, I2PClient.PROP_TCP_PORT,
|
||||||
// long and shouldn't be passed through
|
// long and shouldn't be passed through
|
||||||
@ -105,12 +107,28 @@ class I2CPMessageProducer {
|
|||||||
* @return a new copy, may be modified
|
* @return a new copy, may be modified
|
||||||
* @since 0.9.38
|
* @since 0.9.38
|
||||||
*/
|
*/
|
||||||
private static Properties getRouterOptions(I2PSessionImpl session) {
|
private Properties getRouterOptions(I2PSessionImpl session) {
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
props.putAll(session.getOptions());
|
props.putAll(session.getOptions());
|
||||||
for (int i = 0; i < CLIENT_SIDE_OPTIONS.length; i++) {
|
for (int i = 0; i < CLIENT_SIDE_OPTIONS.length; i++) {
|
||||||
props.remove(CLIENT_SIDE_OPTIONS[i]);
|
props.remove(CLIENT_SIDE_OPTIONS[i]);
|
||||||
}
|
}
|
||||||
|
for (Iterator<Map.Entry<Object, Object>> iter = props.entrySet().iterator(); iter.hasNext(); ) {
|
||||||
|
// Long strings MUST be removed, even in router context,
|
||||||
|
// as the session config properties must be serialized to be signed.
|
||||||
|
// fixme, bytes could still be over 255 (unlikely)
|
||||||
|
Map.Entry<Object, Object> e = iter.next();
|
||||||
|
String key = (String) e.getKey();
|
||||||
|
String val = (String) e.getValue();
|
||||||
|
if (key.length() > 255 || val.length() > 255) {
|
||||||
|
if (_log.shouldLog(Log.WARN))
|
||||||
|
_log.warn("Not passing on property ["
|
||||||
|
+ key
|
||||||
|
+ "] in the session config, key or value is too long (max = 255): "
|
||||||
|
+ val);
|
||||||
|
iter.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,18 +516,7 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String val = options.getProperty(key);
|
String val = options.getProperty(key);
|
||||||
// Long strings MUST be removed, even in router context,
|
rv.setProperty(key, val);
|
||||||
// as the session config properties must be serialized to be signed.
|
|
||||||
// fixme, bytes could still be over 255 (unlikely)
|
|
||||||
if (key.length() > 255 || val.length() > 255) {
|
|
||||||
if (_log.shouldLog(Log.WARN))
|
|
||||||
_log.warn("Not passing on property ["
|
|
||||||
+ key
|
|
||||||
+ "] in the session config, key or value is too long (max = 255): "
|
|
||||||
+ val);
|
|
||||||
} else {
|
|
||||||
rv.setProperty(key, val);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -186,35 +186,69 @@ 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) {
|
||||||
|
List<EncType> types = new ArrayList<EncType>(2);
|
||||||
|
String senc = session.getOptions().getProperty(PROP_LS_ENCTYPE);
|
||||||
|
if (senc != null) {
|
||||||
|
if (!PREFER_NEW_ENC && senc.equals("4,0"))
|
||||||
|
senc = "0,4";
|
||||||
|
else if (PREFER_NEW_ENC && senc.equals("0,4"))
|
||||||
|
senc = "4,0";
|
||||||
|
String[] senca = DataHelper.split(senc, ",");
|
||||||
|
for (String sencaa : senca) {
|
||||||
|
EncType newtype = EncType.parseEncType(sencaa);
|
||||||
|
if (newtype != null) {
|
||||||
|
if (types.contains(newtype)) {
|
||||||
|
_log.error("Duplicate crypto type: " + newtype);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (newtype.isAvailable()) {
|
||||||
|
types.add(newtype);
|
||||||
|
} else {
|
||||||
|
_log.error("Unsupported crypto type: " + newtype);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_log.error("Unsupported crypto type: " + sencaa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (types.isEmpty()) {
|
||||||
|
//if (_log.shouldDebug())
|
||||||
|
// _log.debug("Using default crypto type");
|
||||||
|
types.add(EncType.ELGAMAL_2048);
|
||||||
|
}
|
||||||
|
|
||||||
// [enctype:]b64,... of private keys
|
// [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);
|
// only for LS1
|
||||||
|
String sspk = isLS2 ? null : session.getOptions().getProperty(PROP_LS_SPK);
|
||||||
List<PrivateKey> privKeys = new ArrayList<PrivateKey>(2);
|
List<PrivateKey> privKeys = new ArrayList<PrivateKey>(2);
|
||||||
SigningPrivateKey signingPrivKey = null;
|
SigningPrivateKey signingPrivKey = null;
|
||||||
if (spk != null && sspk != null) {
|
if (spk != null && (isLS2 || sspk != null)) {
|
||||||
boolean useOldKeys = true;
|
boolean useOldKeys = true;
|
||||||
int colon = sspk.indexOf(':');
|
if (!isLS2) {
|
||||||
SigType type = dest.getSigType();
|
int colon = sspk.indexOf(':');
|
||||||
if (colon > 0) {
|
SigType type = dest.getSigType();
|
||||||
String stype = sspk.substring(0, colon);
|
if (colon > 0) {
|
||||||
SigType t = SigType.parseSigType(stype);
|
String stype = sspk.substring(0, colon);
|
||||||
if (t == type)
|
SigType t = SigType.parseSigType(stype);
|
||||||
sspk = sspk.substring(colon + 1);
|
if (t == type)
|
||||||
else
|
sspk = sspk.substring(colon + 1);
|
||||||
useOldKeys = false;
|
else
|
||||||
}
|
useOldKeys = false;
|
||||||
if (useOldKeys) {
|
}
|
||||||
try {
|
if (useOldKeys) {
|
||||||
signingPrivKey = new SigningPrivateKey(type);
|
try {
|
||||||
signingPrivKey.fromBase64(sspk);
|
signingPrivKey = new SigningPrivateKey(type);
|
||||||
} catch (DataFormatException dfe) {
|
signingPrivKey.fromBase64(sspk);
|
||||||
useOldKeys = false;
|
} catch (DataFormatException dfe) {
|
||||||
signingPrivKey = null;
|
useOldKeys = false;
|
||||||
|
signingPrivKey = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (useOldKeys) {
|
if (useOldKeys) {
|
||||||
parsePrivateKeys(spk, privKeys);
|
parsePrivateKeys(spk, privKeys, types);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (privKeys.isEmpty() && !_existingLeaseSets.isEmpty()) {
|
if (privKeys.isEmpty() && !_existingLeaseSets.isEmpty()) {
|
||||||
@ -223,8 +257,8 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
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())) {
|
||||||
privKeys.addAll(e.getValue().getPrivateKeys());
|
privKeys.addAll(e.getValue().getPrivateKeys());
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldInfo())
|
||||||
_log.debug("Creating new leaseInfo keys for " + dest + " with private key from " + e.getKey());
|
_log.info("Creating leaseInfo for " + dest.toBase32() + " with private key from " + e.getKey().toBase32());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -232,53 +266,27 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
if (!privKeys.isEmpty()) {
|
if (!privKeys.isEmpty()) {
|
||||||
if (signingPrivKey != null) {
|
if (signingPrivKey != null) {
|
||||||
li = new LeaseInfo(privKeys, signingPrivKey);
|
li = new LeaseInfo(privKeys, signingPrivKey);
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldInfo())
|
||||||
_log.debug("Creating new leaseInfo keys for " + dest + " WITH configured private keys");
|
_log.info("Creating leaseInfo for " + dest.toBase32() + " LS1 WITH configured private keys");
|
||||||
|
} else if (isLS2) {
|
||||||
|
li = new LeaseInfo(privKeys);
|
||||||
|
if (_log.shouldInfo())
|
||||||
|
_log.info("Creating leaseInfo for " + dest.toBase32() + " LS2 WITH configured private keys");
|
||||||
} else {
|
} else {
|
||||||
li = new LeaseInfo(privKeys, dest);
|
li = new LeaseInfo(privKeys, dest);
|
||||||
|
if (_log.shouldInfo())
|
||||||
|
_log.info("Creating leaseInfo for " + dest.toBase32() + " LS1 WITH configured private keys and new revocation key");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
List<EncType> types = new ArrayList<EncType>(2);
|
li = new LeaseInfo(dest, types, isLS2);
|
||||||
String senc = session.getOptions().getProperty(PROP_LS_ENCTYPE);
|
if (_log.shouldInfo())
|
||||||
if (senc != null) {
|
_log.info("Creating leaseInfo for " + dest.toBase32() + " without configured private keys");
|
||||||
if (!PREFER_NEW_ENC && senc.equals("4,0"))
|
|
||||||
senc = "0,4";
|
|
||||||
else if (PREFER_NEW_ENC && senc.equals("0,4"))
|
|
||||||
senc = "4,0";
|
|
||||||
String[] senca = DataHelper.split(senc, ",");
|
|
||||||
for (String sencaa : senca) {
|
|
||||||
EncType newtype = EncType.parseEncType(sencaa);
|
|
||||||
if (newtype != null) {
|
|
||||||
if (types.contains(newtype)) {
|
|
||||||
_log.error("Duplicate crypto type: " + newtype);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (newtype.isAvailable()) {
|
|
||||||
types.add(newtype);
|
|
||||||
if (_log.shouldDebug())
|
|
||||||
_log.debug("Using crypto type: " + newtype);
|
|
||||||
} else {
|
|
||||||
_log.error("Unsupported crypto type: " + newtype);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_log.error("Unsupported crypto type: " + sencaa);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (types.isEmpty()) {
|
|
||||||
if (_log.shouldDebug())
|
|
||||||
_log.debug("Using default crypto type");
|
|
||||||
types.add(EncType.ELGAMAL_2048);
|
|
||||||
}
|
|
||||||
li = new LeaseInfo(dest, types);
|
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
|
||||||
_log.debug("Creating new leaseInfo keys for " + dest + " without configured private keys");
|
|
||||||
}
|
}
|
||||||
_existingLeaseSets.put(dest, li);
|
_existingLeaseSets.put(dest, li);
|
||||||
} else {
|
} else {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Caching the old leaseInfo keys for "
|
_log.debug("Caching the old leaseInfo keys for "
|
||||||
+ dest);
|
+ dest.toBase32());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLS2) {
|
if (isLS2) {
|
||||||
@ -438,7 +446,7 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
* @param privKeys out parameter
|
* @param privKeys out parameter
|
||||||
* @since 0.9.39
|
* @since 0.9.39
|
||||||
*/
|
*/
|
||||||
private void parsePrivateKeys(String spkl, List<PrivateKey> privKeys) {
|
private void parsePrivateKeys(String spkl, List<PrivateKey> privKeys, List<EncType> allowedTypes) {
|
||||||
String[] spks = DataHelper.split(spkl, ",");
|
String[] spks = DataHelper.split(spkl, ",");
|
||||||
for (String spk : spks) {
|
for (String spk : spks) {
|
||||||
int colon = spk.indexOf(':');
|
int colon = spk.indexOf(':');
|
||||||
@ -446,14 +454,17 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
EncType type = EncType.parseEncType(spk.substring(0, colon));
|
EncType type = EncType.parseEncType(spk.substring(0, colon));
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
if (type.isAvailable()) {
|
if (type.isAvailable()) {
|
||||||
try {
|
if (allowedTypes.contains(type)) {
|
||||||
PrivateKey privKey = new PrivateKey(type);
|
try {
|
||||||
privKey.fromBase64(spk.substring(colon + 1));
|
PrivateKey privKey = new PrivateKey(type);
|
||||||
privKeys.add(privKey);
|
privKey.fromBase64(spk.substring(colon + 1));
|
||||||
|
privKeys.add(privKey);
|
||||||
|
} catch (DataFormatException dfe) {
|
||||||
|
_log.error("Bad private key: " + spk, dfe);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (_log.shouldDebug())
|
if (_log.shouldDebug())
|
||||||
_log.debug("Using crypto type: " + type);
|
_log.debug("Ignoring private key with unconfigured crypto type: " + type);
|
||||||
} catch (DataFormatException dfe) {
|
|
||||||
_log.error("Bad private key: " + spk, dfe);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_log.error("Unsupported crypto type: " + type);
|
_log.error("Unsupported crypto type: " + type);
|
||||||
@ -462,12 +473,18 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
_log.error("Unsupported crypto type: " + spk);
|
_log.error("Unsupported crypto type: " + spk);
|
||||||
}
|
}
|
||||||
} else if (colon < 0) {
|
} else if (colon < 0) {
|
||||||
try {
|
EncType type = EncType.ELGAMAL_2048;
|
||||||
PrivateKey privKey = new PrivateKey();
|
if (allowedTypes.contains(type)) {
|
||||||
privKey.fromBase64(spk);
|
try {
|
||||||
privKeys.add(privKey);
|
PrivateKey privKey = new PrivateKey();
|
||||||
} catch (DataFormatException dfe) {
|
privKey.fromBase64(spk);
|
||||||
_log.error("Bad private key: " + spk, dfe);
|
privKeys.add(privKey);
|
||||||
|
} catch (DataFormatException dfe) {
|
||||||
|
_log.error("Bad private key: " + spk, dfe);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (_log.shouldDebug())
|
||||||
|
_log.debug("Ignoring private key with unconfigured crypto type: " + type);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_log.error("Empty crypto type");
|
_log.error("Empty crypto type");
|
||||||
@ -488,7 +505,7 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
* New keys
|
* New keys
|
||||||
* @param types must be available
|
* @param types must be available
|
||||||
*/
|
*/
|
||||||
public LeaseInfo(Destination dest, List<EncType> types) {
|
public LeaseInfo(Destination dest, List<EncType> types, boolean isLS2) {
|
||||||
if (types.size() > 1 && PREFER_NEW_ENC) {
|
if (types.size() > 1 && PREFER_NEW_ENC) {
|
||||||
Collections.sort(types, Collections.reverseOrder());
|
Collections.sort(types, Collections.reverseOrder());
|
||||||
}
|
}
|
||||||
@ -499,19 +516,24 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
_pubKeys.add(encKeys.getPublic());
|
_pubKeys.add(encKeys.getPublic());
|
||||||
_privKeys.add(encKeys.getPrivate());
|
_privKeys.add(encKeys.getPrivate());
|
||||||
}
|
}
|
||||||
// must be same type as the Destination's signing key
|
if (isLS2) {
|
||||||
SimpleDataStructure signKeys[];
|
_signingPubKey = null;
|
||||||
try {
|
_signingPrivKey = null;
|
||||||
signKeys = KeyGenerator.getInstance().generateSigningKeys(dest.getSigningPublicKey().getType());
|
} else {
|
||||||
} catch (GeneralSecurityException gse) {
|
// must be same type as the Destination's signing key
|
||||||
throw new IllegalStateException(gse);
|
SimpleDataStructure signKeys[];
|
||||||
|
try {
|
||||||
|
signKeys = KeyGenerator.getInstance().generateSigningKeys(dest.getSigningPublicKey().getType());
|
||||||
|
} catch (GeneralSecurityException gse) {
|
||||||
|
throw new IllegalStateException(gse);
|
||||||
|
}
|
||||||
|
_signingPubKey = (SigningPublicKey) signKeys[0];
|
||||||
|
_signingPrivKey = (SigningPrivateKey) signKeys[1];
|
||||||
}
|
}
|
||||||
_signingPubKey = (SigningPublicKey) signKeys[0];
|
|
||||||
_signingPrivKey = (SigningPrivateKey) signKeys[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Existing keys
|
* Existing keys, LS1 only
|
||||||
* @param privKeys all EncTypes must be available
|
* @param privKeys all EncTypes must be available
|
||||||
* @since 0.9.18
|
* @since 0.9.18
|
||||||
*/
|
*/
|
||||||
@ -529,7 +551,7 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Existing crypto keys, new signing key
|
* Existing crypto keys, new signing key, LS1 only
|
||||||
* @param privKeys all EncTypes must be available
|
* @param privKeys all EncTypes must be available
|
||||||
* @since 0.9.21
|
* @since 0.9.21
|
||||||
*/
|
*/
|
||||||
@ -549,6 +571,24 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
_signingPrivKey = (SigningPrivateKey) signKeys[1];
|
_signingPrivKey = (SigningPrivateKey) signKeys[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Existing keys, LS2 only
|
||||||
|
* @param privKeys all EncTypes must be available
|
||||||
|
* @since 0.9.47
|
||||||
|
*/
|
||||||
|
public LeaseInfo(List<PrivateKey> privKeys) {
|
||||||
|
if (privKeys.size() > 1) {
|
||||||
|
Collections.sort(privKeys, new PrivKeyComparator());
|
||||||
|
}
|
||||||
|
_privKeys = privKeys;
|
||||||
|
_pubKeys = new ArrayList<PublicKey>(privKeys.size());
|
||||||
|
for (PrivateKey privKey : privKeys) {
|
||||||
|
_pubKeys.add(KeyGenerator.getPublicKey(privKey));
|
||||||
|
}
|
||||||
|
_signingPubKey = null;
|
||||||
|
_signingPrivKey = null;
|
||||||
|
}
|
||||||
|
|
||||||
/** @return the first one if more than one */
|
/** @return the first one if more than one */
|
||||||
public PublicKey getPublicKey() {
|
public PublicKey getPublicKey() {
|
||||||
return _pubKeys.get(0);
|
return _pubKeys.get(0);
|
||||||
@ -569,10 +609,12 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
|||||||
return _privKeys;
|
return _privKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return null for LS2 */
|
||||||
public SigningPublicKey getSigningPublicKey() {
|
public SigningPublicKey getSigningPublicKey() {
|
||||||
return _signingPubKey;
|
return _signingPubKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return null for LS2 */
|
||||||
public SigningPrivateKey getSigningPrivateKey() {
|
public SigningPrivateKey getSigningPrivateKey() {
|
||||||
return _signingPrivKey;
|
return _signingPrivKey;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user