Author: toad
Date: 2007-12-05 16:27:39 +0000 (Wed, 05 Dec 2007)
New Revision: 16328

Modified:
   trunk/freenet/src/freenet/node/FNPPacketMangler.java
Log:
sendAnonAuthPacket vs sendAuthPacket.
Pass in unknownInitiator and setupType to each JFK method.
Some work on stage 2, 3.

Modified: trunk/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/FNPPacketMangler.java        2007-12-05 
15:55:56 UTC (rev 16327)
+++ trunk/freenet/src/freenet/node/FNPPacketMangler.java        2007-12-05 
16:27:39 UTC (rev 16328)
@@ -507,10 +507,10 @@

                if(packetType == 0) {
                        // Phase 1
-                       processJFKMessage1(payload,4,null,replyTo, true);
+                       processJFKMessage1(payload,4,null,replyTo, true, 
setupType);
                } else if(packetType == 2) {
                        // Phase 3
-                       processJFKMessage3(payload, 4, null, replyTo, false);
+                       processJFKMessage3(payload, 4, null, replyTo, false, 
true, setupType);
                } else {
                        Logger.error(this, "Invalid phase "+packetType+" for 
anonymous-initiator (we are the responder)");
                }
@@ -551,10 +551,10 @@

                if(packetType == 1) {
                        // Phase 2
-                       processJFKMessage2(payload, 4, pn, replyTo);
+                       processJFKMessage2(payload, 4, pn, replyTo, true, 
setupType);
                } else if(packetType == 3) {
                        // Phase 4
-                       processJFKMessage4(payload, 4, pn, replyTo, false);
+                       processJFKMessage4(payload, 4, pn, replyTo, false, 
true, setupType);
                } else {
                        Logger.error(this, "Invalid phase "+packetType+" for 
anonymous-initiator (we are the responder)");
                }
@@ -627,7 +627,7 @@
                                 * session key will be different,can be used to 
differentiate between
                                 * parallel sessions
                                 */
-                               processJFKMessage1(payload,3,pn,replyTo,false);
+                               
processJFKMessage1(payload,3,pn,replyTo,false,-1);

                        }
                        else if(packetType==1){
@@ -636,7 +636,7 @@
                                 * nonce and an authenticator calculated from a 
transient hash key private
                                 * to the responder.
                                 */
-                               processJFKMessage2(payload,3,pn,replyTo);
+                               
processJFKMessage2(payload,3,pn,replyTo,false,-1);
                        }
                        else if(packetType==2){
                                /*
@@ -644,7 +644,7 @@
                                 * cached by the Responder.Receiving a 
duplicate message simply causes
                                 * the responder to Re-transmit the 
corresponding message4
                                 */
-                               processJFKMessage3(payload, 3, pn, replyTo, 
oldOpennetPeer);
+                               processJFKMessage3(payload, 3, pn, replyTo, 
oldOpennetPeer, false, -1);
                        }
                        else if(packetType==3){
                                /*
@@ -652,7 +652,7 @@
                                 * using the same keys as in the previous 
message.
                                 * The signature is non-message recovering
                                 */
-                               processJFKMessage4(payload, 3, pn, replyTo, 
oldOpennetPeer);
+                               processJFKMessage4(payload, 3, pn, replyTo, 
oldOpennetPeer, false, -1);
                        }
                } else {
                        Logger.error(this, "Decrypted auth packet but unknown 
negotiation type "+negType+" from "+replyTo+" possibly from "+pn);
@@ -682,7 +682,7 @@
         * ACM Transactions on Information and System Security, Vol 7 No 2, May 
2004, Pages 1-30.
         * 
         */     
-       private void processJFKMessage1(byte[] payload,int offset,PeerNode 
pn,Peer replyTo, boolean unknownInitiator)
+       private void processJFKMessage1(byte[] payload,int offset,PeerNode 
pn,Peer replyTo, boolean unknownInitiator, int setupType)
        {
                long t1=System.currentTimeMillis();
                if(logMINOR) Logger.minor(this, "Got a JFK(1) message, 
processing it - "+pn);
@@ -713,7 +713,7 @@

                NativeBigInteger _hisExponential = new 
NativeBigInteger(1,hisExponential);
                if(DiffieHellman.checkDHExponentialValidity(this.getClass(), 
_hisExponential)) {
-                       sendJFKMessage2(nonceInitiator, hisExponential, pn, 
replyTo);
+                       sendJFKMessage2(nonceInitiator, hisExponential, pn, 
replyTo, unknownInitiator, setupType);
                }else
                        Logger.error(this, "We can't accept the exponential 
"+pn+" sent us!! REDFLAG: IT CAN'T HAPPEN UNLESS AGAINST AN ACTIVE ATTACKER!!");

@@ -727,7 +727,7 @@
         * Ni,g^i
         * We send IDr' only if unknownInitiator is set.
         */
-       private void sendJFKMessage1(PeerNode pn, Peer replyTo, boolean 
unknownInitiator) {
+       private void sendJFKMessage1(PeerNode pn, Peer replyTo, boolean 
unknownInitiator, int setupType) {
                if(logMINOR) Logger.minor(this, "Sending a JFK(1) message to 
"+pn);
                final long now = System.currentTimeMillis();
                DiffieHellmanLightContext ctx = (DiffieHellmanLightContext) 
pn.getKeyAgreementSchemeContext();
@@ -754,9 +754,10 @@
                if(unknownInitiator) {
                        offset += modulusLength;
                        System.arraycopy(pn.identityHash, 0, message1, offset, 
pn.identityHash.length);
+                       
sendAnonAuthPacket(1,2,0,setupType,message1,pn,replyTo,pn.anonymousInitiatorSetupCipher);
+               } else {
+                       sendAuthPacket(1,2,0,message1,pn,replyTo);
                }
-
-               sendAuthPacket(1,2,0,message1,pn,replyTo);
        }

        /*
@@ -768,7 +769,7 @@
         * NB: we don't send IDr nor groupinfo as we know them: even if the 
responder doesn't know the initiator,
         * the initiator ALWAYS knows the responder. 
         */
-       private void sendJFKMessage2(byte[] nonceInitator, byte[] 
hisExponential, PeerNode pn, Peer replyTo) {
+       private void sendJFKMessage2(byte[] nonceInitator, byte[] 
hisExponential, PeerNode pn, Peer replyTo, boolean unknownInitiator, int 
setupType) {
                if(logMINOR) Logger.minor(this, "Sending a JFK(2) message to 
"+pn);
                DiffieHellmanLightContext ctx = getLightDiffieHellmanContext();
                // g^r
@@ -801,7 +802,10 @@

                System.arraycopy(authenticator, 0, message2, offset, 
HASH_LENGTH);

-               sendAuthPacket(1,2,1,message2,pn,replyTo);
+               if(unknownInitiator)
+                       
sendAnonAuthPacket(1,2,1,setupType,message2,pn,replyTo,crypto.anonSetupCipher);
+               else
+                       sendAuthPacket(1,2,1,message2,pn,replyTo);
        }

        /*
@@ -837,7 +841,7 @@
         * @param The peerNode we are talking to
         */

-       private void processJFKMessage2(byte[] payload,int inputOffset,PeerNode 
pn,Peer replyTo)
+       private void processJFKMessage2(byte[] payload,int inputOffset,PeerNode 
pn,Peer replyTo, boolean unknownInitiator, int setupType)
        {
                long t1=System.currentTimeMillis();
                if(logMINOR) Logger.minor(this, "Got a JFK(2) message, 
processing it - "+pn);
@@ -917,7 +921,7 @@
                // At this point we know it's from the peer, so we can report a 
packet received.
                pn.receivedPacket(true);

-               sendJFKMessage3(1, 2, 3, nonceInitiator, nonceResponder, 
hisExponential, authenticator, pn, replyTo);
+               sendJFKMessage3(1, 2, 3, nonceInitiator, nonceResponder, 
hisExponential, authenticator, pn, replyTo, unknownInitiator, setupType);

                long t2=System.currentTimeMillis();
                if((t2-t1)>500)
@@ -937,15 +941,17 @@
         * Ni, Nr, g^i, g^r
         * Authenticator - HMAC{g^ir}(g^r, g^i, Nr, Ni, IP)
         * HMAC{Ka}(cyphertext)
-        * IV + E{KE}[S{i}[Ni,Nr,g^i,g^r,idR, bootID, znoderefI], bootID, 
znoderefI]
+        * IV + E{KE}[S{i}[Ni,Nr,g^i,g^r,idR, bootID, znoderefI], bootID, 
znoderefI*]
         * 
+        * * Noderef is sent whether or not unknownInitiator is true, however 
if it is, it will
+        * be a *full* noderef, otherwise it will exclude the pubkey etc.
         * 
         * @param Payload
         * @param The peer to which we need to send the packet
         * @param The peerNode we are talking to
         * @return byte Message3
         */
-       private void processJFKMessage3(byte[] payload, int inputOffset, 
PeerNode pn,Peer replyTo, boolean oldOpennetPeer)
+       private void processJFKMessage3(byte[] payload, int inputOffset, 
PeerNode pn,Peer replyTo, boolean oldOpennetPeer, boolean unknownInitiator, int 
setupType)
        {
                final long t1 = System.currentTimeMillis();
                if(logMINOR) Logger.minor(this, "Got a JFK(3) message, 
processing it - "+pn);
@@ -1068,7 +1074,7 @@
                pn.receivedPacket(true);

                // Send reply
-               sendJFKMessage4(1, 2, 3, nonceInitiator, 
nonceResponder,initiatorExponential, responderExponential, c, Ke, Ka, 
authenticator, hisRef, pn, replyTo);
+               sendJFKMessage4(1, 2, 3, nonceInitiator, 
nonceResponder,initiatorExponential, responderExponential, c, Ke, Ka, 
authenticator, hisRef, pn, replyTo, unknownInitiator, setupType);
                c.initialize(Ks);

                // Promote if necessary
@@ -1112,7 +1118,7 @@
         * @param The peerNode we are talking to
         * @param replyTo the Peer we are replying to
         */
-       private void processJFKMessage4(byte[] payload, int inputOffset, 
PeerNode pn, Peer replyTo, boolean oldOpennetPeer)
+       private void processJFKMessage4(byte[] payload, int inputOffset, 
PeerNode pn, Peer replyTo, boolean oldOpennetPeer, boolean unknownInitiator, 
int setupType)
        {
                final long t1 = System.currentTimeMillis();
                if(logMINOR) Logger.minor(this, "Got a JFK(4) message, 
processing it - "+pn);
@@ -1245,7 +1251,7 @@
         * 
         */

-       private void sendJFKMessage3(int version,int negType,int phase,byte[] 
nonceInitiator,byte[] nonceResponder,byte[] hisExponential, byte[] 
authenticator, final PeerNode pn, final Peer replyTo)
+       private void sendJFKMessage3(int version,int negType,int phase,byte[] 
nonceInitiator,byte[] nonceResponder,byte[] hisExponential, byte[] 
authenticator, final PeerNode pn, final Peer replyTo, boolean unknownInitiator, 
int setupType)
        {
                if(logMINOR) Logger.minor(this, "Sending a JFK(3) message to 
"+pn);
                BlockCipher c = null;
@@ -1338,8 +1344,11 @@
                synchronized (authenticatorCache) {
                        if(!maybeResetTransientKey())
                                authenticatorCache.put(authenticator,message3);
-               }               
-               sendAuthPacket(1, 2, 2, message3, pn, replyTo);
+               }
+               if(unknownInitiator)
+                       sendAnonAuthPacket(1, 2, 2, setupType, message3, pn, 
replyTo, pn.anonymousInitiatorSetupCipher);
+               else
+                       sendAuthPacket(1, 2, 2, message3, pn, replyTo);

                /* Re-send the packet after 5sec if we don't get any reply */
                node.getTicker().queueTimedJob(new Runnable() {
@@ -1358,7 +1367,7 @@
         * IV, E{Ke}[S{R}[Ni,Nr,g^i,g^r,idI, bootID, znoderefR, 
znoderefI],bootID,znoderefR]
         * 
         */
-       private void sendJFKMessage4(int version,int negType,int phase,byte[] 
nonceInitiator,byte[] nonceResponder,byte[] initiatorExponential,byte[] 
responderExponential, BlockCipher c, byte[] Ke, byte[] Ka, byte[] 
authenticator, byte[] hisRef, PeerNode pn, Peer replyTo)
+       private void sendJFKMessage4(int version,int negType,int phase,byte[] 
nonceInitiator,byte[] nonceResponder,byte[] initiatorExponential,byte[] 
responderExponential, BlockCipher c, byte[] Ke, byte[] Ka, byte[] 
authenticator, byte[] hisRef, PeerNode pn, Peer replyTo, boolean 
unknownInitiator, int setupType)
        {
                if(logMINOR)
                        Logger.minor(this, "Sending a JFK(4) message to "+pn);
@@ -1418,7 +1427,10 @@
                                authenticatorCache.put(authenticator, message4);
                }

-               sendAuthPacket(1, 2, 3, message4, pn, replyTo);
+               if(unknownInitiator)
+                       sendAnonAuthPacket(1, 2, 3, setupType, message4, pn, 
replyTo, crypto.anonSetupCipher);
+               else
+                       sendAuthPacket(1, 2, 3, message4, pn, replyTo);
        }

        /**
@@ -1433,19 +1445,38 @@
                output[2] = (byte) phase;
                System.arraycopy(data, 0, output, 3, data.length);
                if(logMINOR) Logger.minor(this, "Sending auth packet for 
"+pn.getPeer()+" (phase="+phase+", ver="+version+", nt="+negType+") (last 
packet sent "+TimeUtil.formatTime(delta, 2, true)+" ago) to "+replyTo+" 
data.length="+data.length);
-               sendAuthPacket(output, pn, replyTo);
+               sendAuthPacket(output, pn.outgoingSetupCipher, pn, replyTo);
        }
-
+       
        /**
+        * @param version
+        * @param negType
+        * @param phase
+        * @param setupType
+        * @param data
+        * @param pn May be null. If not null, used for details such as 
anti-firewall hacks.
+        * @param replyTo
+        * @param cipher
+        */
+       private void sendAnonAuthPacket(int version, int negType, int phase, 
int setupType, byte[] data, PeerNode pn, Peer replyTo, BlockCipher cipher) {
+               byte[] output = new byte[data.length+4];
+               output[0] = (byte) version;
+               output[1] = (byte) negType;
+               output[2] = (byte) phase;
+               output[3] = (byte) setupType;
+               System.arraycopy(data, 0, output, 4, data.length);
+               if(logMINOR) Logger.minor(this, "Sending anon auth packet 
(phase="+phase+", ver="+version+", nt="+negType+") data.length="+data.length);
+               sendAuthPacket(output, cipher, pn, replyTo);
+       }
+       
+       /**
         * Send an auth packet (we have constructed the payload, now hash it, 
pad it, encrypt it).
         */
-       private void sendAuthPacket(byte[] output, PeerNode pn, Peer replyTo) {
+       private void sendAuthPacket(byte[] output, BlockCipher cipher, PeerNode 
pn, Peer replyTo) {
                int length = output.length;
                if(length > sock.getMaxPacketSize()) {
                        throw new IllegalStateException("Cannot send auth 
packet: too long: "+length);
                }
-               BlockCipher cipher = pn.outgoingSetupCipher;
-               if(logMINOR) Logger.minor(this, "Outgoing cipher: 
"+HexUtil.bytesToHex(pn.outgoingSetupKey));
                PCFBMode pcfb = PCFBMode.create(cipher);
                int paddingLength = node.fastWeakRandom.nextInt(100);
                byte[] iv = new byte[pcfb.lengthIV()];
@@ -1473,12 +1504,15 @@
        }

        private void sendPacket(byte[] data, Peer replyTo, PeerNode pn, int 
alreadyReportedBytes) throws LocalAddressException {
-               if(pn.isIgnoreSource()) {
-                       Peer p = pn.getPeer();
-                       if(p != null) replyTo = p;
+               if(pn != null) {
+                       if(pn.isIgnoreSource()) {
+                               Peer p = pn.getPeer();
+                               if(p != null) replyTo = p;
+                       }
                }
-               sock.sendPacket(data, replyTo, pn.allowLocalAddresses());
-               pn.reportOutgoingPacket(data, 0, data.length, 
System.currentTimeMillis());
+               sock.sendPacket(data, replyTo, pn == null ? 
crypto.config.alwaysAllowLocalAddresses() : pn.allowLocalAddresses());
+               if(pn != null)
+                       pn.reportOutgoingPacket(data, 0, data.length, 
System.currentTimeMillis());
                node.outputThrottle.forceGrab(data.length - 
alreadyReportedBytes);
        }

@@ -2393,7 +2427,7 @@
                                if(logMINOR) Logger.minor(this, "Not sending 
handshake to "+handshakeIPs[i]+" for "+pn.getPeer()+" because it's not a real 
Internet address and metadata.allowLocalAddresses is not true");
                                continue;
                        }
-                       sendJFKMessage1(pn, peer, false);
+                       sendJFKMessage1(pn, peer, false, -1);
                        if(logMINOR)
                                Logger.minor(this, "Sending handshake to 
"+peer+" for "+pn+" ("+i+" of "+handshakeIPs.length);
                        pn.sentHandshake();


Reply via email to