+Classes formerly in net.i2p.data but moved here as they are only used by the router. +
+ + diff --git a/router/java/src/net/i2p/router/Blocklist.java b/router/java/src/net/i2p/router/Blocklist.java index 093a6fdc5a..a6fe1d2093 100644 --- a/router/java/src/net/i2p/router/Blocklist.java +++ b/router/java/src/net/i2p/router/Blocklist.java @@ -28,8 +28,8 @@ import java.util.TreeSet; import net.i2p.data.Base64; import net.i2p.data.DataHelper; import net.i2p.data.Hash; -import net.i2p.data.RouterAddress; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterAddress; +import net.i2p.data.router.RouterInfo; import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade; import net.i2p.util.Addresses; import net.i2p.util.ConcurrentHashSet; diff --git a/router/java/src/net/i2p/router/CommSystemFacade.java b/router/java/src/net/i2p/router/CommSystemFacade.java index 9c7d92338d..59a22eb9ca 100644 --- a/router/java/src/net/i2p/router/CommSystemFacade.java +++ b/router/java/src/net/i2p/router/CommSystemFacade.java @@ -13,7 +13,7 @@ import java.io.Writer; import java.util.Collections; import java.util.List; import net.i2p.data.Hash; -import net.i2p.data.RouterAddress; +import net.i2p.data.router.RouterAddress; /** * Manages the communication subsystem between peers, including connections, diff --git a/router/java/src/net/i2p/router/HandlerJobBuilder.java b/router/java/src/net/i2p/router/HandlerJobBuilder.java index c1c9832cdc..62e2074a5f 100644 --- a/router/java/src/net/i2p/router/HandlerJobBuilder.java +++ b/router/java/src/net/i2p/router/HandlerJobBuilder.java @@ -9,7 +9,7 @@ package net.i2p.router; */ import net.i2p.data.Hash; -import net.i2p.data.RouterIdentity; +import net.i2p.data.router.RouterIdentity; import net.i2p.data.i2np.I2NPMessage; /** diff --git a/router/java/src/net/i2p/router/InNetMessagePool.java b/router/java/src/net/i2p/router/InNetMessagePool.java index 28296cebba..fb4c2a632c 100644 --- a/router/java/src/net/i2p/router/InNetMessagePool.java +++ b/router/java/src/net/i2p/router/InNetMessagePool.java @@ -14,7 +14,7 @@ import java.util.Date; import java.util.List; import net.i2p.data.Hash; -import net.i2p.data.RouterIdentity; +import net.i2p.data.router.RouterIdentity; import net.i2p.data.i2np.DatabaseLookupMessage; import net.i2p.data.i2np.DatabaseSearchReplyMessage; import net.i2p.data.i2np.DeliveryStatusMessage; diff --git a/router/java/src/net/i2p/router/KeyManager.java b/router/java/src/net/i2p/router/KeyManager.java index ce4992f8bd..2807e8fe7f 100644 --- a/router/java/src/net/i2p/router/KeyManager.java +++ b/router/java/src/net/i2p/router/KeyManager.java @@ -18,6 +18,7 @@ import java.io.OutputStream; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import net.i2p.crypto.SigType; import net.i2p.data.DataFormatException; import net.i2p.data.DataStructure; import net.i2p.data.Destination; @@ -26,6 +27,7 @@ import net.i2p.data.PrivateKey; import net.i2p.data.PublicKey; import net.i2p.data.SigningPrivateKey; import net.i2p.data.SigningPublicKey; +import net.i2p.router.startup.CreateRouterInfoJob; import net.i2p.util.Log; import net.i2p.util.SecureDirectory; import net.i2p.util.SecureFileOutputStream; @@ -47,10 +49,10 @@ public class KeyManager { public final static String PROP_KEYDIR = "router.keyBackupDir"; public final static String DEFAULT_KEYDIR = "keyBackup"; - private final static String KEYFILE_PRIVATE_ENC = "privateEncryption.key"; - private final static String KEYFILE_PUBLIC_ENC = "publicEncryption.key"; - private final static String KEYFILE_PRIVATE_SIGNING = "privateSigning.key"; - private final static String KEYFILE_PUBLIC_SIGNING = "publicSigning.key"; + public final static String KEYFILE_PRIVATE_ENC = "privateEncryption.key"; + public final static String KEYFILE_PUBLIC_ENC = "publicEncryption.key"; + public final static String KEYFILE_PRIVATE_SIGNING = "privateSigning.key"; + public final static String KEYFILE_PUBLIC_SIGNING = "publicSigning.key"; public KeyManager(RouterContext context) { _context = context; @@ -151,8 +153,9 @@ public class KeyManager { private void syncKeys(File keyDir) { syncPrivateKey(keyDir); syncPublicKey(keyDir); - syncSigningKey(keyDir); - syncVerificationKey(keyDir); + SigType type = CreateRouterInfoJob.getSigTypeConfig(getContext()); + syncSigningKey(keyDir, type); + syncVerificationKey(keyDir, type); } private void syncPrivateKey(File keyDir) { @@ -181,27 +184,33 @@ public class KeyManager { _publicKey = (PublicKey) readin; } - private void syncSigningKey(File keyDir) { + /** + * @param type the SigType to expect on read-in, ignored on write + */ + private void syncSigningKey(File keyDir, SigType type) { DataStructure ds; File keyFile = new File(keyDir, KEYFILE_PRIVATE_SIGNING); boolean exists = (_signingPrivateKey != null); if (exists) ds = _signingPrivateKey; else - ds = new SigningPrivateKey(); + ds = new SigningPrivateKey(type); DataStructure readin = syncKey(keyFile, ds, exists); if (readin != null && !exists) _signingPrivateKey = (SigningPrivateKey) readin; } - private void syncVerificationKey(File keyDir) { + /** + * @param type the SigType to expect on read-in, ignored on write + */ + private void syncVerificationKey(File keyDir, SigType type) { DataStructure ds; File keyFile = new File(keyDir, KEYFILE_PUBLIC_SIGNING); boolean exists = (_signingPublicKey != null); if (exists) ds = _signingPublicKey; else - ds = new SigningPublicKey(); + ds = new SigningPublicKey(type); DataStructure readin = syncKey(keyFile, ds, exists); if (readin != null && !exists) _signingPublicKey = (SigningPublicKey) readin; diff --git a/router/java/src/net/i2p/router/MultiRouter.java b/router/java/src/net/i2p/router/MultiRouter.java index 5e8cb47608..abcd32e3d0 100644 --- a/router/java/src/net/i2p/router/MultiRouter.java +++ b/router/java/src/net/i2p/router/MultiRouter.java @@ -10,7 +10,7 @@ import java.util.Scanner; import net.i2p.I2PAppContext; import net.i2p.data.DataHelper; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.router.Router; /** diff --git a/router/java/src/net/i2p/router/NetworkDatabaseFacade.java b/router/java/src/net/i2p/router/NetworkDatabaseFacade.java index 7fc3c50826..2e4ee3c150 100644 --- a/router/java/src/net/i2p/router/NetworkDatabaseFacade.java +++ b/router/java/src/net/i2p/router/NetworkDatabaseFacade.java @@ -16,7 +16,7 @@ import java.util.Set; import net.i2p.data.DatabaseEntry; import net.i2p.data.Hash; import net.i2p.data.LeaseSet; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.router.networkdb.reseed.ReseedChecker; /** diff --git a/router/java/src/net/i2p/router/OutNetMessage.java b/router/java/src/net/i2p/router/OutNetMessage.java index 633416640c..54434ac4b7 100644 --- a/router/java/src/net/i2p/router/OutNetMessage.java +++ b/router/java/src/net/i2p/router/OutNetMessage.java @@ -18,7 +18,7 @@ import java.util.List; import java.util.Map; import java.util.Set; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.I2NPMessage; import net.i2p.router.util.CDPQEntry; import net.i2p.util.Log; diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index f6eb8a907e..c199aca2b4 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -29,11 +29,12 @@ import net.i2p.data.Certificate; import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.Destination; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.SigningPrivateKey; import net.i2p.data.i2np.GarlicMessage; import net.i2p.router.message.GarlicMessageHandler; import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade; +import net.i2p.router.startup.CreateRouterInfoJob; import net.i2p.router.startup.StartupJob; import net.i2p.router.startup.WorkingDir; import net.i2p.router.tasks.*; @@ -98,10 +99,6 @@ public class Router implements RouterClock.ClockShiftListener { /** this does not put an 'H' in your routerInfo **/ public final static String PROP_HIDDEN_HIDDEN = "router.isHidden"; public final static String PROP_DYNAMIC_KEYS = "router.dynamicKeys"; - public final static String PROP_INFO_FILENAME = "router.info.location"; - public final static String PROP_INFO_FILENAME_DEFAULT = "router.info"; - public final static String PROP_KEYS_FILENAME = "router.keys.location"; - public final static String PROP_KEYS_FILENAME_DEFAULT = "router.keys"; public final static String PROP_SHUTDOWN_IN_PROGRESS = "__shutdownInProgress"; public final static String DNS_CACHE_TIME = "" + (5*60); private static final String EVENTLOG = "eventlog.txt"; @@ -671,20 +668,6 @@ public class Router implements RouterClock.ClockShiftListener { return Boolean.parseBoolean(h); return _context.commSystem().isInBadCountry(); } - - /** - * Only called at startup via LoadRouterInfoJob and RebuildRouterInfoJob. - * Not called by periodic RepublishLocalRouterInfoJob. - * We don't want to change the cert on the fly as it changes the router hash. - * RouterInfo.isHidden() checks the capability, but RouterIdentity.isHidden() checks the cert. - * There's no reason to ever add a hidden cert? - * @return the certificate for a new RouterInfo - probably a null cert. - */ - public Certificate createCertificate() { - if (_context.getBooleanProperty(PROP_HIDDEN)) - return new Certificate(Certificate.CERTIFICATE_TYPE_HIDDEN, null); - return Certificate.NULL_CERT; - } /** * @since 0.9.3 @@ -697,16 +680,18 @@ public class Router implements RouterClock.ClockShiftListener { * Ugly list of files that we need to kill if we are building a new identity * */ - private static final String _rebuildFiles[] = new String[] { "router.info", - "router.keys", - "netDb/my.info", // no longer used - "connectionTag.keys", // never used? - "keyBackup/privateEncryption.key", - "keyBackup/privateSigning.key", - "keyBackup/publicEncryption.key", - "keyBackup/publicSigning.key", - "sessionKeys.dat" // no longer used - }; + private static final String _rebuildFiles[] = new String[] { + CreateRouterInfoJob.INFO_FILENAME, + CreateRouterInfoJob.KEYS_FILENAME, + CreateRouterInfoJob.KEYS2_FILENAME, + "netDb/my.info", // no longer used + "connectionTag.keys", // never used? + KeyManager.DEFAULT_KEYDIR + '/' + KeyManager.KEYFILE_PRIVATE_ENC, + KeyManager.DEFAULT_KEYDIR + '/' + KeyManager.KEYFILE_PUBLIC_ENC, + KeyManager.DEFAULT_KEYDIR + '/' + KeyManager.KEYFILE_PRIVATE_SIGNING, + KeyManager.DEFAULT_KEYDIR + '/' + KeyManager.KEYFILE_PUBLIC_SIGNING, + "sessionKeys.dat" // no longer used + }; public void killKeys() { //new Exception("Clearing identity files").printStackTrace(); diff --git a/router/java/src/net/i2p/router/RouterContext.java b/router/java/src/net/i2p/router/RouterContext.java index 1f8a38af68..20b2fe9b7d 100644 --- a/router/java/src/net/i2p/router/RouterContext.java +++ b/router/java/src/net/i2p/router/RouterContext.java @@ -10,7 +10,7 @@ import java.util.concurrent.CopyOnWriteArrayList; import net.i2p.I2PAppContext; import net.i2p.app.ClientAppManager; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.internal.InternalClientManager; import net.i2p.router.client.ClientManagerFacadeImpl; import net.i2p.router.crypto.TransientSessionKeyManager; diff --git a/router/java/src/net/i2p/router/RouterThrottleImpl.java b/router/java/src/net/i2p/router/RouterThrottleImpl.java index 805e7bbbc3..275e4d85a4 100644 --- a/router/java/src/net/i2p/router/RouterThrottleImpl.java +++ b/router/java/src/net/i2p/router/RouterThrottleImpl.java @@ -1,7 +1,7 @@ package net.i2p.router; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.router.peermanager.TunnelHistory; import net.i2p.stat.Rate; import net.i2p.stat.RateAverages; diff --git a/router/java/src/net/i2p/router/dummy/DummyNetworkDatabaseFacade.java b/router/java/src/net/i2p/router/dummy/DummyNetworkDatabaseFacade.java index 11b9419f38..6c99bb90b3 100644 --- a/router/java/src/net/i2p/router/dummy/DummyNetworkDatabaseFacade.java +++ b/router/java/src/net/i2p/router/dummy/DummyNetworkDatabaseFacade.java @@ -17,7 +17,7 @@ import java.util.Set; import net.i2p.data.DatabaseEntry; import net.i2p.data.Hash; import net.i2p.data.LeaseSet; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.router.Job; import net.i2p.router.NetworkDatabaseFacade; import net.i2p.router.RouterContext; diff --git a/router/java/src/net/i2p/router/message/GarlicConfig.java b/router/java/src/net/i2p/router/message/GarlicConfig.java index 9fe299e0c3..4970a589f9 100644 --- a/router/java/src/net/i2p/router/message/GarlicConfig.java +++ b/router/java/src/net/i2p/router/message/GarlicConfig.java @@ -14,7 +14,7 @@ import java.util.List; import net.i2p.data.Certificate; import net.i2p.data.PublicKey; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.DeliveryInstructions; /** diff --git a/router/java/src/net/i2p/router/message/GarlicMessageHandler.java b/router/java/src/net/i2p/router/message/GarlicMessageHandler.java index c44ec2f055..3a762b6fd7 100644 --- a/router/java/src/net/i2p/router/message/GarlicMessageHandler.java +++ b/router/java/src/net/i2p/router/message/GarlicMessageHandler.java @@ -9,7 +9,7 @@ package net.i2p.router.message; */ import net.i2p.data.Hash; -import net.i2p.data.RouterIdentity; +import net.i2p.data.router.RouterIdentity; import net.i2p.data.i2np.GarlicMessage; import net.i2p.data.i2np.I2NPMessage; import net.i2p.router.HandlerJobBuilder; diff --git a/router/java/src/net/i2p/router/message/HandleGarlicMessageJob.java b/router/java/src/net/i2p/router/message/HandleGarlicMessageJob.java index 9392526b3f..9a22ec6e84 100644 --- a/router/java/src/net/i2p/router/message/HandleGarlicMessageJob.java +++ b/router/java/src/net/i2p/router/message/HandleGarlicMessageJob.java @@ -9,7 +9,7 @@ package net.i2p.router.message; */ import net.i2p.data.Hash; -import net.i2p.data.RouterIdentity; +import net.i2p.data.router.RouterIdentity; import net.i2p.data.i2np.DeliveryInstructions; import net.i2p.data.i2np.GarlicMessage; import net.i2p.data.i2np.I2NPMessage; diff --git a/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java b/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java index 5040606e8d..7da54172ce 100644 --- a/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java +++ b/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java @@ -18,7 +18,7 @@ import net.i2p.data.Lease; import net.i2p.data.LeaseSet; import net.i2p.data.Payload; import net.i2p.data.PublicKey; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.SessionKey; import net.i2p.data.SessionTag; import net.i2p.data.i2cp.MessageId; diff --git a/router/java/src/net/i2p/router/message/SendMessageDirectJob.java b/router/java/src/net/i2p/router/message/SendMessageDirectJob.java index 6d0cfdbcf2..cc7a337cc5 100644 --- a/router/java/src/net/i2p/router/message/SendMessageDirectJob.java +++ b/router/java/src/net/i2p/router/message/SendMessageDirectJob.java @@ -11,7 +11,7 @@ package net.i2p.router.message; import java.util.Date; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.I2NPMessage; import net.i2p.router.Job; import net.i2p.router.JobImpl; diff --git a/router/java/src/net/i2p/router/networkdb/HandleDatabaseLookupMessageJob.java b/router/java/src/net/i2p/router/networkdb/HandleDatabaseLookupMessageJob.java index 685e18512c..9931444aaf 100644 --- a/router/java/src/net/i2p/router/networkdb/HandleDatabaseLookupMessageJob.java +++ b/router/java/src/net/i2p/router/networkdb/HandleDatabaseLookupMessageJob.java @@ -14,8 +14,8 @@ import java.util.Set; import net.i2p.data.DatabaseEntry; import net.i2p.data.Hash; import net.i2p.data.LeaseSet; -import net.i2p.data.RouterIdentity; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterIdentity; +import net.i2p.data.router.RouterInfo; import net.i2p.data.SessionKey; import net.i2p.data.TunnelId; import net.i2p.data.i2np.DatabaseLookupMessage; diff --git a/router/java/src/net/i2p/router/networkdb/PublishLocalRouterInfoJob.java b/router/java/src/net/i2p/router/networkdb/PublishLocalRouterInfoJob.java index f6a29355b7..8b235260e3 100644 --- a/router/java/src/net/i2p/router/networkdb/PublishLocalRouterInfoJob.java +++ b/router/java/src/net/i2p/router/networkdb/PublishLocalRouterInfoJob.java @@ -12,7 +12,7 @@ import java.util.Date; import java.util.Properties; import net.i2p.data.DataFormatException; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.SigningPrivateKey; import net.i2p.router.JobImpl; import net.i2p.router.Router; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/ExpireRoutersJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/ExpireRoutersJob.java index c2ea790a5a..b52df8e179 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/ExpireRoutersJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/ExpireRoutersJob.java @@ -12,7 +12,7 @@ import java.util.Set; import net.i2p.data.DatabaseEntry; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.router.CommSystemFacade; import net.i2p.router.JobImpl; import net.i2p.router.RouterContext; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodOnlyLookupMatchJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodOnlyLookupMatchJob.java index 8f3a193a5a..0de6c6504f 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodOnlyLookupMatchJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodOnlyLookupMatchJob.java @@ -2,7 +2,7 @@ package net.i2p.router.networkdb.kademlia; import net.i2p.data.DatabaseEntry; import net.i2p.data.LeaseSet; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.DatabaseSearchReplyMessage; import net.i2p.data.i2np.DatabaseStoreMessage; import net.i2p.data.i2np.I2NPMessage; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseLookupMessageHandler.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseLookupMessageHandler.java index 8ef121d060..a07ac8c708 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseLookupMessageHandler.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseLookupMessageHandler.java @@ -9,7 +9,7 @@ package net.i2p.router.networkdb.kademlia; */ import net.i2p.data.Hash; -import net.i2p.data.RouterIdentity; +import net.i2p.data.router.RouterIdentity; import net.i2p.data.i2np.DatabaseLookupMessage; import net.i2p.data.i2np.I2NPMessage; import net.i2p.router.HandlerJobBuilder; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseStoreMessageHandler.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseStoreMessageHandler.java index e4c6ce71af..99d8c62658 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseStoreMessageHandler.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseStoreMessageHandler.java @@ -9,7 +9,7 @@ package net.i2p.router.networkdb.kademlia; */ import net.i2p.data.Hash; -import net.i2p.data.RouterIdentity; +import net.i2p.data.router.RouterIdentity; import net.i2p.data.i2np.DatabaseStoreMessage; import net.i2p.data.i2np.I2NPMessage; import net.i2p.router.HandlerJobBuilder; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillMonitorJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillMonitorJob.java index 99c4beda29..de634943cb 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillMonitorJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillMonitorJob.java @@ -3,8 +3,8 @@ package net.i2p.router.networkdb.kademlia; import java.util.List; import net.i2p.data.Hash; -import net.i2p.data.RouterAddress; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterAddress; +import net.i2p.data.router.RouterInfo; import net.i2p.router.JobImpl; import net.i2p.router.Router; import net.i2p.router.RouterContext; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java index 24a7bc40a1..22d51249a2 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java @@ -8,7 +8,7 @@ import java.util.Set; import net.i2p.data.DatabaseEntry; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.TunnelId; import net.i2p.data.i2np.DatabaseLookupMessage; import net.i2p.data.i2np.DatabaseStoreMessage; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillPeerSelector.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillPeerSelector.java index fdf47bf3cc..6870edcd58 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillPeerSelector.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillPeerSelector.java @@ -18,8 +18,8 @@ import java.util.Set; import java.util.TreeSet; import net.i2p.data.Hash; -import net.i2p.data.RouterAddress; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterAddress; +import net.i2p.data.router.RouterInfo; import net.i2p.kademlia.KBucketSet; import net.i2p.kademlia.SelectionCollector; import net.i2p.kademlia.XORComparator; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillVerifyStoreJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillVerifyStoreJob.java index f66b50020a..85d0bc974d 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillVerifyStoreJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillVerifyStoreJob.java @@ -8,7 +8,7 @@ import net.i2p.data.Certificate; import net.i2p.data.DatabaseEntry; import net.i2p.data.Hash; import net.i2p.data.LeaseSet; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.DatabaseLookupMessage; import net.i2p.data.i2np.DatabaseSearchReplyMessage; import net.i2p.data.i2np.DatabaseStoreMessage; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseLookupMessageJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseLookupMessageJob.java index 0d03d7d4fe..eceb4b576e 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseLookupMessageJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseLookupMessageJob.java @@ -11,8 +11,8 @@ package net.i2p.router.networkdb.kademlia; import java.util.Set; import net.i2p.data.Hash; -import net.i2p.data.RouterIdentity; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterIdentity; +import net.i2p.data.router.RouterInfo; import net.i2p.data.TunnelId; import net.i2p.data.i2np.DatabaseStoreMessage; import net.i2p.data.i2np.DatabaseLookupMessage; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseStoreMessageJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseStoreMessageJob.java index f623022ca7..57d1ee57bc 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseStoreMessageJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseStoreMessageJob.java @@ -14,9 +14,9 @@ import java.util.Date; import net.i2p.data.DatabaseEntry; import net.i2p.data.Hash; import net.i2p.data.LeaseSet; -import net.i2p.data.RouterAddress; -import net.i2p.data.RouterIdentity; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterAddress; +import net.i2p.data.router.RouterIdentity; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.DatabaseStoreMessage; import net.i2p.data.i2np.DeliveryStatusMessage; import net.i2p.router.JobImpl; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/HarvesterJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/HarvesterJob.java index a69a2bc906..6bd687185c 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/HarvesterJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/HarvesterJob.java @@ -7,7 +7,7 @@ import java.util.Set; import java.util.TreeMap; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.DatabaseLookupMessage; import net.i2p.router.JobImpl; import net.i2p.router.OutNetMessage; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/IterativeLookupJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/IterativeLookupJob.java index 13d7636887..ac283109ca 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/IterativeLookupJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/IterativeLookupJob.java @@ -1,7 +1,7 @@ package net.i2p.router.networkdb.kademlia; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.DatabaseSearchReplyMessage; import net.i2p.util.Log; import net.i2p.router.JobImpl; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/IterativeSearchJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/IterativeSearchJob.java index 7a2fa77709..023b6a8731 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/IterativeSearchJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/IterativeSearchJob.java @@ -13,7 +13,7 @@ import java.util.concurrent.ConcurrentHashMap; import net.i2p.data.Base64; import net.i2p.data.DataHelper; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.DatabaseLookupMessage; import net.i2p.data.i2np.I2NPMessage; import net.i2p.kademlia.KBucketSet; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java index b4d108d024..ba52e5d611 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java @@ -23,8 +23,8 @@ import net.i2p.data.DatabaseEntry; import net.i2p.data.DataHelper; import net.i2p.data.Hash; import net.i2p.data.LeaseSet; -import net.i2p.data.RouterAddress; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterAddress; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.DatabaseLookupMessage; import net.i2p.data.i2np.DatabaseStoreMessage; import net.i2p.kademlia.KBucketSet; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/MessageWrapper.java b/router/java/src/net/i2p/router/networkdb/kademlia/MessageWrapper.java index 15ae87a8bc..ff9d3d5011 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/MessageWrapper.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/MessageWrapper.java @@ -8,7 +8,7 @@ import net.i2p.crypto.TagSetHandle; import net.i2p.data.Certificate; import net.i2p.data.Hash; import net.i2p.data.PublicKey; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.SessionKey; import net.i2p.data.SessionTag; import net.i2p.data.i2np.DeliveryInstructions; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/PeerSelector.java b/router/java/src/net/i2p/router/networkdb/kademlia/PeerSelector.java index f73eb00fef..4eb23e13cb 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/PeerSelector.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/PeerSelector.java @@ -16,7 +16,7 @@ import java.util.Set; import java.util.TreeMap; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.kademlia.KBucketSet; import net.i2p.kademlia.SelectionCollector; import net.i2p.router.RouterContext; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java b/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java index 27435d5b56..2a7713cffd 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java @@ -29,7 +29,7 @@ import net.i2p.data.Base64; import net.i2p.data.DatabaseEntry; import net.i2p.data.DataFormatException; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.router.JobImpl; import net.i2p.router.Router; import net.i2p.router.RouterContext; @@ -524,6 +524,11 @@ class PersistentDataStore extends TransientDataStore { if (_log.shouldLog(Log.INFO)) _log.info("Unable to read the router reference in " + _routerFile.getName(), ioe); corrupt = true; + } catch (Exception e) { + // key certificate problems, etc., don't let one bad RI kill the whole thing + if (_log.shouldLog(Log.INFO)) + _log.info("Unable to read the router reference in " + _routerFile.getName(), e); + corrupt = true; } finally { if (fis != null) try { fis.close(); } catch (IOException ioe) {} } diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/RefreshRoutersJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/RefreshRoutersJob.java index 852a5c7920..20dd2a0754 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/RefreshRoutersJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/RefreshRoutersJob.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Set; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.router.JobImpl; import net.i2p.router.RouterContext; import net.i2p.util.Log; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/SearchJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/SearchJob.java index 54a9383196..9f2313f8eb 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/SearchJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/SearchJob.java @@ -17,7 +17,7 @@ import net.i2p.data.DatabaseEntry; import net.i2p.data.DataHelper; import net.i2p.data.Hash; import net.i2p.data.LeaseSet; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.TunnelId; import net.i2p.data.i2np.DatabaseLookupMessage; import net.i2p.data.i2np.DatabaseSearchReplyMessage; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/SearchMessageSelector.java b/router/java/src/net/i2p/router/networkdb/kademlia/SearchMessageSelector.java index 3d756529d8..30e8e4b18a 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/SearchMessageSelector.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/SearchMessageSelector.java @@ -3,7 +3,7 @@ package net.i2p.router.networkdb.kademlia; import java.util.concurrent.atomic.AtomicInteger; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.DatabaseSearchReplyMessage; import net.i2p.data.i2np.DatabaseStoreMessage; import net.i2p.data.i2np.I2NPMessage; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/SearchReplyJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/SearchReplyJob.java index 8d8e5f19d9..a8354b096f 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/SearchReplyJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/SearchReplyJob.java @@ -2,7 +2,7 @@ package net.i2p.router.networkdb.kademlia; import net.i2p.data.Hash; import net.i2p.data.i2np.DatabaseSearchReplyMessage; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.router.JobImpl; import net.i2p.router.RouterContext; import net.i2p.util.Log; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/SearchUpdateReplyFoundJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/SearchUpdateReplyFoundJob.java index 22602b497a..a67ae2fd83 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/SearchUpdateReplyFoundJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/SearchUpdateReplyFoundJob.java @@ -5,7 +5,7 @@ import java.util.Date; import net.i2p.data.DatabaseEntry; import net.i2p.data.Hash; import net.i2p.data.LeaseSet; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.DatabaseSearchReplyMessage; import net.i2p.data.i2np.DatabaseStoreMessage; import net.i2p.data.i2np.I2NPMessage; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/SingleLookupJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/SingleLookupJob.java index 711510fb4d..62a878d6de 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/SingleLookupJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/SingleLookupJob.java @@ -1,7 +1,7 @@ package net.i2p.router.networkdb.kademlia; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.DatabaseSearchReplyMessage; import net.i2p.router.JobImpl; import net.i2p.router.RouterContext; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/StartExplorersJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/StartExplorersJob.java index cced2f5466..7938ab072c 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/StartExplorersJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/StartExplorersJob.java @@ -12,7 +12,7 @@ import java.util.HashSet; import java.util.Set; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.router.JobImpl; import net.i2p.router.Router; import net.i2p.router.RouterContext; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java index 311f2ba8f1..81bef6950a 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java @@ -18,7 +18,7 @@ import net.i2p.data.DatabaseEntry; import net.i2p.data.DataFormatException; import net.i2p.data.Hash; import net.i2p.data.LeaseSet; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.TunnelId; import net.i2p.data.i2np.DatabaseStoreMessage; import net.i2p.data.i2np.I2NPMessage; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/StoreMessageSelector.java b/router/java/src/net/i2p/router/networkdb/kademlia/StoreMessageSelector.java index 6901f0afa6..352c19cd71 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/StoreMessageSelector.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/StoreMessageSelector.java @@ -1,7 +1,7 @@ package net.i2p.router.networkdb.kademlia; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.DeliveryStatusMessage; import net.i2p.data.i2np.I2NPMessage; import net.i2p.router.MessageSelector; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/TransientDataStore.java b/router/java/src/net/i2p/router/networkdb/kademlia/TransientDataStore.java index 2a7318d25f..11603efb98 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/TransientDataStore.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/TransientDataStore.java @@ -18,7 +18,7 @@ import java.util.Set; import net.i2p.data.DatabaseEntry; import net.i2p.data.Hash; import net.i2p.data.LeaseSet; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.router.RouterContext; import net.i2p.util.Log; diff --git a/router/java/src/net/i2p/router/peermanager/PeerManager.java b/router/java/src/net/i2p/router/peermanager/PeerManager.java index ef7b1de349..d2de16d9ba 100644 --- a/router/java/src/net/i2p/router/peermanager/PeerManager.java +++ b/router/java/src/net/i2p/router/peermanager/PeerManager.java @@ -19,7 +19,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.router.PeerSelectionCriteria; import net.i2p.router.Router; import net.i2p.router.RouterContext; diff --git a/router/java/src/net/i2p/router/peermanager/PeerTestJob.java b/router/java/src/net/i2p/router/peermanager/PeerTestJob.java index 24176a2088..466c63ec19 100644 --- a/router/java/src/net/i2p/router/peermanager/PeerTestJob.java +++ b/router/java/src/net/i2p/router/peermanager/PeerTestJob.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Set; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.TunnelId; import net.i2p.data.i2np.DatabaseStoreMessage; import net.i2p.data.i2np.DeliveryStatusMessage; diff --git a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java index a224f576ac..7e89cab255 100644 --- a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java +++ b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java @@ -19,8 +19,8 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import net.i2p.crypto.SHA256Generator; import net.i2p.data.Hash; -import net.i2p.data.RouterAddress; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterAddress; +import net.i2p.data.router.RouterInfo; import net.i2p.router.NetworkDatabaseFacade; import net.i2p.router.RouterContext; import net.i2p.router.tunnel.pool.TunnelPeerSelector; diff --git a/router/java/src/net/i2p/router/startup/BootCommSystemJob.java b/router/java/src/net/i2p/router/startup/BootCommSystemJob.java index 3af4164b5e..305869bada 100644 --- a/router/java/src/net/i2p/router/startup/BootCommSystemJob.java +++ b/router/java/src/net/i2p/router/startup/BootCommSystemJob.java @@ -16,7 +16,7 @@ import net.i2p.router.tasks.ReadConfigJob; import net.i2p.util.Log; /** This actually boots almost everything */ -public class BootCommSystemJob extends JobImpl { +class BootCommSystemJob extends JobImpl { private Log _log; public static final String PROP_USE_TRUSTED_LINKS = "router.trustedLinks"; diff --git a/router/java/src/net/i2p/router/startup/BootNetworkDbJob.java b/router/java/src/net/i2p/router/startup/BootNetworkDbJob.java index bf8d36a772..e512f9ea38 100644 --- a/router/java/src/net/i2p/router/startup/BootNetworkDbJob.java +++ b/router/java/src/net/i2p/router/startup/BootNetworkDbJob.java @@ -12,7 +12,7 @@ import net.i2p.router.JobImpl; import net.i2p.router.RouterContext; /** start up the network database */ -public class BootNetworkDbJob extends JobImpl { +class BootNetworkDbJob extends JobImpl { public BootNetworkDbJob(RouterContext ctx) { super(ctx); diff --git a/router/java/src/net/i2p/router/startup/BootPeerManagerJob.java b/router/java/src/net/i2p/router/startup/BootPeerManagerJob.java index 7ac5254f0e..33f4010236 100644 --- a/router/java/src/net/i2p/router/startup/BootPeerManagerJob.java +++ b/router/java/src/net/i2p/router/startup/BootPeerManagerJob.java @@ -12,7 +12,7 @@ import net.i2p.router.JobImpl; import net.i2p.router.RouterContext; /** start up the peer manager */ -public class BootPeerManagerJob extends JobImpl { +class BootPeerManagerJob extends JobImpl { public BootPeerManagerJob(RouterContext ctx) { super(ctx); diff --git a/router/java/src/net/i2p/router/startup/BuildTrustedLinksJob.java b/router/java/src/net/i2p/router/startup/BuildTrustedLinksJob.java index 3b88a2d9cd..566204068b 100644 --- a/router/java/src/net/i2p/router/startup/BuildTrustedLinksJob.java +++ b/router/java/src/net/i2p/router/startup/BuildTrustedLinksJob.java @@ -15,7 +15,7 @@ import net.i2p.router.RouterContext; /** * For future restricted routes. Does nothing now. */ -public class BuildTrustedLinksJob extends JobImpl { +class BuildTrustedLinksJob extends JobImpl { private final Job _next; public BuildTrustedLinksJob(RouterContext context, Job next) { diff --git a/router/java/src/net/i2p/router/startup/CreateRouterInfoJob.java b/router/java/src/net/i2p/router/startup/CreateRouterInfoJob.java index 498cbe6658..a343939f98 100644 --- a/router/java/src/net/i2p/router/startup/CreateRouterInfoJob.java +++ b/router/java/src/net/i2p/router/startup/CreateRouterInfoJob.java @@ -12,16 +12,22 @@ import java.io.BufferedOutputStream; import java.io.File; import java.io.IOException; import java.io.OutputStream; +import java.security.GeneralSecurityException; import java.util.Properties; +import net.i2p.crypto.SigType; import net.i2p.data.Certificate; import net.i2p.data.DataFormatException; +import net.i2p.data.DataHelper; +import net.i2p.data.KeyCertificate; import net.i2p.data.PrivateKey; +import net.i2p.data.PrivateKeyFile; import net.i2p.data.PublicKey; -import net.i2p.data.RouterIdentity; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterIdentity; +import net.i2p.data.router.RouterInfo; import net.i2p.data.SigningPrivateKey; import net.i2p.data.SigningPublicKey; +import net.i2p.data.SimpleDataStructure; import net.i2p.router.Job; import net.i2p.router.JobImpl; import net.i2p.router.Router; @@ -40,7 +46,14 @@ public class CreateRouterInfoJob extends JobImpl { private final Log _log; private final Job _next; - public CreateRouterInfoJob(RouterContext ctx, Job next) { + public static final String INFO_FILENAME = "router.info"; + public static final String KEYS_FILENAME = "router.keys"; + public static final String KEYS2_FILENAME = "router.keys.dat"; + private static final String PROP_ROUTER_SIGTYPE = "router.sigType"; + /** TODO when changing, check isAvailable() and fallback to DSA_SHA1 */ + private static final SigType DEFAULT_SIGTYPE = SigType.DSA_SHA1; + + CreateRouterInfoJob(RouterContext ctx, Job next) { super(ctx); _next = next; _log = ctx.logManager().getLog(CreateRouterInfoJob.class); @@ -59,9 +72,13 @@ public class CreateRouterInfoJob extends JobImpl { /** * Writes 6 files: router.info (standard RI format), - * router,keys, and 4 individual key files under keyBackup/ + * router.keys2, and 4 individual key files under keyBackup/ * - * router.keys file format: Note that this is NOT the + * router.keys2 file format: This is the + * same "eepPriv.dat" format used by the client code, + * as documented in PrivateKeyFile. + * + * Old router.keys file format: Note that this is NOT the * same "eepPriv.dat" format used by the client code. ** - Private key (256 bytes) @@ -74,9 +91,9 @@ public class CreateRouterInfoJob extends JobImpl { * Caller must hold Router.routerInfoFileLock. */ RouterInfo createRouterInfo() { + SigType type = getSigTypeConfig(getContext()); RouterInfo info = new RouterInfo(); OutputStream fos1 = null; - OutputStream fos2 = null; try { info.setAddresses(getContext().commSystem().createAddresses()); Properties stats = getContext().statPublisher().publishStatistics(); @@ -86,21 +103,26 @@ public class CreateRouterInfoJob extends JobImpl { // not necessary, in constructor //info.setPeers(new HashSet()); info.setPublished(getCurrentPublishDate(getContext())); - RouterIdentity ident = new RouterIdentity(); - Certificate cert = getContext().router().createCertificate(); - ident.setCertificate(cert); - PublicKey pubkey = null; - PrivateKey privkey = null; - SigningPublicKey signingPubKey = null; - SigningPrivateKey signingPrivKey = null; Object keypair[] = getContext().keyGenerator().generatePKIKeypair(); - pubkey = (PublicKey)keypair[0]; - privkey = (PrivateKey)keypair[1]; - Object signingKeypair[] = getContext().keyGenerator().generateSigningKeypair(); - signingPubKey = (SigningPublicKey)signingKeypair[0]; - signingPrivKey = (SigningPrivateKey)signingKeypair[1]; + PublicKey pubkey = (PublicKey)keypair[0]; + PrivateKey privkey = (PrivateKey)keypair[1]; + SimpleDataStructure signingKeypair[] = getContext().keyGenerator().generateSigningKeys(type); + SigningPublicKey signingPubKey = (SigningPublicKey)signingKeypair[0]; + SigningPrivateKey signingPrivKey = (SigningPrivateKey)signingKeypair[1]; + RouterIdentity ident = new RouterIdentity(); + Certificate cert = createCertificate(getContext(), signingPubKey); + ident.setCertificate(cert); ident.setPublicKey(pubkey); ident.setSigningPublicKey(signingPubKey); + byte[] padding; + int padLen = SigningPublicKey.KEYSIZE_BYTES - signingPubKey.length(); + if (padLen > 0) { + padding = new byte[padLen]; + getContext().random().nextBytes(padding); + ident.setPadding(padding); + } else { + padding = null; + } info.setIdentity(ident); info.sign(signingPrivKey); @@ -108,34 +130,51 @@ public class CreateRouterInfoJob extends JobImpl { if (!info.isValid()) throw new DataFormatException("RouterInfo we just built is invalid: " + info); - String infoFilename = getContext().getProperty(Router.PROP_INFO_FILENAME, Router.PROP_INFO_FILENAME_DEFAULT); - File ifile = new File(getContext().getRouterDir(), infoFilename); + // remove router.keys + (new File(getContext().getRouterDir(), KEYS_FILENAME)).delete(); + + // write router.info + File ifile = new File(getContext().getRouterDir(), INFO_FILENAME); fos1 = new BufferedOutputStream(new SecureFileOutputStream(ifile)); info.writeBytes(fos1); - String keyFilename = getContext().getProperty(Router.PROP_KEYS_FILENAME, Router.PROP_KEYS_FILENAME_DEFAULT); - File kfile = new File(getContext().getRouterDir(), keyFilename); - fos2 = new BufferedOutputStream(new SecureFileOutputStream(kfile)); - privkey.writeBytes(fos2); - signingPrivKey.writeBytes(fos2); - pubkey.writeBytes(fos2); - signingPubKey.writeBytes(fos2); + // write router.keys.dat + File kfile = new File(getContext().getRouterDir(), KEYS2_FILENAME); + PrivateKeyFile pkf = new PrivateKeyFile(kfile, pubkey, signingPubKey, cert, + privkey, signingPrivKey, padding); + pkf.write(); getContext().keyManager().setKeys(pubkey, privkey, signingPubKey, signingPrivKey); - _log.info("Router info created and stored at " + ifile.getAbsolutePath() + " with private keys stored at " + kfile.getAbsolutePath() + " [" + info + "]"); + if (_log.shouldLog(Log.INFO)) + _log.info("Router info created and stored at " + ifile.getAbsolutePath() + " with private keys stored at " + kfile.getAbsolutePath() + " [" + info + "]"); getContext().router().eventLog().addEvent(EventLog.REKEYED, ident.calculateHash().toBase64()); + } catch (GeneralSecurityException gse) { + _log.log(Log.CRIT, "Error building the new router information", gse); } catch (DataFormatException dfe) { _log.log(Log.CRIT, "Error building the new router information", dfe); } catch (IOException ioe) { _log.log(Log.CRIT, "Error writing out the new router information", ioe); } finally { if (fos1 != null) try { fos1.close(); } catch (IOException ioe) {} - if (fos2 != null) try { fos2.close(); } catch (IOException ioe) {} } return info; } + /** + * The configured SigType to expect on read-in + * @since 0.9.16 + */ + public static SigType getSigTypeConfig(RouterContext ctx) { + SigType cstype = CreateRouterInfoJob.DEFAULT_SIGTYPE; + String sstype = ctx.getProperty(PROP_ROUTER_SIGTYPE); + if (sstype != null) { + SigType ntype = SigType.parseSigType(sstype); + if (ntype != null && ntype.isAvailable()) + cstype = ntype; + } + return cstype; + } /** * We probably don't want to expose the exact time at which a router published its info. @@ -146,4 +185,22 @@ public class CreateRouterInfoJob extends JobImpl { //_log.info("Setting published date to /now/"); return context.clock().now(); } + + /** + * Only called at startup via LoadRouterInfoJob and RebuildRouterInfoJob. + * Not called by periodic RepublishLocalRouterInfoJob. + * We don't want to change the cert on the fly as it changes the router hash. + * RouterInfo.isHidden() checks the capability, but RouterIdentity.isHidden() checks the cert. + * There's no reason to ever add a hidden cert? + * + * @return the certificate for a new RouterInfo - probably a null cert. + * @since 0.9.16 moved from Router + */ + static Certificate createCertificate(RouterContext ctx, SigningPublicKey spk) { + if (spk.getType() != SigType.DSA_SHA1) + return new KeyCertificate(spk); + if (ctx.getBooleanProperty(Router.PROP_HIDDEN)) + return new Certificate(Certificate.CERTIFICATE_TYPE_HIDDEN, null); + return Certificate.NULL_CERT; + } } diff --git a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java index 9a560da5f4..51ca135ab7 100644 --- a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java +++ b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java @@ -15,18 +15,27 @@ import java.io.InputStream; import java.io.IOException; import java.util.concurrent.atomic.AtomicBoolean; +import net.i2p.crypto.SigType; +import net.i2p.data.Certificate; import net.i2p.data.DataFormatException; +import net.i2p.data.DataHelper; import net.i2p.data.PrivateKey; import net.i2p.data.PublicKey; -import net.i2p.data.RouterInfo; import net.i2p.data.SigningPrivateKey; import net.i2p.data.SigningPublicKey; +import net.i2p.data.router.RouterIdentity; +import net.i2p.data.router.RouterInfo; +import net.i2p.data.router.RouterPrivateKeyFile; import net.i2p.router.JobImpl; import net.i2p.router.Router; import net.i2p.router.RouterContext; import net.i2p.util.Log; -public class LoadRouterInfoJob extends JobImpl { +/** + * Run once or twice at startup by StartupJob, + * and then runs BootCommSystemJob + */ +class LoadRouterInfoJob extends JobImpl { private final Log _log; private RouterInfo _us; private static final AtomicBoolean _keyLengthChecked = new AtomicBoolean(); @@ -45,6 +54,7 @@ public class LoadRouterInfoJob extends JobImpl { if (_us == null) { RebuildRouterInfoJob r = new RebuildRouterInfoJob(getContext()); r.rebuildRouterInfo(false); + // run a second time getContext().jobQueue().addJob(this); return; } else { @@ -54,18 +64,21 @@ public class LoadRouterInfoJob extends JobImpl { } } + /** + * Loads router.info and router.keys2 or router.keys. + * + * See CreateRouterInfoJob for file formats + */ private void loadRouterInfo() { - String routerInfoFile = getContext().getProperty(Router.PROP_INFO_FILENAME, Router.PROP_INFO_FILENAME_DEFAULT); RouterInfo info = null; - String keyFilename = getContext().getProperty(Router.PROP_KEYS_FILENAME, Router.PROP_KEYS_FILENAME_DEFAULT); - - File rif = new File(getContext().getRouterDir(), routerInfoFile); + File rif = new File(getContext().getRouterDir(), CreateRouterInfoJob.INFO_FILENAME); boolean infoExists = rif.exists(); - File rkf = new File(getContext().getRouterDir(), keyFilename); + File rkf = new File(getContext().getRouterDir(), CreateRouterInfoJob.KEYS_FILENAME); boolean keysExist = rkf.exists(); + File rkf2 = new File(getContext().getRouterDir(), CreateRouterInfoJob.KEYS2_FILENAME); + boolean keys2Exist = rkf2.exists(); InputStream fis1 = null; - InputStream fis2 = null; try { // if we have a routerinfo but no keys, things go bad in a hurry: // CRIT ...rkdb.PublishLocalRouterInfoJob: Internal error - signing private key not known? rescheduling publish for 30s @@ -73,7 +86,7 @@ public class LoadRouterInfoJob extends JobImpl { // CRIT ...sport.udp.EstablishmentManager: Error in the establisher java.lang.NullPointerException // at net.i2p.router.transport.udp.PacketBuilder.buildSessionConfirmedPacket(PacketBuilder.java:574) // so pretend the RI isn't there if there is no keyfile - if (infoExists && keysExist) { + if (infoExists && (keys2Exist || keysExist)) { fis1 = new BufferedInputStream(new FileInputStream(rif)); info = new RouterInfo(); info.readBytes(fis1); @@ -85,29 +98,32 @@ public class LoadRouterInfoJob extends JobImpl { _us = info; } - if (keysExist) { - fis2 = new BufferedInputStream(new FileInputStream(rkf)); - PrivateKey privkey = new PrivateKey(); - privkey.readBytes(fis2); - if (shouldRebuild(privkey)) { + if (keys2Exist || keysExist) { + KeyData kd = readKeyData(rkf, rkf2); + PublicKey pubkey = kd.routerIdentity.getPublicKey(); + SigningPublicKey signingPubKey = kd.routerIdentity.getSigningPublicKey(); + PrivateKey privkey = kd.privateKey; + SigningPrivateKey signingPrivKey = kd.signingPrivateKey; + SigType stype = signingPubKey.getType(); + + // check if the sigtype config changed + SigType cstype = CreateRouterInfoJob.getSigTypeConfig(getContext()); + boolean sigTypeChanged = stype != cstype; + + if (sigTypeChanged || shouldRebuild(privkey)) { + if (sigTypeChanged) + _log.logAlways(Log.WARN, "Rebuilding RouterInfo with new signature type " + cstype); _us = null; // windows... close before deleting if (fis1 != null) { try { fis1.close(); } catch (IOException ioe) {} fis1 = null; } - try { fis2.close(); } catch (IOException ioe) {} - fis2 = null; rif.delete(); rkf.delete(); + rkf2.delete(); return; } - SigningPrivateKey signingPrivKey = new SigningPrivateKey(); - signingPrivKey.readBytes(fis2); - PublicKey pubkey = new PublicKey(); - pubkey.readBytes(fis2); - SigningPublicKey signingPubKey = new SigningPublicKey(); - signingPubKey.readBytes(fis2); getContext().keyManager().setKeys(pubkey, privkey, signingPubKey, signingPrivKey); } @@ -119,12 +135,9 @@ public class LoadRouterInfoJob extends JobImpl { try { fis1.close(); } catch (IOException ioe2) {} fis1 = null; } - if (fis2 != null) { - try { fis2.close(); } catch (IOException ioe2) {} - fis2 = null; - } rif.delete(); rkf.delete(); + rkf2.delete(); } catch (DataFormatException dfe) { _log.log(Log.CRIT, "Corrupt router info or keys at " + rif.getAbsolutePath() + " / " + rkf.getAbsolutePath(), dfe); _us = null; @@ -133,15 +146,11 @@ public class LoadRouterInfoJob extends JobImpl { try { fis1.close(); } catch (IOException ioe) {} fis1 = null; } - if (fis2 != null) { - try { fis2.close(); } catch (IOException ioe) {} - fis2 = null; - } rif.delete(); rkf.delete(); + rkf2.delete(); } finally { if (fis1 != null) try { fis1.close(); } catch (IOException ioe) {} - if (fis2 != null) try { fis2.close(); } catch (IOException ioe) {} } } @@ -174,4 +183,55 @@ public class LoadRouterInfoJob extends JobImpl { _log.logAlways(Log.WARN, "Rebuilding RouterInfo with faster key"); return uselong != haslong; } + + /** @since 0.9.16 */ + public static class KeyData { + public final RouterIdentity routerIdentity; + public final PrivateKey privateKey; + public final SigningPrivateKey signingPrivateKey; + + public KeyData(RouterIdentity ri, PrivateKey pk, SigningPrivateKey spk) { + routerIdentity = ri; + privateKey = pk; + signingPrivateKey = spk; + } + } + + /** + * @param rkf1 in router.keys format, tried second + * @param rkf2 in eepPriv.dat format, tried first + * @return non-null, throws IOE if neither exisits + * @since 0.9.16 + */ + public static KeyData readKeyData(File rkf1, File rkf2) throws DataFormatException, IOException { + RouterIdentity ri; + PrivateKey privkey; + SigningPrivateKey signingPrivKey; + if (rkf2.exists()) { + RouterPrivateKeyFile pkf = new RouterPrivateKeyFile(rkf2); + ri = pkf.getRouterIdentity(); + privkey = pkf.getPrivKey(); + signingPrivKey = pkf.getSigningPrivKey(); + } else { + InputStream fis = null; + try { + fis = new BufferedInputStream(new FileInputStream(rkf1)); + privkey = new PrivateKey(); + privkey.readBytes(fis); + signingPrivKey = new SigningPrivateKey(); + signingPrivKey.readBytes(fis); + PublicKey pubkey = new PublicKey(); + pubkey.readBytes(fis); + SigningPublicKey signingPubKey = new SigningPublicKey(); + signingPubKey.readBytes(fis); + ri = new RouterIdentity(); + ri.setPublicKey(pubkey); + ri.setSigningPublicKey(signingPubKey); + ri.setCertificate(Certificate.NULL_CERT); + } finally { + if (fis != null) try { fis.close(); } catch (IOException ioe) {} + } + } + return new KeyData(ri, privkey, signingPrivKey); + } } diff --git a/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java b/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java index b611114d06..ef0826cf5f 100644 --- a/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java +++ b/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java @@ -9,22 +9,24 @@ package net.i2p.router.startup; */ import java.io.File; -import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.Properties; +import net.i2p.crypto.SigType; import net.i2p.data.Certificate; import net.i2p.data.DataFormatException; +import net.i2p.data.DataHelper; import net.i2p.data.PrivateKey; import net.i2p.data.PublicKey; -import net.i2p.data.RouterIdentity; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterIdentity; +import net.i2p.data.router.RouterInfo; import net.i2p.data.SigningPrivateKey; import net.i2p.data.SigningPublicKey; import net.i2p.router.JobImpl; import net.i2p.router.Router; import net.i2p.router.RouterContext; +import net.i2p.router.startup.LoadRouterInfoJob.KeyData; import net.i2p.util.Log; import net.i2p.util.SecureFileOutputStream; @@ -44,7 +46,7 @@ import net.i2p.util.SecureFileOutputStream; * router.info.rebuild file is deleted * */ -public class RebuildRouterInfoJob extends JobImpl { +class RebuildRouterInfoJob extends JobImpl { private final Log _log; private final static long REBUILD_DELAY = 45*1000; // every 30 seconds @@ -57,11 +59,11 @@ public class RebuildRouterInfoJob extends JobImpl { public String getName() { return "Rebuild Router Info"; } public void runJob() { + throw new UnsupportedOperationException(); +/**** _log.debug("Testing to rebuild router info"); - String infoFile = getContext().getProperty(Router.PROP_INFO_FILENAME, Router.PROP_INFO_FILENAME_DEFAULT); - File info = new File(getContext().getRouterDir(), infoFile); - String keyFilename = getContext().getProperty(Router.PROP_KEYS_FILENAME, Router.PROP_KEYS_FILENAME_DEFAULT); - File keyFile = new File(getContext().getRouterDir(), keyFilename); + File info = new File(getContext().getRouterDir(), CreateRouterInfoJob.INFO_FILENAME); + File keyFile = new File(getContext().getRouterDir(), CreateRouterInfoJob.KEYS2_FILENAME); if (!info.exists() || !keyFile.exists()) { _log.info("Router info file [" + info.getAbsolutePath() + "] or private key file [" + keyFile.getAbsolutePath() + "] deleted, rebuilding"); @@ -71,51 +73,37 @@ public class RebuildRouterInfoJob extends JobImpl { } getTiming().setStartAfter(getContext().clock().now() + REBUILD_DELAY); getContext().jobQueue().addJob(this); +****/ } void rebuildRouterInfo() { rebuildRouterInfo(true); } + /** + * @param alreadyRunning unused + */ void rebuildRouterInfo(boolean alreadyRunning) { _log.debug("Rebuilding the new router info"); RouterInfo info = null; - String infoFilename = getContext().getProperty(Router.PROP_INFO_FILENAME, Router.PROP_INFO_FILENAME_DEFAULT); - File infoFile = new File(getContext().getRouterDir(), infoFilename); - String keyFilename = getContext().getProperty(Router.PROP_KEYS_FILENAME, Router.PROP_KEYS_FILENAME_DEFAULT); - File keyFile = new File(getContext().getRouterDir(), keyFilename); + File infoFile = new File(getContext().getRouterDir(), CreateRouterInfoJob.INFO_FILENAME); + File keyFile = new File(getContext().getRouterDir(), CreateRouterInfoJob.KEYS_FILENAME); + File keyFile2 = new File(getContext().getRouterDir(), CreateRouterInfoJob.KEYS2_FILENAME); - if (keyFile.exists()) { + if (keyFile2.exists() || keyFile.exists()) { // ok, no need to rebuild a brand new identity, just update what we can RouterInfo oldinfo = getContext().router().getRouterInfo(); if (oldinfo == null) { - info = new RouterInfo(); - FileInputStream fis = null; try { - fis = new FileInputStream(keyFile); - PrivateKey privkey = new PrivateKey(); - privkey.readBytes(fis); - SigningPrivateKey signingPrivKey = new SigningPrivateKey(); - signingPrivKey.readBytes(fis); - PublicKey pubkey = new PublicKey(); - pubkey.readBytes(fis); - SigningPublicKey signingPubKey = new SigningPublicKey(); - signingPubKey.readBytes(fis); - RouterIdentity ident = new RouterIdentity(); - Certificate cert = getContext().router().createCertificate(); - ident.setCertificate(cert); - ident.setPublicKey(pubkey); - ident.setSigningPublicKey(signingPubKey); - info.setIdentity(ident); + KeyData kd = LoadRouterInfoJob.readKeyData(keyFile, keyFile2); + info = new RouterInfo(); + info.setIdentity(kd.routerIdentity); } catch (Exception e) { _log.log(Log.CRIT, "Error reading in the key data from " + keyFile.getAbsolutePath(), e); - if (fis != null) try { fis.close(); } catch (IOException ioe) {} - fis = null; keyFile.delete(); + keyFile2.delete(); rebuildRouterInfo(alreadyRunning); return; - } finally { - if (fis != null) try { fis.close(); } catch (IOException ioe) {} } } else { // Make a new RI from the old identity, or else info.setAddresses() will throw an ISE @@ -160,12 +148,14 @@ public class RebuildRouterInfoJob extends JobImpl { _log.warn("Private key file " + keyFile.getAbsolutePath() + " deleted! Rebuilding a brand new router identity!"); // this proc writes the keys and info to the file as well as builds the latest and greatest info CreateRouterInfoJob j = new CreateRouterInfoJob(getContext(), null); - info = j.createRouterInfo(); + synchronized (getContext().router().routerInfoFileLock) { + info = j.createRouterInfo(); + } } //MessageHistory.initialize(); getContext().router().setRouterInfo(info); - _log.info("Router info rebuilt and stored at " + infoFilename + " [" + info + "]"); + _log.info("Router info rebuilt and stored at " + infoFile + " [" + info + "]"); } } diff --git a/router/java/src/net/i2p/router/startup/StartAcceptingClientsJob.java b/router/java/src/net/i2p/router/startup/StartAcceptingClientsJob.java index 50d840d432..672bf702aa 100644 --- a/router/java/src/net/i2p/router/startup/StartAcceptingClientsJob.java +++ b/router/java/src/net/i2p/router/startup/StartAcceptingClientsJob.java @@ -12,7 +12,7 @@ import net.i2p.router.JobImpl; import net.i2p.router.RouterContext; /** start I2CP interface */ -public class StartAcceptingClientsJob extends JobImpl { +class StartAcceptingClientsJob extends JobImpl { public StartAcceptingClientsJob(RouterContext context) { super(context); diff --git a/router/java/src/net/i2p/router/startup/WorkingDir.java b/router/java/src/net/i2p/router/startup/WorkingDir.java index 3763f2e7a7..15a3e7fb44 100644 --- a/router/java/src/net/i2p/router/startup/WorkingDir.java +++ b/router/java/src/net/i2p/router/startup/WorkingDir.java @@ -147,7 +147,7 @@ public class WorkingDir { // Check for a router.keys file or logs dir, if either exists it's an old install, // and only migrate the data files if told to do so // (router.keys could be deleted later by a killkeys()) - test = new File(oldDirf, "router.keys"); + test = new File(oldDirf, CreateRouterInfoJob.KEYS_FILENAME); boolean oldInstall = test.exists(); if (!oldInstall) { test = new File(oldDirf, "logs"); diff --git a/router/java/src/net/i2p/router/tasks/PersistRouterInfoJob.java b/router/java/src/net/i2p/router/tasks/PersistRouterInfoJob.java index c29dd25772..6a14a51346 100644 --- a/router/java/src/net/i2p/router/tasks/PersistRouterInfoJob.java +++ b/router/java/src/net/i2p/router/tasks/PersistRouterInfoJob.java @@ -13,10 +13,10 @@ import java.io.FileOutputStream; import java.io.IOException; import net.i2p.data.DataFormatException; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.router.JobImpl; -import net.i2p.router.Router; import net.i2p.router.RouterContext; +import net.i2p.router.startup.CreateRouterInfoJob; import net.i2p.util.Log; import net.i2p.util.SecureFileOutputStream; @@ -37,8 +37,7 @@ public class PersistRouterInfoJob extends JobImpl { if (_log.shouldLog(Log.DEBUG)) _log.debug("Persisting updated router info"); - String infoFilename = getContext().getProperty(Router.PROP_INFO_FILENAME, Router.PROP_INFO_FILENAME_DEFAULT); - File infoFile = new File(getContext().getRouterDir(), infoFilename); + File infoFile = new File(getContext().getRouterDir(), CreateRouterInfoJob.INFO_FILENAME); RouterInfo info = getContext().router().getRouterInfo(); diff --git a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java index bc3ad9543a..b9e38f9da3 100644 --- a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java +++ b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java @@ -17,8 +17,8 @@ import java.util.Locale; import java.util.Vector; import net.i2p.data.Hash; -import net.i2p.data.RouterAddress; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterAddress; +import net.i2p.data.router.RouterInfo; import net.i2p.router.CommSystemFacade; import net.i2p.router.OutNetMessage; import net.i2p.router.RouterContext; diff --git a/router/java/src/net/i2p/router/transport/Transport.java b/router/java/src/net/i2p/router/transport/Transport.java index e232fa7e46..459c846806 100644 --- a/router/java/src/net/i2p/router/transport/Transport.java +++ b/router/java/src/net/i2p/router/transport/Transport.java @@ -14,8 +14,8 @@ import java.util.List; import java.util.Vector; import net.i2p.data.Hash; -import net.i2p.data.RouterAddress; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterAddress; +import net.i2p.data.router.RouterInfo; import net.i2p.router.OutNetMessage; /** diff --git a/router/java/src/net/i2p/router/transport/TransportEventListener.java b/router/java/src/net/i2p/router/transport/TransportEventListener.java index 9a6d80d1ca..b8437efd1f 100644 --- a/router/java/src/net/i2p/router/transport/TransportEventListener.java +++ b/router/java/src/net/i2p/router/transport/TransportEventListener.java @@ -9,7 +9,7 @@ package net.i2p.router.transport; */ import net.i2p.data.Hash; -import net.i2p.data.RouterIdentity; +import net.i2p.data.router.RouterIdentity; import net.i2p.data.i2np.I2NPMessage; public interface TransportEventListener { diff --git a/router/java/src/net/i2p/router/transport/TransportImpl.java b/router/java/src/net/i2p/router/transport/TransportImpl.java index 194ae3016d..6dd93b4c59 100644 --- a/router/java/src/net/i2p/router/transport/TransportImpl.java +++ b/router/java/src/net/i2p/router/transport/TransportImpl.java @@ -30,9 +30,9 @@ import java.util.concurrent.CopyOnWriteArrayList; import net.i2p.data.DataHelper; import net.i2p.data.Hash; -import net.i2p.data.RouterAddress; -import net.i2p.data.RouterIdentity; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterAddress; +import net.i2p.data.router.RouterIdentity; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.I2NPMessage; import net.i2p.router.CommSystemFacade; import net.i2p.router.Job; diff --git a/router/java/src/net/i2p/router/transport/TransportManager.java b/router/java/src/net/i2p/router/transport/TransportManager.java index d9e0c37985..75e843707c 100644 --- a/router/java/src/net/i2p/router/transport/TransportManager.java +++ b/router/java/src/net/i2p/router/transport/TransportManager.java @@ -22,8 +22,8 @@ import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import net.i2p.data.Hash; -import net.i2p.data.RouterAddress; -import net.i2p.data.RouterIdentity; +import net.i2p.data.router.RouterAddress; +import net.i2p.data.router.RouterIdentity; import net.i2p.data.i2np.I2NPMessage; import net.i2p.router.CommSystemFacade; import net.i2p.router.OutNetMessage; @@ -59,6 +59,7 @@ public class TransportManager implements TransportEventListener { _context = context; _log = _context.logManager().getLog(TransportManager.class); _context.statManager().createRateStat("transport.banlistOnUnreachable", "Add a peer to the banlist since none of the transports can reach them", "Transport", new long[] { 60*1000, 10*60*1000, 60*60*1000 }); + _context.statManager().createRateStat("transport.banlistOnUsupportedSigType", "Add a peer to the banlist since signature type is unsupported", "Transport", new long[] { 60*1000, 10*60*1000, 60*60*1000 }); _context.statManager().createRateStat("transport.noBidsYetNotAllUnreachable", "Add a peer to the banlist since none of the transports can reach them", "Transport", new long[] { 60*1000, 10*60*1000, 60*60*1000 }); _context.statManager().createRateStat("transport.bidFailBanlisted", "Could not attempt to bid on message, as they were banlisted", "Transport", new long[] { 60*1000, 10*60*1000, 60*60*1000 }); _context.statManager().createRateStat("transport.bidFailSelf", "Could not attempt to bid on message, as it targeted ourselves", "Transport", new long[] { 60*1000, 10*60*1000, 60*60*1000 }); @@ -499,8 +500,11 @@ public class TransportManager implements TransportEventListener { } } if (unreachableTransports >= _transports.size()) { - // Don't banlist if we aren't talking to anybody, as we may have a network connection issue - if (unreachableTransports >= _transports.size() && countActivePeers() > 0) { + if (msg.getTarget().getIdentity().getSigningPublicKey().getType() == null) { + _context.statManager().addRateData("transport.banlistOnUnsupportedSigType", 1); + _context.banlist().banlistRouterForever(peer, _x("Unsupported signature type")); + } else if (unreachableTransports >= _transports.size() && countActivePeers() > 0) { + // Don't banlist if we aren't talking to anybody, as we may have a network connection issue _context.statManager().addRateData("transport.banlistOnUnreachable", msg.getLifetime(), msg.getLifetime()); _context.banlist().banlistRouter(peer, _x("Unreachable on any transport")); } diff --git a/router/java/src/net/i2p/router/transport/TransportUtil.java b/router/java/src/net/i2p/router/transport/TransportUtil.java index 1682abd91c..648119f91d 100644 --- a/router/java/src/net/i2p/router/transport/TransportUtil.java +++ b/router/java/src/net/i2p/router/transport/TransportUtil.java @@ -13,7 +13,7 @@ import java.net.UnknownHostException; import java.util.HashMap; import java.util.Map; -import net.i2p.data.RouterAddress; +import net.i2p.data.router.RouterAddress; import net.i2p.router.RouterContext; /** diff --git a/router/java/src/net/i2p/router/transport/ntcp/EstablishState.java b/router/java/src/net/i2p/router/transport/ntcp/EstablishState.java index bc6e37bc4d..b451d61544 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/EstablishState.java +++ b/router/java/src/net/i2p/router/transport/ntcp/EstablishState.java @@ -11,7 +11,7 @@ import net.i2p.data.Base64; import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.Hash; -import net.i2p.data.RouterIdentity; +import net.i2p.data.router.RouterIdentity; import net.i2p.data.Signature; import net.i2p.router.Router; import net.i2p.router.RouterContext; diff --git a/router/java/src/net/i2p/router/transport/ntcp/EventPumper.java b/router/java/src/net/i2p/router/transport/ntcp/EventPumper.java index d4fd7521ac..607234ae70 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/EventPumper.java +++ b/router/java/src/net/i2p/router/transport/ntcp/EventPumper.java @@ -20,8 +20,8 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.LinkedBlockingQueue; import net.i2p.I2PAppContext; -import net.i2p.data.RouterAddress; -import net.i2p.data.RouterIdentity; +import net.i2p.data.router.RouterAddress; +import net.i2p.data.router.RouterIdentity; import net.i2p.router.CommSystemFacade; import net.i2p.router.RouterContext; import net.i2p.router.transport.FIFOBandwidthLimiter; diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java index 2b2ae6a442..acd5570e38 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java @@ -17,9 +17,9 @@ import java.util.zip.Adler32; import net.i2p.data.Base64; import net.i2p.data.ByteArray; import net.i2p.data.DataHelper; -import net.i2p.data.RouterAddress; -import net.i2p.data.RouterIdentity; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterAddress; +import net.i2p.data.router.RouterIdentity; +import net.i2p.data.router.RouterInfo; import net.i2p.data.SessionKey; import net.i2p.data.i2np.DatabaseStoreMessage; import net.i2p.data.i2np.I2NPMessage; diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java index 0ad8d88a94..c7e4703a4d 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java @@ -25,9 +25,9 @@ import java.util.concurrent.ConcurrentHashMap; import net.i2p.data.DataHelper; import net.i2p.data.Hash; -import net.i2p.data.RouterAddress; -import net.i2p.data.RouterIdentity; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterAddress; +import net.i2p.data.router.RouterIdentity; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.DatabaseStoreMessage; import net.i2p.data.i2np.I2NPMessage; import net.i2p.router.CommSystemFacade; @@ -362,6 +362,12 @@ public class NTCPTransport extends TransportImpl { return null; } + // Check for supported sig type + if (toAddress.getIdentity().getSigningPublicKey().getType() == null) { + markUnreachable(peer); + return null; + } + if (!allowConnection()) { if (_log.shouldLog(Log.WARN)) _log.warn("no bid when trying to send to " + peer + ", max connection limit reached"); diff --git a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java index 267c4fc2a5..92696ff9ce 100644 --- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java +++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java @@ -10,9 +10,9 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import net.i2p.data.Hash; -import net.i2p.data.RouterAddress; -import net.i2p.data.RouterIdentity; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterAddress; +import net.i2p.data.router.RouterIdentity; +import net.i2p.data.router.RouterInfo; import net.i2p.data.SessionKey; import net.i2p.data.i2np.DatabaseStoreMessage; import net.i2p.data.i2np.DeliveryStatusMessage; diff --git a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java index abdd59e15d..6d1f177554 100644 --- a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java +++ b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java @@ -5,11 +5,12 @@ import java.io.IOException; import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; +import net.i2p.crypto.SigType; import net.i2p.data.Base64; import net.i2p.data.ByteArray; import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; -import net.i2p.data.RouterIdentity; +import net.i2p.data.router.RouterIdentity; import net.i2p.data.SessionKey; import net.i2p.data.Signature; import net.i2p.router.OutNetMessage; @@ -47,6 +48,9 @@ class InboundEstablishState { private long _receivedSignedOnTime; private byte _receivedSignature[]; private boolean _verificationAttempted; + // sig not verified + private RouterIdentity _receivedUnconfirmedIdentity; + // identical to uncomfirmed, but sig now verified private RouterIdentity _receivedConfirmedIdentity; // general status private final long _establishBegin; @@ -295,9 +299,28 @@ class InboundEstablishState { if (cur == _receivedIdentity.length-1) { _receivedSignedOnTime = conf.readFinalFragmentSignedOnTime(); - if (_receivedSignature == null) - _receivedSignature = new byte[Signature.SIGNATURE_BYTES]; - conf.readFinalSignature(_receivedSignature, 0); + // TODO verify time to prevent replay attacks + buildIdentity(); + if (_receivedUnconfirmedIdentity != null) { + SigType type = _receivedUnconfirmedIdentity.getSigningPublicKey().getType(); + if (type != null) { + int sigLen = type.getSigLen(); + if (_receivedSignature == null) + _receivedSignature = new byte[sigLen]; + conf.readFinalSignature(_receivedSignature, 0, sigLen); + } else { + if (_log.shouldLog(Log.WARN)) + _log.warn("Unsupported sig type from: " + toString()); + // _x() in UDPTransport + _context.banlist().banlistRouterForever(_receivedUnconfirmedIdentity.calculateHash(), + "Unsupported signature type"); + fail(); + } + } else { + if (_log.shouldLog(Log.WARN)) + _log.warn("Bad ident from: " + toString()); + fail(); + } } if ( (_currentState == InboundState.IB_STATE_UNKNOWN) || @@ -318,9 +341,10 @@ class InboundEstablishState { */ private boolean confirmedFullyReceived() { if (_receivedIdentity != null) { - for (int i = 0; i < _receivedIdentity.length; i++) + for (int i = 0; i < _receivedIdentity.length; i++) { if (_receivedIdentity[i] == null) return false; + } return true; } else { return false; @@ -339,7 +363,51 @@ class InboundEstablishState { } return _receivedConfirmedIdentity; } - + + /** + * Construct Alice's RouterIdentity. + * Must have received all fragments. + * Sets _receivedUnconfirmedIdentity, unless invalid. + * + * Caller must synch on this. + * + * @since 0.9.16 was in verifyIdentity() + */ + private void buildIdentity() { + if (_receivedUnconfirmedIdentity != null) + return; // dup pkt? + int frags = _receivedIdentity.length; + byte[] ident; + if (frags > 1) { + int identSize = 0; + for (int i = 0; i < _receivedIdentity.length; i++) + identSize += _receivedIdentity[i].length; + ident = new byte[identSize]; + int off = 0; + for (int i = 0; i < _receivedIdentity.length; i++) { + int len = _receivedIdentity[i].length; + System.arraycopy(_receivedIdentity[i], 0, ident, off, len); + off += len; + } + } else { + // no need to copy + ident = _receivedIdentity[0]; + } + ByteArrayInputStream in = new ByteArrayInputStream(ident); + RouterIdentity peer = new RouterIdentity(); + try { + peer.readBytes(in); + _receivedUnconfirmedIdentity = peer; + } catch (DataFormatException dfe) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Improperly formatted yet fully received ident", dfe); + } catch (IOException ioe) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Improperly formatted yet fully received ident", ioe); + } + } + + /** * Determine if Alice sent us a valid confirmation packet. The * identity signs: Alice's IP + Alice's port + Bob's IP + Bob's port @@ -351,21 +419,11 @@ class InboundEstablishState { * Caller must synch on this. */ private void verifyIdentity() { - int identSize = 0; - for (int i = 0; i < _receivedIdentity.length; i++) - identSize += _receivedIdentity[i].length; - byte ident[] = new byte[identSize]; - int off = 0; - for (int i = 0; i < _receivedIdentity.length; i++) { - int len = _receivedIdentity[i].length; - System.arraycopy(_receivedIdentity[i], 0, ident, off, len); - off += len; - } - ByteArrayInputStream in = new ByteArrayInputStream(ident); - RouterIdentity peer = new RouterIdentity(); - try { - peer.readBytes(in); - + if (_receivedUnconfirmedIdentity == null) + return; // either not yet recvd or bad ident + if (_receivedSignature == null) + return; // either not yet recvd or bad sig + byte signed[] = new byte[256+256 // X + Y + _aliceIP.length + 2 + _bobIP.length + 2 @@ -373,7 +431,7 @@ class InboundEstablishState { + 4 // signed on time ]; - off = 0; + int off = 0; System.arraycopy(_receivedX, 0, signed, off, _receivedX.length); off += _receivedX.length; getSentY(); @@ -391,22 +449,15 @@ class InboundEstablishState { off += 4; DataHelper.toLong(signed, off, 4, _receivedSignedOnTime); Signature sig = new Signature(_receivedSignature); - boolean ok = _context.dsa().verifySignature(sig, signed, peer.getSigningPublicKey()); + boolean ok = _context.dsa().verifySignature(sig, signed, _receivedUnconfirmedIdentity.getSigningPublicKey()); if (ok) { // todo partial spoof detection - get peer.calculateHash(), // lookup in netdb locally, if not equal, fail? - _receivedConfirmedIdentity = peer; + _receivedConfirmedIdentity = _receivedUnconfirmedIdentity; } else { if (_log.shouldLog(Log.WARN)) - _log.warn("Signature failed from " + peer); + _log.warn("Signature failed from " + _receivedUnconfirmedIdentity); } - } catch (DataFormatException dfe) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Improperly formatted yet fully received ident", dfe); - } catch (IOException ioe) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Improperly formatted yet fully received ident", ioe); - } } private void packetReceived() { diff --git a/router/java/src/net/i2p/router/transport/udp/IntroductionManager.java b/router/java/src/net/i2p/router/transport/udp/IntroductionManager.java index 37db458801..7e55cf1ce3 100644 --- a/router/java/src/net/i2p/router/transport/udp/IntroductionManager.java +++ b/router/java/src/net/i2p/router/transport/udp/IntroductionManager.java @@ -11,8 +11,8 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import net.i2p.data.Base64; -import net.i2p.data.RouterAddress; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterAddress; +import net.i2p.data.router.RouterInfo; import net.i2p.data.SessionKey; import net.i2p.router.RouterContext; import net.i2p.util.Addresses; diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java index ba4375dbdb..ff94852559 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java @@ -3,10 +3,11 @@ package net.i2p.router.transport.udp; import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; +import net.i2p.crypto.SigType; import net.i2p.data.Base64; import net.i2p.data.ByteArray; import net.i2p.data.DataHelper; -import net.i2p.data.RouterIdentity; +import net.i2p.data.router.RouterIdentity; import net.i2p.data.SessionKey; import net.i2p.data.Signature; import net.i2p.data.i2np.DatabaseStoreMessage; @@ -41,6 +42,7 @@ class OutboundEstablishState { private SessionKey _sessionKey; private SessionKey _macKey; private Signature _receivedSignature; + // includes trailing padding to mod 16 private byte[] _receivedEncryptedSignature; private byte[] _receivedIV; // SessionConfirmed messages @@ -104,6 +106,7 @@ class OutboundEstablishState { /** * @param claimedAddress an IP/port based RemoteHostId, or null if unknown * @param remoteHostId non-null, == claimedAddress if direct, or a hash-based one if indirect + * @param remotePeer must have supported sig type * @param introKey Bob's introduction key, as published in the netdb * @param addr non-null */ @@ -247,8 +250,20 @@ class OutboundEstablishState { _alicePort = reader.readPort(); _receivedRelayTag = reader.readRelayTag(); _receivedSignedOnTime = reader.readSignedOnTime(); - _receivedEncryptedSignature = new byte[Signature.SIGNATURE_BYTES + 8]; - reader.readEncryptedSignature(_receivedEncryptedSignature, 0); + // handle variable signature size + SigType type = _remotePeer.getSigningPublicKey().getType(); + if (type == null) { + // shouldn't happen, we only connect to supported peers + fail(); + packetReceived(); + return; + } + int sigLen = type.getSigLen(); + int mod = sigLen % 16; + int pad = (mod == 0) ? 0 : (16 - mod); + int esigLen = sigLen + pad; + _receivedEncryptedSignature = new byte[esigLen]; + reader.readEncryptedSignature(_receivedEncryptedSignature, 0, esigLen); _receivedIV = new byte[UDPPacket.IV_SIZE]; reader.readIV(_receivedIV, 0); @@ -353,7 +368,9 @@ class OutboundEstablishState { * decrypt the signature (and subsequent pad bytes) with the * additional layer of encryption using the negotiated key along side * the packet's IV + * * Caller must synch on this. + * Only call this once! Decrypts in-place. */ private void decryptSignature() { if (_receivedEncryptedSignature == null) throw new NullPointerException("encrypted signature is null! this=" + this.toString()); @@ -361,11 +378,20 @@ class OutboundEstablishState { if (_receivedIV == null) throw new NullPointerException("IV is null!"); _context.aes().decrypt(_receivedEncryptedSignature, 0, _receivedEncryptedSignature, 0, _sessionKey, _receivedIV, _receivedEncryptedSignature.length); - byte signatureBytes[] = new byte[Signature.SIGNATURE_BYTES]; - System.arraycopy(_receivedEncryptedSignature, 0, signatureBytes, 0, Signature.SIGNATURE_BYTES); - _receivedSignature = new Signature(signatureBytes); + // handle variable signature size + SigType type = _remotePeer.getSigningPublicKey().getType(); + // if type == null throws NPE + int sigLen = type.getSigLen(); + int mod = sigLen % 16; + if (mod != 0) { + byte signatureBytes[] = new byte[sigLen]; + System.arraycopy(_receivedEncryptedSignature, 0, signatureBytes, 0, sigLen); + _receivedSignature = new Signature(type, signatureBytes); + } else { + _receivedSignature = new Signature(type, _receivedEncryptedSignature); + } if (_log.shouldLog(Log.DEBUG)) - _log.debug("Decrypted received signature: " + Base64.encode(signatureBytes)); + _log.debug("Decrypted received signature: " + Base64.encode(_receivedSignature.getData())); } /** diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java b/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java index 034f3e6054..2be5557744 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java @@ -6,7 +6,7 @@ import java.util.List; import java.util.Set; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.router.OutNetMessage; import net.i2p.router.RouterContext; import net.i2p.util.ConcurrentHashSet; diff --git a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java index 053703cb1c..d518a0b568 100644 --- a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java +++ b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java @@ -13,7 +13,7 @@ import net.i2p.I2PAppContext; import net.i2p.data.Base64; import net.i2p.data.DataHelper; import net.i2p.data.Hash; -import net.i2p.data.RouterIdentity; +import net.i2p.data.router.RouterIdentity; import net.i2p.data.SessionKey; import net.i2p.data.Signature; import net.i2p.util.Addresses; @@ -596,14 +596,22 @@ class PacketBuilder { off += 4; DataHelper.toLong(data, off, 4, state.getSentSignedOnTime()); off += 4; - System.arraycopy(state.getSentSignature().getData(), 0, data, off, Signature.SIGNATURE_BYTES); - off += Signature.SIGNATURE_BYTES; - // ok, we need another 8 bytes of random padding - // (ok, this only gives us 63 bits, not 64) - long l = _context.random().nextLong(); - if (l < 0) l = 0 - l; - DataHelper.toLong(data, off, 8, l); - off += 8; + + // handle variable signature size + Signature sig = state.getSentSignature(); + int siglen = sig.length(); + System.arraycopy(sig.getData(), 0, data, off, siglen); + off += siglen; + // ok, we need another few bytes of random padding + int rem = siglen % 16; + int padding; + if (rem > 0) { + padding = 16 - rem; + _context.random().nextBytes(data, off, padding); + off += padding; + } else { + padding = 0; + } if (_log.shouldLog(Log.DEBUG)) { StringBuilder buf = new StringBuilder(128); @@ -612,9 +620,9 @@ class PacketBuilder { buf.append(" Bob: ").append(Addresses.toString(state.getReceivedOurIP(), externalPort)); buf.append(" RelayTag: ").append(state.getSentRelayTag()); buf.append(" SignedOn: ").append(state.getSentSignedOnTime()); - buf.append(" signature: ").append(Base64.encode(state.getSentSignature().getData())); + buf.append(" signature: ").append(Base64.encode(sig.getData())); buf.append("\nRawCreated: ").append(Base64.encode(data, 0, off)); - buf.append("\nsignedTime: ").append(Base64.encode(data, off-8-Signature.SIGNATURE_BYTES-4, 4)); + buf.append("\nsignedTime: ").append(Base64.encode(data, off - padding - siglen - 4, 4)); _log.debug(buf.toString()); } @@ -623,7 +631,7 @@ class PacketBuilder { byte[] iv = SimpleByteCache.acquire(UDPPacket.IV_SIZE); _context.random().nextBytes(iv); - int encrWrite = Signature.SIGNATURE_BYTES + 8; + int encrWrite = siglen + padding; int sigBegin = off - encrWrite; _context.aes().encrypt(data, sigBegin, data, sigBegin, state.getCipherKey(), iv, encrWrite); @@ -774,8 +782,11 @@ class PacketBuilder { DataHelper.toLong(data, off, 4, state.getSentSignedOnTime()); off += 4; + // handle variable signature size // we need to pad this so we're at the encryption boundary - int mod = (off + Signature.SIGNATURE_BYTES) & 0x0f; + Signature sig = state.getSentSignature(); + int siglen = sig.length(); + int mod = (off + siglen) & 0x0f; if (mod != 0) { int paddingRequired = 16 - mod; // add an arbitrary number of 16byte pad blocks too ??? @@ -787,8 +798,8 @@ class PacketBuilder { // so trailing non-mod-16 data is ignored. That truncates the sig. // BUG: NPE here if null signature - System.arraycopy(state.getSentSignature().getData(), 0, data, off, Signature.SIGNATURE_BYTES); - off += Signature.SIGNATURE_BYTES; + System.arraycopy(sig.getData(), 0, data, off, siglen); + off += siglen; } else { // We never get here (see above) diff --git a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java index 48a5e08225..bc47fba87c 100644 --- a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java +++ b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java @@ -9,8 +9,8 @@ import java.util.concurrent.LinkedBlockingQueue; import net.i2p.data.Base64; import net.i2p.data.DataHelper; -import net.i2p.data.RouterAddress; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterAddress; +import net.i2p.data.router.RouterInfo; import net.i2p.data.SessionKey; import net.i2p.router.CommSystemFacade; import net.i2p.router.RouterContext; diff --git a/router/java/src/net/i2p/router/transport/udp/UDPAddress.java b/router/java/src/net/i2p/router/transport/udp/UDPAddress.java index f05205582d..88551d588c 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPAddress.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPAddress.java @@ -5,7 +5,7 @@ import java.net.UnknownHostException; import java.util.Map; import net.i2p.data.Base64; -import net.i2p.data.RouterAddress; +import net.i2p.data.router.RouterAddress; import net.i2p.data.SessionKey; import net.i2p.util.LHMCache; import net.i2p.util.SystemVersion; diff --git a/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java b/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java index affaf09df8..f7c89bb893 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java @@ -203,9 +203,10 @@ class UDPPacketReader { return rv; } - public void readEncryptedSignature(byte target[], int targetOffset) { + /** @param size the amount to be copied, including padding to mod 16 */ + public void readEncryptedSignature(byte target[], int targetOffset, int size) { int offset = readBodyOffset() + Y_LENGTH + 1 + readIPSize() + 2 + 4 + 4; - System.arraycopy(_message, offset, target, targetOffset, Signature.SIGNATURE_BYTES + 8); + System.arraycopy(_message, offset, target, targetOffset, size); } public void readIV(byte target[], int targetOffset) { @@ -239,7 +240,11 @@ class UDPPacketReader { System.arraycopy(_message, readOffset, target, targetOffset, len); } - /** read the time at which the signature was generated */ + /** + * Read the time at which the signature was generated. + * TODO must be completely in final fragment. + * Time and sig cannot be split across fragments. + */ public long readFinalFragmentSignedOnTime() { if (readCurrentFragmentNum() != readTotalFragmentNum()-1) throw new IllegalStateException("This is not the final fragment"); @@ -247,12 +252,19 @@ class UDPPacketReader { return DataHelper.fromLong(_message, readOffset, 4); } - /** read the signature from the final sessionConfirmed packet */ - public void readFinalSignature(byte target[], int targetOffset) { + /** + * Read the signature from the final sessionConfirmed packet. + * TODO must be completely in final fragment. + * Time and sig cannot be split across fragments. + * @param size not including padding + */ + public void readFinalSignature(byte target[], int targetOffset, int size) { if (readCurrentFragmentNum() != readTotalFragmentNum()-1) throw new IllegalStateException("This is not the final fragment"); - int readOffset = _payloadBeginOffset + _payloadLength - Signature.SIGNATURE_BYTES; - System.arraycopy(_message, readOffset, target, targetOffset, Signature.SIGNATURE_BYTES); + int readOffset = _payloadBeginOffset + _payloadLength - size; + if (readOffset < readBodyOffset() + (1 + 2 + 4)) + throw new IllegalStateException("Sig split across fragments"); + System.arraycopy(_message, readOffset, target, targetOffset, size); } } diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java index b9c2ad8024..63fc957600 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -25,9 +25,9 @@ import java.util.concurrent.CopyOnWriteArrayList; import net.i2p.data.DatabaseEntry; import net.i2p.data.DataHelper; import net.i2p.data.Hash; -import net.i2p.data.RouterAddress; -import net.i2p.data.RouterIdentity; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterAddress; +import net.i2p.data.router.RouterIdentity; +import net.i2p.data.router.RouterInfo; import net.i2p.data.SessionKey; import net.i2p.data.i2np.DatabaseStoreMessage; import net.i2p.data.i2np.I2NPMessage; @@ -1550,6 +1550,12 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority return null; } + // Check for supported sig type + if (toAddress.getIdentity().getSigningPublicKey().getType() == null) { + markUnreachable(to); + return null; + } + if (!allowConnection()) return _cachedBid[TRANSIENT_FAIL_BID]; diff --git a/router/java/src/net/i2p/router/tunnel/InboundGatewayReceiver.java b/router/java/src/net/i2p/router/tunnel/InboundGatewayReceiver.java index 3fa40c984e..bb18c44b22 100644 --- a/router/java/src/net/i2p/router/tunnel/InboundGatewayReceiver.java +++ b/router/java/src/net/i2p/router/tunnel/InboundGatewayReceiver.java @@ -1,7 +1,7 @@ package net.i2p.router.tunnel; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.TunnelDataMessage; import net.i2p.router.JobImpl; import net.i2p.router.OutNetMessage; diff --git a/router/java/src/net/i2p/router/tunnel/InboundMessageDistributor.java b/router/java/src/net/i2p/router/tunnel/InboundMessageDistributor.java index ec3529b48f..660aedab81 100644 --- a/router/java/src/net/i2p/router/tunnel/InboundMessageDistributor.java +++ b/router/java/src/net/i2p/router/tunnel/InboundMessageDistributor.java @@ -4,7 +4,7 @@ import net.i2p.data.DatabaseEntry; import net.i2p.data.Hash; import net.i2p.data.LeaseSet; import net.i2p.data.Payload; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.TunnelId; import net.i2p.data.i2np.DataMessage; import net.i2p.data.i2np.DatabaseSearchReplyMessage; diff --git a/router/java/src/net/i2p/router/tunnel/OutboundMessageDistributor.java b/router/java/src/net/i2p/router/tunnel/OutboundMessageDistributor.java index 364c5970ab..3961af80fc 100644 --- a/router/java/src/net/i2p/router/tunnel/OutboundMessageDistributor.java +++ b/router/java/src/net/i2p/router/tunnel/OutboundMessageDistributor.java @@ -4,7 +4,7 @@ import java.util.HashSet; import java.util.Set; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.TunnelId; import net.i2p.data.i2np.I2NPMessage; import net.i2p.data.i2np.TunnelGatewayMessage; diff --git a/router/java/src/net/i2p/router/tunnel/OutboundReceiver.java b/router/java/src/net/i2p/router/tunnel/OutboundReceiver.java index 03923ecfeb..4aef149028 100644 --- a/router/java/src/net/i2p/router/tunnel/OutboundReceiver.java +++ b/router/java/src/net/i2p/router/tunnel/OutboundReceiver.java @@ -1,7 +1,7 @@ package net.i2p.router.tunnel; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.i2np.TunnelDataMessage; import net.i2p.router.JobImpl; import net.i2p.router.OutNetMessage; diff --git a/router/java/src/net/i2p/router/tunnel/TunnelParticipant.java b/router/java/src/net/i2p/router/tunnel/TunnelParticipant.java index b53d8a6430..d580602793 100644 --- a/router/java/src/net/i2p/router/tunnel/TunnelParticipant.java +++ b/router/java/src/net/i2p/router/tunnel/TunnelParticipant.java @@ -1,7 +1,7 @@ package net.i2p.router.tunnel; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.TunnelId; import net.i2p.data.i2np.I2NPMessage; import net.i2p.data.i2np.TunnelDataMessage; diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java b/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java index b771589a1f..42cff28c7a 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java @@ -10,7 +10,7 @@ import java.util.concurrent.ConcurrentHashMap; import net.i2p.data.Hash; import net.i2p.data.i2np.I2NPMessage; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.router.CommSystemFacade; import net.i2p.router.RouterContext; import net.i2p.router.TunnelManagerFacade; diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java index afe3940bff..3522e5c4ed 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java @@ -9,8 +9,8 @@ import net.i2p.data.Base64; import net.i2p.data.ByteArray; import net.i2p.data.DataHelper; import net.i2p.data.Hash; -import net.i2p.data.RouterIdentity; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterIdentity; +import net.i2p.data.router.RouterInfo; import net.i2p.data.TunnelId; import net.i2p.data.i2np.BuildRequestRecord; import net.i2p.data.i2np.BuildResponseRecord; diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java b/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java index fbfca2bcc9..31aaa86654 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java @@ -8,7 +8,7 @@ import net.i2p.data.ByteArray; import net.i2p.data.DataHelper; import net.i2p.data.Hash; import net.i2p.data.PublicKey; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.data.TunnelId; import net.i2p.data.i2np.TunnelBuildMessage; import net.i2p.data.i2np.VariableTunnelBuildMessage; diff --git a/router/java/src/net/i2p/router/tunnel/pool/TunnelPeerSelector.java b/router/java/src/net/i2p/router/tunnel/pool/TunnelPeerSelector.java index 14eab47e2c..8bb657831c 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPeerSelector.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPeerSelector.java @@ -16,7 +16,7 @@ import net.i2p.I2PAppContext; import net.i2p.crypto.SHA256Generator; import net.i2p.data.DataFormatException; import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; +import net.i2p.data.router.RouterInfo; import net.i2p.router.Router; import net.i2p.router.RouterContext; import net.i2p.router.TunnelPoolSettings;