Author: nextgens
Date: 2007-09-29 13:24:41 +0000 (Sat, 29 Sep 2007)
New Revision: 15385

Modified:
   branches/freenet-jfk/src/freenet/node/FNPPacketMangler.java
   branches/freenet-jfk/src/freenet/node/PeerNode.java
Log:
Working message4 ... now we need to sort out what to do regarding rekeying, 
transmition of the bootid ... and well wire it in.

Modified: branches/freenet-jfk/src/freenet/node/FNPPacketMangler.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/FNPPacketMangler.java 2007-09-29 
12:11:36 UTC (rev 15384)
+++ branches/freenet-jfk/src/freenet/node/FNPPacketMangler.java 2007-09-29 
13:24:41 UTC (rev 15385)
@@ -433,7 +433,7 @@
                                 * using the same keys as in the previous 
message.
                                 * The signature is non-message recovering
                                 */
-                               //processMessage4(payload,pn,replyTo);
+                               processMessage4(payload, pn);
                        }
                }
                else {
@@ -663,7 +663,7 @@
                long t2=System.currentTimeMillis();
                if((t2-t1)>500)
                        Logger.error(this,"Message1 timeout error:Sending 
packet for"+pn.getPeer());
-       }        
+       }

        /*
         * Initiator Method:Message3
@@ -762,11 +762,8 @@

                DiffieHellmanLightContext dhContext = 
getLightDiffieHellmanContext(pn);
                BigInteger computedExponential = 
dhContext.getHMACKey(_hisExponential, Global.DHgroupA);
-               if(logMINOR) Logger.minor(this, "We have computed the following 
exponential : " + HexUtil.biToHex(computedExponential));
                byte[] Ke = computeJFKSharedKey(computedExponential, 
nonceInitiator, nonceResponder, "1");
-               if(logMINOR) Logger.minor(this, "We are using Ke=" + 
HexUtil.bytesToHex(Ke));
                byte[] Ka = computeJFKSharedKey(computedExponential, 
nonceInitiator, nonceResponder, "2");
-               if(logMINOR) Logger.minor(this, "We are using Ka=" + 
HexUtil.bytesToHex(Ka));
                c.initialize(Ke);
                final PCFBMode pk = PCFBMode.create(c);
                int ivLength = pk.lengthIV();
@@ -800,24 +797,115 @@
                decypheredPayloadOffset += Node.SIGNATURE_PARAMETER_LENGTH;

                // verify the signature
-               DSASignature remoteSignature = new DSASignature(new 
NativeBigInteger(1,r), new NativeBigInteger(1,s));
-               byte[] locallyGeneratedText = 
SHA256.digest(assembleDHParams(nonceInitiator, nonceResponder, _hisExponential, 
_ourExponential, crypto.myIdentity));
-               if(logMINOR) {
-                       Logger.minor(this, "Remote sent us the following sig 
:"+remoteSignature.toLongString());
-                       Logger.minor(this, "We are have the following locally 
:"+HexUtil.bytesToHex(locallyGeneratedText));
-               }
-               if(!DSA.verify(pn.peerPubKey, remoteSignature, new 
NativeBigInteger(1, locallyGeneratedText), false)) {
+               DSASignature remoteSignature = new DSASignature(new 
NativeBigInteger(1,r), new NativeBigInteger(1,s)); 
+               if(!DSA.verify(pn.peerPubKey, remoteSignature, new 
NativeBigInteger(1, SHA256.digest(assembleDHParams(nonceInitiator, 
nonceResponder, _hisExponential, _ourExponential, crypto.myIdentity))), false)) 
{
                        Logger.error(this, "The signature verification has 
failed!!");
                        return;
                }

                // Send reply
                sendMessage4Packet(1, 2, 3, nonceInitiator, 
nonceResponder,initiatorExponential, responderExponential, c, Ke, Ka, 
authenticator, pn, replyTo);
+               
+               //FIXME: rekey .... ?
+               System.out.println("Time to call completedHandshake ^-^");
+               
                final long t2=System.currentTimeMillis();
                if((t2-t1)>500)
                        Logger.error(this,"Message3 timeout error:Sending 
packet for"+pn.getPeer());
        }
+       
+       /*
+        * Responder Method:Message4
+        * Process Message4
+        * 
+        * @param Payload
+        * @param The peerNode we are talking to
+        * 
+        */
+       private void processMessage4(byte[] payload, PeerNode pn)               
        
