Router: Prep for router encryption types (Proposal 156 WIP)

This commit is contained in:
zzz
2020-09-02 13:09:38 +00:00
parent d13a7d2872
commit bb761aea96
5 changed files with 47 additions and 8 deletions

View File

@ -7,6 +7,7 @@ import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import net.i2p.crypto.EncType;
import net.i2p.crypto.SigType;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
@ -36,7 +37,10 @@ public class RouterPrivateKeyFile extends PrivateKeyFile {
in = new BufferedInputStream(new FileInputStream(this.file));
RouterIdentity ri = new RouterIdentity();
ri.readBytes(in);
privKey = new PrivateKey();
EncType etype = ri.getPublicKey().getType();
if (etype == null)
throw new DataFormatException("Unknown enc type");
privKey = new PrivateKey(etype);
privKey.readBytes(in);
SigType type = ri.getSigningPublicKey().getType();
if (type == null)

View File

@ -2,6 +2,7 @@ package net.i2p.router.networkdb.kademlia;
import java.util.List;
import net.i2p.crypto.EncType;
import net.i2p.crypto.SigType;
import net.i2p.data.Hash;
import net.i2p.data.router.RouterAddress;
@ -139,6 +140,11 @@ class FloodfillMonitorJob extends JobImpl {
RouterInfo ri = getContext().router().getRouterInfo();
if (ri == null)
return false;
// temp until router ratchet SKM implemented
if (ri.getIdentity().getPublicKey().getType() != EncType.ELGAMAL_2048)
return false;
char bw = ri.getBandwidthTier().charAt(0);
// Only if class N, O, P, X
if (bw != Router.CAPABILITY_BW128 && bw != Router.CAPABILITY_BW256 &&

View File

@ -56,6 +56,8 @@ public class CreateRouterInfoJob extends JobImpl {
public static final String KEYS_FILENAME = "router.keys";
public static final String KEYS2_FILENAME = "router.keys.dat";
static final String PROP_ROUTER_SIGTYPE = "router.sigType";
/** @since 0.9.48 */
static final String PROP_ROUTER_ENCTYPE = "router.encType";
private static final SigType DEFAULT_SIGTYPE = SigType.EdDSA_SHA512_Ed25519;
private static final EncType DEFAULT_ENCTYPE = EncType.ELGAMAL_2048;
@ -106,8 +108,7 @@ public class CreateRouterInfoJob extends JobImpl {
// not necessary, in constructor
//info.setPeers(new HashSet());
info.setPublished(getCurrentPublishDate(ctx));
// TODO
EncType etype = DEFAULT_ENCTYPE;
EncType etype = getEncTypeConfig(ctx);
KeyPair keypair = ctx.keyGenerator().generatePKIKeys(etype);
PublicKey pubkey = keypair.getPublic();
PrivateKey privkey = keypair.getPrivate();
@ -196,6 +197,24 @@ public class CreateRouterInfoJob extends JobImpl {
return cstype;
}
/**
* The configured EncType to expect on read-in
* @since 0.9.48
*/
public static EncType getEncTypeConfig(RouterContext ctx) {
EncType cstype = DEFAULT_ENCTYPE;
String sstype = ctx.getProperty(PROP_ROUTER_ENCTYPE);
if (sstype != null) {
EncType ntype = EncType.parseEncType(sstype);
if (ntype != null)
cstype = ntype;
}
// fallback?
if (cstype != EncType.ELGAMAL_2048 && !cstype.isAvailable())
cstype = EncType.ELGAMAL_2048;
return cstype;
}
/**
* We probably don't want to expose the exact time at which a router published its info.
* perhaps round down to the nearest minute? 10 minutes? 30 minutes? day?

View File

@ -15,6 +15,7 @@ import java.io.InputStream;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
import net.i2p.crypto.EncType;
import net.i2p.crypto.KeyGenerator;
import net.i2p.crypto.SigType;
import net.i2p.data.Certificate;
@ -115,22 +116,27 @@ class LoadRouterInfoJob extends JobImpl {
PrivateKey privkey = kd.privateKey;
SigningPrivateKey signingPrivKey = kd.signingPrivateKey;
SigType stype = signingPubKey.getType();
EncType etype = pubkey.getType();
// check if the sigtype config changed
// check if the sigtype or enctype config changed
SigType cstype = CreateRouterInfoJob.getSigTypeConfig(getContext());
boolean sigTypeChanged = stype != cstype;
if (sigTypeChanged && getContext().getProperty(CreateRouterInfoJob.PROP_ROUTER_SIGTYPE) == null) {
EncType cetype = CreateRouterInfoJob.getEncTypeConfig(getContext());
boolean encTypeChanged = etype != cetype;
if ((sigTypeChanged && getContext().getProperty(CreateRouterInfoJob.PROP_ROUTER_SIGTYPE) == null) ||
(encTypeChanged && getContext().getProperty(CreateRouterInfoJob.PROP_ROUTER_ENCTYPE) == null)) {
// Not explicitly configured, and default has changed
// Give a 25% chance of rekeying for each restart
// TODO reduce to ~3 (i.e. increase probability) in future release
if (getContext().random().nextInt(4) > 0) {
if (getContext().random().nextInt(16) > 0) {
sigTypeChanged = false;
encTypeChanged = false;
if (_log.shouldWarn())
_log.warn("Deferring RI rekey from " + stype + " to " + cstype);
}
}
if (sigTypeChanged || shouldRebuild(privkey)) {
if (sigTypeChanged || encTypeChanged || shouldRebuild(privkey)) {
if (_us != null) {
Hash h = _us.getIdentity().getHash();
_log.logAlways(Log.WARN, "Deleting old router identity " + h.toBase64());
@ -143,6 +149,8 @@ class LoadRouterInfoJob extends JobImpl {
}
if (sigTypeChanged)
_log.logAlways(Log.WARN, "Rebuilding RouterInfo with new signature type " + cstype);
if (encTypeChanged)
_log.logAlways(Log.WARN, "Rebuilding RouterInfo with new encryption type " + cetype);
// windows... close before deleting
if (fis1 != null) {
try { fis1.close(); } catch (IOException ioe) {}