forked from I2P_Developers/i2p.i2p
Router: Add KeyManager support for multiple leaseset private keys
This commit is contained in:
@ -15,6 +15,7 @@ import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@ -110,15 +111,29 @@ public class KeyManager {
|
||||
public synchronized SigningPublicKey getSigningPublicKey() { return _signingPublicKey; }
|
||||
|
||||
/**
|
||||
* client
|
||||
* Client with a single key
|
||||
*
|
||||
* @param leaseRevocationPrivateKey unused, may be null
|
||||
*/
|
||||
public void registerKeys(Destination dest, SigningPrivateKey leaseRevocationPrivateKey, PrivateKey endpointDecryptionKey) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Registering keys for destination " + dest.calculateHash().toBase64());
|
||||
if (_log.shouldInfo())
|
||||
_log.info("Registering keys for destination " + dest.toBase32());
|
||||
LeaseSetKeys keys = new LeaseSetKeys(dest, leaseRevocationPrivateKey, endpointDecryptionKey);
|
||||
_leaseSetKeys.put(dest.calculateHash(), keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Client with multiple keys
|
||||
*
|
||||
* @param leaseRevocationPrivateKey unused, may be null
|
||||
* @since 0.9.44
|
||||
*/
|
||||
public void registerKeys(Destination dest, SigningPrivateKey leaseRevocationPrivateKey, List<PrivateKey> endpointDecryptionKeys) {
|
||||
if (_log.shouldInfo())
|
||||
_log.info("Registering keys for destination " + dest.toBase32());
|
||||
LeaseSetKeys keys = new LeaseSetKeys(dest, leaseRevocationPrivateKey, endpointDecryptionKeys);
|
||||
_leaseSetKeys.put(dest.calculateHash(), keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read/Write the router keys from/to disk
|
||||
@ -129,7 +144,7 @@ public class KeyManager {
|
||||
|
||||
/** client */
|
||||
public LeaseSetKeys unregisterKeys(Destination dest) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
if (_log.shouldInfo())
|
||||
_log.info("Unregistering keys for destination " + dest.calculateHash().toBase64());
|
||||
return _leaseSetKeys.remove(dest.calculateHash());
|
||||
}
|
||||
|
@ -8,6 +8,12 @@ package net.i2p.router;
|
||||
*
|
||||
*/
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import net.i2p.crypto.EncType;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.PrivateKey;
|
||||
import net.i2p.data.SigningPrivateKey;
|
||||
@ -19,15 +25,66 @@ import net.i2p.data.SigningPrivateKey;
|
||||
public class LeaseSetKeys {
|
||||
private final SigningPrivateKey _revocationKey;
|
||||
private final PrivateKey _decryptionKey;
|
||||
private final PrivateKey _decryptionKeyEC;
|
||||
|
||||
/**
|
||||
* Unmodifiable, ElGamal only
|
||||
* @since 0.9.44
|
||||
*/
|
||||
public static final Set<EncType> SET_ELG = Collections.unmodifiableSet(EnumSet.of(EncType.ELGAMAL_2048));
|
||||
private static final Set<EncType> SET_EC = Collections.unmodifiableSet(EnumSet.of(EncType.ECIES_X25519));
|
||||
private static final Set<EncType> SET_BOTH = Collections.unmodifiableSet(EnumSet.of(EncType.ELGAMAL_2048, EncType.ECIES_X25519));
|
||||
private static final Set<EncType> SET_NONE = Collections.unmodifiableSet(EnumSet.noneOf(EncType.class));
|
||||
|
||||
/**
|
||||
* Client with a single key
|
||||
*
|
||||
* @param dest unused
|
||||
* @param revocationKey unused, may be null
|
||||
* @param decryptionKey non-null
|
||||
*/
|
||||
public LeaseSetKeys(Destination dest, SigningPrivateKey revocationKey, PrivateKey decryptionKey) {
|
||||
_revocationKey = revocationKey;
|
||||
_decryptionKey = decryptionKey;
|
||||
_revocationKey = revocationKey;
|
||||
EncType type = decryptionKey.getType();
|
||||
if (type == EncType.ELGAMAL_2048) {
|
||||
_decryptionKey = decryptionKey;
|
||||
_decryptionKeyEC = null;
|
||||
} else if (type == EncType.ECIES_X25519) {
|
||||
_decryptionKey = null;
|
||||
_decryptionKeyEC = decryptionKey;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown type " + type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Client with multiple keys
|
||||
*
|
||||
* @param dest unused
|
||||
* @param revocationKey unused, may be null
|
||||
* @param decryptionKeys non-null
|
||||
* @since 0.9.44
|
||||
*/
|
||||
public LeaseSetKeys(Destination dest, SigningPrivateKey revocationKey, List<PrivateKey> decryptionKeys) {
|
||||
_revocationKey = revocationKey;
|
||||
PrivateKey elg = null;
|
||||
PrivateKey ec = null;
|
||||
for (PrivateKey pk : decryptionKeys) {
|
||||
EncType type = pk.getType();
|
||||
if (type == EncType.ELGAMAL_2048) {
|
||||
if (elg != null)
|
||||
throw new IllegalArgumentException("Multiple keys same type");
|
||||
elg = pk;
|
||||
} else if (type == EncType.ECIES_X25519) {
|
||||
if (ec != null)
|
||||
throw new IllegalArgumentException("Multiple keys same type");
|
||||
ec = pk;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown type " + type);
|
||||
}
|
||||
}
|
||||
_decryptionKey = elg;
|
||||
_decryptionKeyEC = ec;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -43,7 +100,48 @@ public class LeaseSetKeys {
|
||||
* know on what router the destination is connected and as such can't encrypt
|
||||
* to that router's normal public key.
|
||||
*
|
||||
* @return ElGamal key or null if the LS does not support ElGamal
|
||||
*/
|
||||
public PrivateKey getDecryptionKey() { return _decryptionKey; }
|
||||
|
||||
/**
|
||||
* Decryption key which can open up garlic messages encrypted to the
|
||||
* LeaseSet's public key. This is used because the general public does not
|
||||
* know on what router the destination is connected and as such can't encrypt
|
||||
* to that router's normal public key.
|
||||
*
|
||||
* @return key of the specified type or null if the LS does not support that type
|
||||
* @since 0.9.44
|
||||
*/
|
||||
public PrivateKey getDecryptionKey(EncType type) {
|
||||
if (type == EncType.ELGAMAL_2048)
|
||||
return _decryptionKey;
|
||||
if (type == EncType.ECIES_X25519)
|
||||
return _decryptionKeyEC;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do we support this type of encryption?
|
||||
*
|
||||
* @since 0.9.44
|
||||
*/
|
||||
public boolean isSupported(EncType type) {
|
||||
if (type == EncType.ELGAMAL_2048)
|
||||
return _decryptionKey != null;
|
||||
if (type == EncType.ECIES_X25519)
|
||||
return _decryptionKeyEC != null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* What types of encryption are supported?
|
||||
*
|
||||
* @since 0.9.44
|
||||
*/
|
||||
public Set<EncType> getSupportedEncryption() {
|
||||
if (_decryptionKey != null)
|
||||
return (_decryptionKeyEC != null) ? SET_BOTH : SET_ELG;
|
||||
return (_decryptionKeyEC != null) ? SET_EC : SET_NONE;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user