+       {
+               final long t1 = System.currentTimeMillis();
+               if(logMINOR) Logger.minor(this, "Got a JFK(4) message, 
processing it");
+               BlockCipher c = null;
+               try { c = new Rijndael(256, 256); } catch 
(UnsupportedCipherException e) {}
+               int inputOffset=3;
+               
+               final int expectedLength =      HASH_LENGTH + // HMAC of the 
cyphertext
+                                                                       
(c.getBlockSize() >> 3) + // IV
+                                                                       
HASH_LENGTH; // the signature
+               if(payload.length < expectedLength + 3) {
+                       Logger.error(this, "Packet too short from "+pn+": 
"+payload.length+" after decryption in JFK(4), should be "+(expectedLength + 
3));
+                       return;
+               }
+               byte[] jfkBuffer = pn.getJFKBuffer();
+               if(jfkBuffer == null) {
+                       Logger.normal(this, "We have already handled this 
message... might be a replay or a bug");
+                       return;
+               }

+               byte[] hmac = new byte[HASH_LENGTH];
+               System.arraycopy(payload, inputOffset, hmac, 0, HASH_LENGTH);
+               inputOffset += HASH_LENGTH;
+               
+               //FIXME: do we need to "c.initialize(Ke);" ? I don't think so 
but I'm not sure - nextgens
+               c.initialize(pn.jfkKe);
+               final PCFBMode pk = PCFBMode.create(c);
+               int ivLength = pk.lengthIV();
+               int decypheredPayloadOffset = 0;
+               // We compute the HMAC of ("I"+cyphertext) : the cyphertext 
includes the IV!
+               byte[] prefix = null;
+               try { prefix = "R".getBytes("UTF-8"); } catch 
(UnsupportedEncodingException e) {}
+               byte[] decypheredPayload = new byte[prefix.length + ivLength + 
Node.SIGNATURE_PARAMETER_LENGTH*2];
+               System.arraycopy(prefix, 0, decypheredPayload, 
decypheredPayloadOffset, prefix.length);
+               decypheredPayloadOffset += prefix.length;
+               System.arraycopy(payload, inputOffset, decypheredPayload, 
decypheredPayloadOffset, ivLength + Node.SIGNATURE_PARAMETER_LENGTH*2);
+               HMAC mac = new HMAC(SHA256.getInstance());
+               if(!mac.verify(pn.jfkKa, decypheredPayload, hmac)) {
+                       Logger.error(this, "The digest-HMAC doesn't match; 
let's discard the packet");
+                       return;
+               }
+               
+               // Get the IV
+               pk.reset(decypheredPayload, decypheredPayloadOffset);
+               decypheredPayloadOffset += ivLength;
+               // Decrypt the payload
+               pk.blockDecipher(decypheredPayload, decypheredPayloadOffset, 
Node.SIGNATURE_PARAMETER_LENGTH*2);
+               /*
+                * DecipheredData Format:
+                * Signature-r,s
+                */
+               byte[] r = new byte[Node.SIGNATURE_PARAMETER_LENGTH];
+               System.arraycopy(decypheredPayload, decypheredPayloadOffset, r, 
0, Node.SIGNATURE_PARAMETER_LENGTH);
+               decypheredPayloadOffset += Node.SIGNATURE_PARAMETER_LENGTH;
+               byte[] s = new byte[Node.SIGNATURE_PARAMETER_LENGTH];
+               System.arraycopy(decypheredPayload, decypheredPayloadOffset, s, 
0, Node.SIGNATURE_PARAMETER_LENGTH);
+               decypheredPayloadOffset += Node.SIGNATURE_PARAMETER_LENGTH;
+               
+               // verify the signature
+               DSASignature remoteSignature = new DSASignature(new 
NativeBigInteger(1,r), new NativeBigInteger(1,s));
+               byte[] locallyGeneratedText = new byte[NONCE_SIZE * 2 + 
DiffieHellman.modulusLengthInBytes() * 2 + crypto.myIdentity.length];
+               int bufferOffset = NONCE_SIZE * 2 + 
DiffieHellman.modulusLengthInBytes()*2;
+               System.arraycopy(jfkBuffer, 0, locallyGeneratedText, 0, 
bufferOffset);
+               System.arraycopy(crypto.myIdentity, 0, locallyGeneratedText, 
bufferOffset, crypto.myIdentity.length);
+               if(!DSA.verify(pn.peerPubKey, remoteSignature, new 
NativeBigInteger(1, SHA256.digest(locallyGeneratedText)), false)) {
+                       Logger.error(this, "The signature verification has 
failed!!");
+                       return;
+               }
+               
+               //FIXME: when do we reset the buffer/rekey/DH/transientkey ?
+               System.out.println("time to call completedHandshake! ^-^");
+               // pn.completedHandshake(bufferOffset, locallyGeneratedText, 
decypheredPayloadOffset, ivLength, c, Ke, replyTo, false)
+               
+               // cleanup
+               pn.setJFKBuffer(null);
+               pn.jfkKa = null;
+               pn.jfkKe = null;
+               
+               final long t2=System.currentTimeMillis();
+               if((t2-t1)>500)
+                       Logger.error(this,"Message3 timeout error:Sending 
packet for"+pn.getPeer());
+       }
+
        /*
         * Convert Object to byteArray
         */
@@ -883,23 +971,15 @@
                NativeBigInteger _hisExponential = new 
NativeBigInteger(1,hisExponential);
                // save parameters so that we can verify message4
                byte[] toSign = assembleDHParams(nonceInitiator, 
nonceResponder, _ourExponential, _hisExponential, pn.identity);
-               pn.setBufferJFK(toSign);
+               pn.setJFKBuffer(toSign);
                DSASignature localSignature = 
crypto.sign(SHA256.digest(toSign));
                byte[] r = 
localSignature.getRBytes(Node.SIGNATURE_PARAMETER_LENGTH);
                byte[] s = 
localSignature.getSBytes(Node.SIGNATURE_PARAMETER_LENGTH);

                BigInteger computedExponential = 
dhContext.getHMACKey(_hisExponential, Global.DHgroupA);
-               byte[] Ke = computeJFKSharedKey(computedExponential, 
nonceInitiator, nonceResponder, "1");
-               byte[] Ka = computeJFKSharedKey(computedExponential, 
nonceInitiator, nonceResponder, "2");
-               if(logMINOR) {
-                       Logger.minor(this, "We have computed the following 
exponential : " + HexUtil.biToHex(computedExponential));
-                       Logger.minor(this, "We are using Ke=" + 
HexUtil.bytesToHex(Ke));
-                       Logger.minor(this, "We are using Ka=" + 
HexUtil.bytesToHex(Ka));
-                       Logger.minor(this, "We are re-sending authenticator = " 
+ HexUtil.bytesToHex(authenticator));
-                       Logger.minor(this, "We send the following signature : 
"+localSignature.toLongString());
-                       Logger.minor(this, "We have been signing "+ 
HexUtil.bytesToHex(toSign));
-               }
-               c.initialize(Ke);
+               pn.jfkKe = computeJFKSharedKey(computedExponential, 
nonceInitiator, nonceResponder, "1");
+               pn.jfkKa = computeJFKSharedKey(computedExponential, 
nonceInitiator, nonceResponder, "2");
+               c.initialize(pn.jfkKe);
                PCFBMode pcfb = PCFBMode.create(c);
                int ivLength = pcfb.lengthIV();
                byte[] iv = new byte[ivLength];
@@ -924,7 +1004,7 @@

                // We compute the HMAC of (prefix + cyphertext) Includes the IV!
                HMAC mac = new HMAC(SHA256.getInstance());
-               byte[] hmac = mac.mac(Ka, cleartext, HASH_LENGTH);
+               byte[] hmac = mac.mac(pn.jfkKa, cleartext, HASH_LENGTH);

                // copy stuffs back to the message
                System.arraycopy(hmac, 0, message3, offset, HASH_LENGTH);
@@ -936,7 +1016,7 @@
                // cache the message
                synchronized (authenticatorCache) {
                        authenticatorCache.put(authenticator,message3);
-               }
+               }               
                sendAuthPacket(1, 2, 2, message3, pn, replyTo);
        }

@@ -949,16 +1029,13 @@
        {
                if(logMINOR)
                        Logger.minor(this, "Sending a JFK(4) message to "+pn);
-               DiffieHellmanLightContext dhContext = 
getLightDiffieHellmanContext(pn);
                NativeBigInteger _responderExponential = new 
NativeBigInteger(1,responderExponential);
                NativeBigInteger _initiatorExponential = new 
NativeBigInteger(1,initiatorExponential);
-               DSASignature localSignature = 
signDHParams(nonceInitiator,nonceResponder,_responderExponential,_initiatorExponential,
 crypto.myIdentity);
+               
+               DSASignature localSignature = 
crypto.sign(SHA256.digest(assembleDHParams(nonceInitiator, nonceResponder, 
_initiatorExponential, _responderExponential, pn.identity)));
                byte[] r = 
localSignature.getRBytes(Node.SIGNATURE_PARAMETER_LENGTH);
                byte[] s = 
localSignature.getSBytes(Node.SIGNATURE_PARAMETER_LENGTH);
-               BigInteger computedExponential = 
dhContext.getHMACKey(_initiatorExponential, Global.DHgroupA);
-               if(logMINOR) Logger.minor(this, "We have computed the following 
exponential : " + HexUtil.biToHex(computedExponential));
-               if(logMINOR) Logger.minor(this, "We are using Ke=" + 
HexUtil.bytesToHex(Ke));
-               if(logMINOR) Logger.minor(this, "We are using Ka=" + 
HexUtil.bytesToHex(Ka));
+               
                PCFBMode pk=PCFBMode.create(c);
                int ivLength = pk.lengthIV();
                byte[] iv=new byte[ivLength];
@@ -967,38 +1044,38 @@
                byte[] prefix = null;
                try { prefix = "R".getBytes("UTF-8"); } catch 
(UnsupportedEncodingException e) {}

-               byte[] cleartext = new byte[prefix.length + ivLength + 
Node.SIGNATURE_PARAMETER_LENGTH * 2];
+               byte[] cyphertext = new byte[prefix.length + ivLength + 
Node.SIGNATURE_PARAMETER_LENGTH * 2];
                int cleartextOffset = 0;
-               System.arraycopy(prefix, 0, cleartext, cleartextOffset, 
prefix.length);
+               System.arraycopy(prefix, 0, cyphertext, cleartextOffset, 
prefix.length);
                cleartextOffset += prefix.length;
-               System.arraycopy(iv, 0, cleartext, cleartextOffset, ivLength);
+               System.arraycopy(iv, 0, cyphertext, cleartextOffset, ivLength);
                cleartextOffset += ivLength;
-               System.arraycopy(r, 0, cleartext, cleartextOffset, 
Node.SIGNATURE_PARAMETER_LENGTH);
+               System.arraycopy(r, 0, cyphertext, cleartextOffset, 
Node.SIGNATURE_PARAMETER_LENGTH);
                cleartextOffset += Node.SIGNATURE_PARAMETER_LENGTH;
-               System.arraycopy(s, 0, cleartext, cleartextOffset, 
Node.SIGNATURE_PARAMETER_LENGTH);
+               System.arraycopy(s, 0, cyphertext, cleartextOffset, 
Node.SIGNATURE_PARAMETER_LENGTH);
                cleartextOffset += Node.SIGNATURE_PARAMETER_LENGTH;
+               // Now encrypt the cleartext[Signature]
+               int cleartextToEncypherOffset = prefix.length + ivLength;
+               pk.blockEncipher(cyphertext, cleartextToEncypherOffset, 
Node.SIGNATURE_PARAMETER_LENGTH*2);
+               
                // We compute the HMAC of (prefix + iv + signature)
                HMAC mac = new HMAC(SHA256.getInstance());
-               byte[] hmac = mac.mac(Ka, cleartext, HASH_LENGTH);
-               // Now encrypt the cleartext[Signature]
-               int cleartextToEncypherOffset = prefix.length + ivLength;
-               pk.blockEncipher(cleartext, cleartextToEncypherOffset, 
Node.SIGNATURE_PARAMETER_LENGTH*2 );
-
+               byte[] hmac = mac.mac(Ka, cyphertext, HASH_LENGTH);
+               
                // Message4 = hmac + IV + encryptedSignature
-               byte[] message4 = new byte[HASH_LENGTH + (c.getBlockSize() >> 
3) + Node.SIGNATURE_PARAMETER_LENGTH * 2]; 
+               byte[] message4 = new byte[HASH_LENGTH + ivLength + 
Node.SIGNATURE_PARAMETER_LENGTH * 2]; 
                int offset = 0;
                System.arraycopy(hmac, 0, message4, offset, HASH_LENGTH);
                offset += HASH_LENGTH;
                System.arraycopy(iv, 0, message4, offset, ivLength);
                offset += ivLength;
-               System.arraycopy(cleartext, cleartextToEncypherOffset, 
message4, offset, Node.SIGNATURE_PARAMETER_LENGTH * 2);
+               System.arraycopy(cyphertext, cleartextToEncypherOffset, 
message4, offset, Node.SIGNATURE_PARAMETER_LENGTH * 2);

                // cache the message
                synchronized (authenticatorCache) {
                        authenticatorCache.put(authenticator, message4);
                }
-               
-               sendAuthPacket(1,2,3,message4,pn,replyTo);
+               sendAuthPacket(1, 2, 3, message4, pn, replyTo);
        }

        /**
@@ -2310,12 +2387,6 @@
        private DSASignature signDHParams(BigInteger exponential, DSAGroup 
group) {
                return crypto.sign(assembleDHParams(exponential, group));
        }
-       /*
-        * Sign the params for message4
-        */
-       private DSASignature signDHParams(byte[] nonceInitiator,byte[] 
nonceResponder,BigInteger myExponential, BigInteger hisExponential,byte[] 
hashIDi) {
-               return 
crypto.sign(assembleDHParams(nonceInitiator,nonceResponder, myExponential, 
hisExponential, hashIDi));
-       }

        private byte[] getTransientKey() {
                synchronized (authenticatorCache) {

Modified: branches/freenet-jfk/src/freenet/node/PeerNode.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/PeerNode.java 2007-09-29 12:11:36 UTC 
(rev 15384)
+++ branches/freenet-jfk/src/freenet/node/PeerNode.java 2007-09-29 13:24:41 UTC 
(rev 15385)
@@ -89,7 +89,10 @@
     /*
      * Buffer of Ni,Nr,g^i,g^r,ID
      */
-    private byte[] bufferJFK;
+    private byte[] jfkBuffer;
+    //TODO: sync ?
+    protected byte[] jfkKa;
+    protected byte[] jfkKe;

     /** My low-level address for SocketManager purposes */
     private Peer detectedPeer;
@@ -2743,11 +2746,11 @@
                setPeerNodeStatus(System.currentTimeMillis());
        }

-       protected byte[] getBufferJFK() {
-               return bufferJFK;
+       protected byte[] getJFKBuffer() {
+               return jfkBuffer;
        }

-       protected void setBufferJFK(byte[] bufferJFK) {
-               this.bufferJFK = bufferJFK;
+       protected void setJFKBuffer(byte[] bufferJFK) {
+               this.jfkBuffer = bufferJFK;
        }
 }


Reply via email to