Author: nextgens
Date: 2007-10-24 14:15:17 +0000 (Wed, 24 Oct 2007)
New Revision: 15523

Modified:
   trunk/freenet/src/freenet/node/FNPPacketMangler.java
Log:
JFK: 
        Change the transient key on a regular basis (at least once every 
30mins). We need it to be deterministic if we want to have a strict PFS 
interval.

Modified: trunk/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/FNPPacketMangler.java        2007-10-24 
09:53:20 UTC (rev 15522)
+++ trunk/freenet/src/freenet/node/FNPPacketMangler.java        2007-10-24 
14:15:17 UTC (rev 15523)
@@ -64,16 +64,13 @@
        final PacketSocketHandler sock;
        final EntropySource fnpTimingSource;
        final EntropySource myPacketDataSource;
-       /*
+       /**
         * Objects cached during JFK message exchange: JFK(3,4) with 
authenticator as key
         * The messages are cached in hashmaps because the message retrieval 
from the cache 
         * can be performed in constant time( given the key)
-        * Usage of a linkedList could prove to be much slower due to the 
allocation time
-        * for each node in the list.
         */
-
        private final HashMap authenticatorCache;
-       // The following is used in the HMAC calculation of JFK message3 and 
message4
+       /** The following is used in the HMAC calculation of JFK message3 and 
message4 */
        private static final byte[] JFK_PREFIX_INITIATOR, JFK_PREFIX_RESPONDER;
        static {
                byte[] I = null,R = null;
@@ -103,6 +100,21 @@
        private static final int TRANSIENT_KEY_SIZE = HASH_LENGTH;
        /** The key used to authenticate the hmac */
        private final byte[] transientKey = new byte[TRANSIENT_KEY_SIZE];
+       public static final int TRANSIENT_KEY_REKEYING_MIN_INTERVAL = 
30*60*1000;
+       /** The Runnable in charge of rekeying on a regular basis */
+       private final Runnable transitentKeyRekeyer = new Runnable() {
+               public void run() {
+                       resetTransientKey();
+                       
+                       try {
+                               // Ugly hack to let the node start up. When we 
are first
+                               // called in the constructor the ticker is not 
available!
+                               while(!node.isHasStarted())
+                                       Thread.sleep(1000);
+                       } catch (InterruptedException e) {}
+                       node.getTicker().queueTimedJob(transitentKeyRekeyer, 
TRANSIENT_KEY_REKEYING_MIN_INTERVAL);
+               }
+       };
        /** Minimum headers overhead */
        private static final int HEADERS_LENGTH_MINIMUM =
                4 + // sequence number
@@ -139,7 +151,10 @@
                fullHeadersLengthMinimum = HEADERS_LENGTH_MINIMUM + 
sock.getHeadersLength();
                fullHeadersLengthOneMessage = HEADERS_LENGTH_ONE_MESSAGE + 
sock.getHeadersLength();
                logMINOR = Logger.shouldLog(Logger.MINOR, this);
-               resetTransientKey();
+               
+               // Yeah there is a race condition... the key might be at 0 for 
a while...
+               // but it will get reset soonish and current runs will be 
invalidated.
+               node.executor.execute(transitentKeyRekeyer, "JFK 
transientRekeyer");
        }

        /**
@@ -2635,11 +2650,16 @@
                return mac.mac(exponential.toByteArray(), toHash, HASH_LENGTH);
        }

+       /**
+        * Change the transient key used by JFK.
+        * 
+        * It will determine the PFS interval, hence we call it at least once 
every 30mins.
+        */
        private void resetTransientKey() {
                Logger.normal(this, "JFK's TransientKey has been changed and 
the message cache flushed.");
                synchronized (authenticatorCache) {
                        node.random.nextBytes(transientKey);
-
+                       
                        // reset the authenticator cache
                        authenticatorCache.clear();
                }


Reply via email to