I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit 8484a22f authored by zzz's avatar zzz
Browse files

Router: Add KeyManager support for multiple leaseset private keys

parent 0f7ebf2f
No related branches found
No related tags found
No related merge requests found
...@@ -15,6 +15,7 @@ import java.io.FileInputStream; ...@@ -15,6 +15,7 @@ import java.io.FileInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
...@@ -110,15 +111,29 @@ public class KeyManager { ...@@ -110,15 +111,29 @@ public class KeyManager {
public synchronized SigningPublicKey getSigningPublicKey() { return _signingPublicKey; } public synchronized SigningPublicKey getSigningPublicKey() { return _signingPublicKey; }
/** /**
* client * Client with a single key
*
* @param leaseRevocationPrivateKey unused, may be null * @param leaseRevocationPrivateKey unused, may be null
*/ */
public void registerKeys(Destination dest, SigningPrivateKey leaseRevocationPrivateKey, PrivateKey endpointDecryptionKey) { public void registerKeys(Destination dest, SigningPrivateKey leaseRevocationPrivateKey, PrivateKey endpointDecryptionKey) {
if (_log.shouldLog(Log.INFO)) if (_log.shouldInfo())
_log.info("Registering keys for destination " + dest.calculateHash().toBase64()); _log.info("Registering keys for destination " + dest.toBase32());
LeaseSetKeys keys = new LeaseSetKeys(dest, leaseRevocationPrivateKey, endpointDecryptionKey); LeaseSetKeys keys = new LeaseSetKeys(dest, leaseRevocationPrivateKey, endpointDecryptionKey);
_leaseSetKeys.put(dest.calculateHash(), keys); _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 * Read/Write the router keys from/to disk
...@@ -129,7 +144,7 @@ public class KeyManager { ...@@ -129,7 +144,7 @@ public class KeyManager {
/** client */ /** client */
public LeaseSetKeys unregisterKeys(Destination dest) { public LeaseSetKeys unregisterKeys(Destination dest) {
if (_log.shouldLog(Log.INFO)) if (_log.shouldInfo())
_log.info("Unregistering keys for destination " + dest.calculateHash().toBase64()); _log.info("Unregistering keys for destination " + dest.calculateHash().toBase64());
return _leaseSetKeys.remove(dest.calculateHash()); return _leaseSetKeys.remove(dest.calculateHash());
} }
......
...@@ -8,6 +8,12 @@ package net.i2p.router; ...@@ -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.Destination;
import net.i2p.data.PrivateKey; import net.i2p.data.PrivateKey;
import net.i2p.data.SigningPrivateKey; import net.i2p.data.SigningPrivateKey;
...@@ -19,15 +25,66 @@ import net.i2p.data.SigningPrivateKey; ...@@ -19,15 +25,66 @@ import net.i2p.data.SigningPrivateKey;
public class LeaseSetKeys { public class LeaseSetKeys {
private final SigningPrivateKey _revocationKey; private final SigningPrivateKey _revocationKey;
private final PrivateKey _decryptionKey; 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 dest unused
* @param revocationKey unused, may be null * @param revocationKey unused, may be null
* @param decryptionKey non-null * @param decryptionKey non-null
*/ */
public LeaseSetKeys(Destination dest, SigningPrivateKey revocationKey, PrivateKey decryptionKey) { public LeaseSetKeys(Destination dest, SigningPrivateKey revocationKey, PrivateKey decryptionKey) {
_revocationKey = revocationKey; _revocationKey = revocationKey;
_decryptionKey = decryptionKey; 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 { ...@@ -43,7 +100,48 @@ public class LeaseSetKeys {
* know on what router the destination is connected and as such can't encrypt * know on what router the destination is connected and as such can't encrypt
* to that router's normal public key. * to that router's normal public key.
* *
* @return ElGamal key or null if the LS does not support ElGamal
*/ */
public PrivateKey getDecryptionKey() { return _decryptionKey; } 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;
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment