diff --git a/core/java/src/net/i2p/data/PrivateKeyFile.java b/core/java/src/net/i2p/data/PrivateKeyFile.java index e0bcb5043..42a26ef36 100644 --- a/core/java/src/net/i2p/data/PrivateKeyFile.java +++ b/core/java/src/net/i2p/data/PrivateKeyFile.java @@ -53,7 +53,7 @@ public class PrivateKeyFile { protected final File file; private final I2PClient client; - private Destination dest; + protected Destination dest; protected PrivateKey privKey; protected SigningPrivateKey signingPrivKey; @@ -455,6 +455,23 @@ public class PrivateKeyFile { } } + /** + * Verify that the PublicKey matches the PrivateKey, and + * the SigningPublicKey matches the SigningPrivateKey. + * + * @return success + * @since 0.9.16 + */ + public boolean validateKeyPairs() { + try { + if (!dest.getPublicKey().equals(KeyGenerator.getPublicKey(privKey))) + return false; + return dest.getSigningPublicKey().equals(KeyGenerator.getSigningPublicKey(signingPrivKey)); + } catch (IllegalArgumentException iae) { + return false; + } + } + @Override public String toString() { StringBuilder s = new StringBuilder(128); diff --git a/router/java/src/net/i2p/data/router/RouterPrivateKeyFile.java b/router/java/src/net/i2p/data/router/RouterPrivateKeyFile.java index db06d48dd..d2616d957 100644 --- a/router/java/src/net/i2p/data/router/RouterPrivateKeyFile.java +++ b/router/java/src/net/i2p/data/router/RouterPrivateKeyFile.java @@ -9,6 +9,7 @@ import java.io.IOException; import net.i2p.crypto.SigType; import net.i2p.data.DataFormatException; +import net.i2p.data.Destination; import net.i2p.data.PrivateKey; import net.i2p.data.PrivateKeyFile; import net.i2p.data.SigningPrivateKey; @@ -42,6 +43,14 @@ public class RouterPrivateKeyFile extends PrivateKeyFile { throw new DataFormatException("Unknown sig type"); signingPrivKey = new SigningPrivateKey(type); signingPrivKey.readBytes(in); + + // set it a Destination, so we may call validateKeyPairs() + // or other methods + dest = new Destination(); + dest.setPublicKey(ri.getPublicKey()); + dest.setSigningPublicKey(ri.getSigningPublicKey()); + dest.setCertificate(ri.getCertificate()); + return ri; } finally { if (in != null) { diff --git a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java index 51ca135ab..e02ef04aa 100644 --- a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java +++ b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java @@ -15,6 +15,7 @@ import java.io.InputStream; import java.io.IOException; import java.util.concurrent.atomic.AtomicBoolean; +import net.i2p.crypto.KeyGenerator; import net.i2p.crypto.SigType; import net.i2p.data.Certificate; import net.i2p.data.DataFormatException; @@ -210,6 +211,8 @@ class LoadRouterInfoJob extends JobImpl { if (rkf2.exists()) { RouterPrivateKeyFile pkf = new RouterPrivateKeyFile(rkf2); ri = pkf.getRouterIdentity(); + if (!pkf.validateKeyPairs()) + throw new DataFormatException("Key pairs invalid"); privkey = pkf.getPrivKey(); signingPrivKey = pkf.getSigningPrivKey(); } else { @@ -224,6 +227,17 @@ class LoadRouterInfoJob extends JobImpl { pubkey.readBytes(fis); SigningPublicKey signingPubKey = new SigningPublicKey(); signingPubKey.readBytes(fis); + + // validate + try { + if (!pubkey.equals(KeyGenerator.getPublicKey(privkey))) + throw new DataFormatException("Key pairs invalid"); + if (!signingPubKey.equals(KeyGenerator.getSigningPublicKey(signingPrivKey))) + throw new DataFormatException("Key pairs invalid"); + } catch (IllegalArgumentException iae) { + throw new DataFormatException("Key pairs invalid", iae); + } + ri = new RouterIdentity(); ri.setPublicKey(pubkey); ri.setSigningPublicKey(signingPubKey);