Author: nextgens
Date: 2009-01-30 18:35:33 +0000 (Fri, 30 Jan 2009)
New Revision: 25406

Modified:
   trunk/freenet/src/freenet/crypt/HMAC.java
   trunk/freenet/src/freenet/node/FNPPacketMangler.java
   trunk/freenet/src/freenet/node/FailureTable.java
   trunk/freenet/src/freenet/node/NodeDispatcher.java
   trunk/freenet/src/freenet/node/PeerNode.java
Log:
Get rid of some of our home-grown crypto (HMAC)... more refactoring to come.
It may be slower than the current implementation.

Modified: trunk/freenet/src/freenet/crypt/HMAC.java
===================================================================
--- trunk/freenet/src/freenet/crypt/HMAC.java   2009-01-30 18:13:09 UTC (rev 
25405)
+++ trunk/freenet/src/freenet/crypt/HMAC.java   2009-01-30 18:35:33 UTC (rev 
25406)
@@ -3,150 +3,42 @@
  * http://www.gnu.org/ for further details of the GPL. */
 package freenet.crypt;
 
-import java.io.UnsupportedEncodingException;
+import freenet.support.Logger;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
 import java.util.Arrays;
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
 
-import freenet.support.HexUtil;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
 /**
  * Implements the HMAC Keyed Message Authentication function, as described
  * in the draft FIPS standard.
+ * 
+ * Use a KeyGenerator to generate a key!
  */
 public class HMAC {
 
-       protected static final int B = 64;
-       protected static byte[] ipad = new byte[B];
-       protected static byte[] opad = new byte[B];
+    public enum ALGORITHM {
 
-       static {
-               for(int i = 0; i < B; i++) {
-                       ipad[i] = (byte) 0x36;
-                       opad[i] = (byte) 0x5c;
-               }
-       }
-       protected MessageDigest d;
+        HmacSHA256, Hmac1, HmacMD5;
+    }
 
-       public HMAC(MessageDigest md) {
-               this.d = md;
-       }
+    public static byte[] mac(ALGORITHM algo, SecretKey key, byte[] input) 
throws InvalidKeyException {
+        try {
+            Mac mac = Mac.getInstance(algo.name());
+            mac.init(key);
 
-       public boolean verify(byte[] K, byte[] text, byte[] mac) {
-               byte[] mac2 = mac(K, text, mac.length);
-               return Arrays.equals(mac, mac2);
-       }
+            return mac.doFinal();
+        } catch (NoSuchAlgorithmException ex) {
+            Logger.error(HMAC.class, "Check your JVM settings especially the 
JCE!" + ex.getMessage(), ex);
+            System.err.println("Check your JVM settings especially the JCE!" + 
ex);
+            ex.printStackTrace();
+            throw new Error("Check your JVM settings especially the JCE!", ex);
+        }
+    }
 
-       public byte[] mac(byte[] K, byte[] text, int macbytes) {
-               byte[] K0 = null;
-
-               if(K.length == B) // Step 1
-                       K0 = K;
-               else {
-                       // Step 2
-                       if(K.length > B)
-                               K0 = K = Util.hashBytes(d, K);
-
-                       if(K.length < B) { // Step 3
-                               K0 = new byte[B];
-                               System.arraycopy(K, 0, K0, 0, K.length);
-                       }
-               }
-
-               // Step 4
-               byte[] IS1 = Util.xor(K0, ipad);
-
-               // Step 5/6
-               d.update(IS1);
-               d.update(text);
-               IS1 = d.digest();
-
-               // Step 7
-               byte[] IS2 = Util.xor(K0, opad);
-
-               // Step 8/9
-               d.update(IS2);
-               d.update(IS1);
-               IS1 = d.digest();
-
-               // Step 10
-               if(macbytes == IS1.length)
-                       return IS1;
-               else {
-                       byte[] rv = new byte[macbytes];
-                       System.arraycopy(IS1, 0, rv, 0, Math.min(rv.length, 
IS1.length));
-                       return rv;
-               }
-       }
-
-       public static void main(String[] args) throws 
UnsupportedEncodingException {
-               HMAC s = null;
-               try {
-                       s = new HMAC(MessageDigest.getInstance("SHA1"));
-               } catch(NoSuchAlgorithmException e) {
-               }
-               byte[] key = new byte[20];
-               System.err.println("20x0b, 'Hi There':");
-               byte[] text;
-               text = "Hi There".getBytes("UTF-8");
-
-               for(int i = 0; i < key.length; i++)
-                       key[i] = (byte) 0x0b;
-
-               byte[] mv = s.mac(key, text, 20);
-               System.out.println(HexUtil.bytesToHex(mv, 0, mv.length));
-
-               System.err.println("20xaa, 50xdd:");
-               for(int i = 0; i < key.length; i++)
-                       key[i] = (byte) 0xaa;
-               text = new byte[50];
-               for(int i = 0; i < text.length; i++)
-                       text[i] = (byte) 0xdd;
-               mv = s.mac(key, text, 20);
-               System.out.println(HexUtil.bytesToHex(mv, 0, mv.length));
-
-               key = new byte[25];
-               System.err.println("25x[i+1], 50xcd:");
-               for(int i = 0; i < key.length; i++)
-                       key[i] = (byte) (i + 1);
-               for(int i = 0; i < text.length; i++)
-                       text[i] = (byte) 0xcd;
-               mv = s.mac(key, text, 20);
-               System.out.println(HexUtil.bytesToHex(mv, 0, mv.length));
-
-               key = new byte[20];
-               System.err.println("20x0c, 'Test With Truncation':");
-               for(int i = 0; i < key.length; i++)
-                       key[i] = (byte) 0x0c;
-               text = "Test With Truncation".getBytes("UTF-8");
-               mv = s.mac(key, text, 20);
-               System.out.println(HexUtil.bytesToHex(mv, 0, mv.length));
-               mv = s.mac(key, text, 12);
-               System.out.println(HexUtil.bytesToHex(mv, 0, mv.length));
-
-       }
-
-       public static byte[] macWithSHA256(byte[] K, byte[] text, int macbytes) 
{
-               MessageDigest sha256 = null;
-               try {
-                       sha256 = SHA256.getMessageDigest();
-                       HMAC hash = new HMAC(sha256);
-                       return hash.mac(K, text, macbytes);
-               } finally {
-                       if(sha256 != null)
-                               SHA256.returnMessageDigest(sha256);
-               }
-       }
-
-       public static boolean verifyWithSHA256(byte[] K, byte[] text, byte[] 
mac) {
-               MessageDigest sha256 = null;
-               try {
-                       sha256 = SHA256.getMessageDigest();
-                       HMAC hash = new HMAC(sha256);
-                       return hash.verify(K, text, mac);
-               } finally {
-                       if(sha256 != null)
-                               SHA256.returnMessageDigest(sha256);
-               }
-       }
-}      
+    public static boolean verify(ALGORITHM algo, SecretKey key, byte[] input, 
byte[] mac) throws InvalidKeyException {
+        return Arrays.equals(mac, mac(algo, key, input));
+    }
+}
\ No newline at end of file

Modified: trunk/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/FNPPacketMangler.java        2009-01-30 
18:13:09 UTC (rev 25405)
+++ trunk/freenet/src/freenet/node/FNPPacketMangler.java        2009-01-30 
18:35:33 UTC (rev 25406)
@@ -52,6 +52,9 @@
 import freenet.support.TimeUtil;
 import freenet.support.WouldBlockException;
 import freenet.support.io.NativeThread;
+import java.security.InvalidKeyException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
 
 /**
  * @author amphibian
@@ -129,7 +132,7 @@
        /** The size of the key used to authenticate the hmac */
        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];
+       private SecretKey transientKey;
        public static final int TRANSIENT_KEY_REKEYING_MIN_INTERVAL = 
30*60*1000;
         /** The rekeying interval for the session key (keytrackers) */
         public static final int SESSION_KEY_REKEYING_INTERVAL = 60*60*1000;
@@ -231,7 +234,7 @@
                        opn = null;
                }
                PeerNode pn;
-
+                try {
                if(opn != null) {
                        if(logMINOR) Logger.minor(this, "Trying exact match");
                        if(length > HEADERS_LENGTH_MINIMUM) {
@@ -249,7 +252,7 @@
                                if(tryProcessAuth(buf, offset, length, opn, 
peer, false, now)) return;
                                // Might be a reply to an anon auth packet
                                if(tryProcessAuthAnonReply(buf, offset, length, 
opn, peer, now)) return;
-                       }
+                       } 
                }
                PeerNode[] peers = crypto.getPeerNodes();
                // Existing connection, changed IP address?
@@ -306,7 +309,6 @@
                                }
                        }
                }
-               
                OpennetManager opennet = node.getOpennet();
                if(opennet != null) {
                        // Try old opennet connections.
@@ -322,6 +324,10 @@
                if(node.wantAnonAuth()) {
                        if(tryProcessAuthAnon(buf, offset, length, peer)) 
return;
                }
+                } catch (InvalidKeyException e) {
+                    Logger.error(this, "Huh! " + e.getMessage(), e);
+                    return;
+                }
                if(LOG_UNMATCHABLE_ERROR)
                        System.err.println("Unmatchable packet from "+peer+" on 
"+node.getDarknetPortNumber());
                Logger.normal(this,"Unmatchable packet from "+peer);
@@ -337,7 +343,7 @@
         * @param now The time at which the packet was received
         * @return True if we handled a negotiation packet, false otherwise.
         */
-       private boolean tryProcessAuth(byte[] buf, int offset, int length, 
PeerNode pn, Peer peer, boolean oldOpennetPeer, long now) {
+       private boolean tryProcessAuth(byte[] buf, int offset, int length, 
PeerNode pn, Peer peer, boolean oldOpennetPeer, long now) throws 
InvalidKeyException {
                BlockCipher authKey = pn.incomingSetupCipher;
                if(logMINOR) Logger.minor(this, "Decrypt key: 
"+HexUtil.bytesToHex(pn.incomingSetupKey)+" for "+peer+" : "+pn+" in 
tryProcessAuth");
                // Does the packet match IV E( H(data) data ) ?
@@ -406,7 +412,7 @@
         * @param now The time at which the packet was received
         * @return True if we handled a negotiation packet, false otherwise.
         */
-       private boolean tryProcessAuthAnon(byte[] buf, int offset, int length, 
Peer peer) {
+       private boolean tryProcessAuthAnon(byte[] buf, int offset, int length, 
Peer peer) throws InvalidKeyException {
                BlockCipher authKey = crypto.getAnonSetupCipher();
                // Does the packet match IV E( H(data) data ) ?
                PCFBMode pcfb = PCFBMode.create(authKey);
@@ -471,7 +477,7 @@
         * @param now The time at which the packet was received
         * @return True if we handled a negotiation packet, false otherwise.
         */
-       private boolean tryProcessAuthAnonReply(byte[] buf, int offset, int 
length, PeerNode pn, Peer peer, long now) {
+       private boolean tryProcessAuthAnonReply(byte[] buf, int offset, int 
length, PeerNode pn, Peer peer, long now) throws InvalidKeyException {
                BlockCipher authKey = pn.anonymousInitiatorSetupCipher;
                // Does the packet match IV E( H(data) data ) ?
                PCFBMode pcfb = PCFBMode.create(authKey);
@@ -533,7 +539,7 @@
         * @param payload The decrypted payload of the packet.
         * @param replyTo The address the packet came in from.
         */
-       private void processDecryptedAuthAnon(byte[] payload, Peer replyTo) {
+       private void processDecryptedAuthAnon(byte[] payload, Peer replyTo) 
throws InvalidKeyException {
                if(logMINOR) Logger.minor(this, "Processing decrypted auth 
packet from "+replyTo+" length "+payload.length);
                
                /** Protocol version. Should be 1. */
@@ -583,7 +589,7 @@
                }
        }
 
-       private void processDecryptedAuthAnonReply(byte[] payload, Peer 
replyTo, PeerNode pn) {
+       private void processDecryptedAuthAnonReply(byte[] payload, Peer 
replyTo, PeerNode pn) throws InvalidKeyException {
                if(logMINOR) Logger.minor(this, "Processing decrypted auth 
packet from "+replyTo+" for "+pn+" length "+payload.length);
                
                /** Protocol version. Should be 1. */
@@ -634,7 +640,7 @@
         * Process a decrypted, authenticated auth packet.
         * @param payload The packet payload, after it has been decrypted.
         */
-       private void processDecryptedAuth(byte[] payload, PeerNode pn, Peer 
replyTo, boolean oldOpennetPeer) {
+       private void processDecryptedAuth(byte[] payload, PeerNode pn, Peer 
replyTo, boolean oldOpennetPeer) throws InvalidKeyException {
                if(logMINOR) Logger.minor(this, "Processing decrypted auth 
packet from "+replyTo+" for "+pn);
                if(pn.isDisabled()) {
                        if(logMINOR) Logger.minor(this, "Won't connect to a 
disabled peer ("+pn+ ')');
@@ -759,7 +765,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, int setupType, int negType)
+       private void processJFKMessage1(byte[] payload,int offset,PeerNode 
pn,Peer replyTo, boolean unknownInitiator, int setupType, int negType) throws 
InvalidKeyException
        {
                long t1=System.currentTimeMillis();
                if(logMINOR) Logger.minor(this, "Got a JFK(1) message, 
processing it - "+pn);
@@ -854,7 +860,7 @@
         * @param pn The node to encrypt the message for. CAN BE NULL if 
anonymous-initiator.
         * @param replyTo The peer to send the packet to.
         */
-       private void sendJFKMessage2(byte[] nonceInitator, byte[] 
hisExponential, PeerNode pn, Peer replyTo, boolean unknownInitiator, int 
setupType, int negType) {
+       private void sendJFKMessage2(byte[] nonceInitator, byte[] 
hisExponential, PeerNode pn, Peer replyTo, boolean unknownInitiator, int 
setupType, int negType) throws InvalidKeyException {
                if(logMINOR) Logger.minor(this, "Sending a JFK(2) message to 
"+pn);
                DiffieHellmanLightContext ctx = getLightDiffieHellmanContext();
                // g^r
@@ -864,7 +870,7 @@
                node.random.nextBytes(myNonce);
                byte[] r = 
ctx.signature.getRBytes(Node.SIGNATURE_PARAMETER_LENGTH);
                byte[] s = 
ctx.signature.getSBytes(Node.SIGNATURE_PARAMETER_LENGTH);
-               byte[] authenticator = 
HMAC.macWithSHA256(getTransientKey(),assembleJFKAuthenticator(myExponential, 
hisExponential, myNonce, nonceInitator, replyTo.getAddress().getAddress()), 
HASH_LENGTH);
+                byte[] authenticator = HMAC.mac(HMAC.ALGORITHM.HmacSHA256, 
getTransientKey(), assembleJFKAuthenticator(myExponential, hisExponential, 
myNonce, nonceInitator, replyTo.getAddress().getAddress()));
                if(logMINOR) Logger.minor(this, "We are using the following 
HMAC : " + HexUtil.bytesToHex(authenticator));
 
                byte[] message2 = new 
byte[NONCE_SIZE*2+DiffieHellman.modulusLengthInBytes()+
@@ -926,7 +932,7 @@
         * @param pn The peerNode we are talking to. Cannot be null as we are 
the initiator.
         */
 
-       private void processJFKMessage2(byte[] payload,int inputOffset,PeerNode 
pn,Peer replyTo, boolean unknownInitiator, int setupType, int negType)
+       private void processJFKMessage2(byte[] payload,int inputOffset,PeerNode 
pn,Peer replyTo, boolean unknownInitiator, int setupType, int negType) throws 
InvalidKeyException
        {
                long t1=System.currentTimeMillis();
                if(logMINOR) Logger.minor(this, "Got a JFK(2) message, 
processing it - "+pn.getPeer());
@@ -1038,7 +1044,7 @@
         * responder.
         * @return byte Message3
         */
-       private void processJFKMessage3(byte[] payload, int inputOffset, 
PeerNode pn,Peer replyTo, boolean oldOpennetPeer, boolean unknownInitiator, int 
setupType, int negType)
+       private void processJFKMessage3(byte[] payload, int inputOffset, 
PeerNode pn,Peer replyTo, boolean oldOpennetPeer, boolean unknownInitiator, int 
setupType, int negType) throws InvalidKeyException
        {
                final long t1 = System.currentTimeMillis();
                if(logMINOR) Logger.minor(this, "Got a JFK(3) message, 
processing it - "+pn);
@@ -1085,7 +1091,7 @@
 
                // We *WANT* to check the hmac before we do the lookup on the 
hashmap
                // @see https://bugs.freenetproject.org/view.php?id=1604
-               if(!HMAC.verifyWithSHA256(getTransientKey(), 
assembleJFKAuthenticator(responderExponential, initiatorExponential, 
nonceResponder, nonceInitiator, replyTo.getAddress().getAddress()) , 
authenticator)) {
+               if(!HMAC.verify(HMAC.ALGORITHM.HmacSHA256, getTransientKey(), 
assembleJFKAuthenticator(responderExponential, initiatorExponential, 
nonceResponder, nonceInitiator, replyTo.getAddress().getAddress()) , 
authenticator)) {
                        if(shouldLogErrorInHandshake(t1))
                                Logger.normal(this, "The HMAC doesn't match; 
let's discard the packet (either we rekeyed or we are victim of forgery) - JFK3 
- "+pn);
                        return;
@@ -1123,10 +1129,10 @@
                        return;
                }
                BigInteger computedExponential = 
ctx.getHMACKey(_hisExponential, Global.DHgroupA);
-               byte[] Ks = computeJFKSharedKey(computedExponential, 
nonceInitiator, nonceResponder, "0");
-               byte[] Ke = computeJFKSharedKey(computedExponential, 
nonceInitiator, nonceResponder, "1");
-               byte[] Ka = computeJFKSharedKey(computedExponential, 
nonceInitiator, nonceResponder, "2");
-               c.initialize(Ke);
+               SecretKey Ks = computeJFKSharedKey(computedExponential, 
nonceInitiator, nonceResponder, "0");
+               SecretKey Ke = computeJFKSharedKey(computedExponential, 
nonceInitiator, nonceResponder, "1");
+               SecretKey Ka = computeJFKSharedKey(computedExponential, 
nonceInitiator, nonceResponder, "2");
+               c.initialize(Ke.getEncoded());
                final PCFBMode pk = PCFBMode.create(c);
                int ivLength = pk.lengthIV();
                int decypheredPayloadOffset = 0;
@@ -1135,7 +1141,7 @@
                System.arraycopy(JFK_PREFIX_INITIATOR, 0, decypheredPayload, 
decypheredPayloadOffset, JFK_PREFIX_INITIATOR.length);
                decypheredPayloadOffset += JFK_PREFIX_INITIATOR.length;
                System.arraycopy(payload, inputOffset, decypheredPayload, 
decypheredPayloadOffset, decypheredPayload.length-decypheredPayloadOffset);
-               if(!HMAC.verifyWithSHA256(Ka, decypheredPayload, hmac)) {
+               if(!HMAC.verify(HMAC.ALGORITHM.HmacSHA256 ,Ka, 
decypheredPayload, hmac)) {
                        Logger.error(this, "The inner-HMAC doesn't match; let's 
discard the packet JFK(3) - "+pn);
                        return;
                }
@@ -1197,7 +1203,7 @@
                
                BlockCipher cs = null;
                try { cs = new Rijndael(256, 256); } catch 
(UnsupportedCipherException e) {}
-               cs.initialize(Ks);
+               cs.initialize(Ks.getEncoded());
                
                // Promote if necessary
                boolean dontWant = false;
@@ -1292,7 +1298,7 @@
         * @param pn The PeerNode we are talking to. Cannot be null as we are 
the initiator.
         * @param replyTo The Peer we are replying to.
         */
-       private boolean processJFKMessage4(byte[] payload, int inputOffset, 
PeerNode pn, Peer replyTo, boolean oldOpennetPeer, boolean unknownInitiator, 
int setupType, int negType)
+       private boolean processJFKMessage4(byte[] payload, int inputOffset, 
PeerNode pn, Peer replyTo, boolean oldOpennetPeer, boolean unknownInitiator, 
int setupType, int negType) throws InvalidKeyException
        {
                final long t1 = System.currentTimeMillis();
                if(logMINOR) Logger.minor(this, "Got a JFK(4) message, 
processing it - "+pn.getPeer());
@@ -1328,7 +1334,7 @@
                System.arraycopy(payload, inputOffset, hmac, 0, HASH_LENGTH);
                inputOffset += HASH_LENGTH;
                
-               c.initialize(pn.jfkKe);
+               c.initialize(pn.jfkKe.getEncoded());
                final PCFBMode pk = PCFBMode.create(c);
                int ivLength = pk.lengthIV();
                int decypheredPayloadOffset = 0;
@@ -1337,7 +1343,7 @@
                System.arraycopy(JFK_PREFIX_RESPONDER, 0, decypheredPayload, 
decypheredPayloadOffset, JFK_PREFIX_RESPONDER.length);
                decypheredPayloadOffset += JFK_PREFIX_RESPONDER.length;
                System.arraycopy(payload, inputOffset, decypheredPayload, 
decypheredPayloadOffset, payload.length-inputOffset);
-               if(!HMAC.verifyWithSHA256(pn.jfkKa, decypheredPayload, hmac)) {
+               if(!HMAC.verify(HMAC.ALGORITHM.HmacSHA256, pn.jfkKa, 
decypheredPayload, hmac)) {
                        Logger.normal(this, "The digest-HMAC doesn't match; 
let's discard the packet - "+pn.getPeer());
                        return false;
                }
@@ -1436,7 +1442,7 @@
                }
                
                // We change the key
-               c.initialize(pn.jfkKs);
+               c.initialize(pn.jfkKs.getEncoded());
                if(pn.completedHandshake(bootID, hisRef, 0, hisRef.length, c, 
pn.jfkKs, replyTo, false, negType, trackerID, true, reusedTracker) >= 0) {
                        if(dontWant)
                                node.peers.disconnect(pn, true, true, true);
@@ -1478,7 +1484,7 @@
         * @param replyTo The Peer to send the packet to.
         */
 
-       private void sendJFKMessage3(int version,final int negType,int 
phase,byte[] nonceInitiator,byte[] nonceResponder,byte[] hisExponential, byte[] 
authenticator, final PeerNode pn, final Peer replyTo, final boolean 
unknownInitiator, final int setupType)
+       private void sendJFKMessage3(int version,final int negType,int 
phase,byte[] nonceInitiator,byte[] nonceResponder,byte[] hisExponential, byte[] 
authenticator, final PeerNode pn, final Peer replyTo, final boolean 
unknownInitiator, final int setupType) throws InvalidKeyException
        {
                if(logMINOR) Logger.minor(this, "Sending a JFK(3) message to 
"+pn.getPeer());
                long t1=System.currentTimeMillis();
@@ -1543,7 +1549,7 @@
                pn.jfkKs = computeJFKSharedKey(computedExponential, 
nonceInitiator, nonceResponder, "0");
                pn.jfkKe = computeJFKSharedKey(computedExponential, 
nonceInitiator, nonceResponder, "1");
                pn.jfkKa = computeJFKSharedKey(computedExponential, 
nonceInitiator, nonceResponder, "2");
-               c.initialize(pn.jfkKe);
+               c.initialize(pn.jfkKe.getEncoded());
                PCFBMode pcfb = PCFBMode.create(c);
                int ivLength = pcfb.lengthIV();
                byte[] iv = new byte[ivLength];
@@ -1566,7 +1572,7 @@
                pcfb.blockEncipher(cleartext, cleartextToEncypherOffset, 
cleartext.length-cleartextToEncypherOffset);
                
                // We compute the HMAC of (prefix + cyphertext) Includes the IV!
-               byte[] hmac = HMAC.macWithSHA256(pn.jfkKa, cleartext, 
HASH_LENGTH);
+               byte[] hmac = HMAC.mac(HMAC.ALGORITHM.HmacSHA256, pn.jfkKa, 
cleartext);
                
                // copy stuffs back to the message
                System.arraycopy(hmac, 0, message3, offset, HASH_LENGTH);
@@ -1611,7 +1617,7 @@
         * @param pn The PeerNode to encrypt the auth packet to. Cannot be 
null, because even in anonymous initiator,
         * we will have created one before calling this method.
         */
-       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, long newTrackerID, boolean sameAsOldTrackerID)
+       private void sendJFKMessage4(int version,int negType,int phase,byte[] 
nonceInitiator,byte[] nonceResponder,byte[] initiatorExponential,byte[] 
responderExponential, BlockCipher c, SecretKey Ke, SecretKey Ka, byte[] 
authenticator, byte[] hisRef, PeerNode pn, Peer replyTo, boolean 
unknownInitiator, int setupType, long newTrackerID, boolean sameAsOldTrackerID) 
throws InvalidKeyException
        {
                if(logMINOR)
                        Logger.minor(this, "Sending a JFK(4) message to 
"+pn.getPeer());
@@ -1667,7 +1673,7 @@
                pk.blockEncipher(cyphertext, cleartextToEncypherOffset, 
cyphertext.length - cleartextToEncypherOffset);
                
                // We compute the HMAC of (prefix + iv + signature)
-               byte[] hmac = HMAC.macWithSHA256(Ka, cyphertext, HASH_LENGTH);
+               byte[] hmac = HMAC.mac(HMAC.ALGORITHM.HmacSHA256, Ka, 
cyphertext);
                
                // Message4 = hmac + IV + encryptedSignature
                byte[] message4 = new byte[HASH_LENGTH + ivLength + 
(cyphertext.length - cleartextToEncypherOffset)]; 
@@ -3032,13 +3038,13 @@
                return result;
        }
        
-       private byte[] getTransientKey() {
+       private SecretKey getTransientKey() {
                synchronized (authenticatorCache) {
                        return transientKey;
                }
        }
        
-       private byte[] computeJFKSharedKey(BigInteger exponential, byte[] nI, 
byte[] nR, String what) {
+       private SecretKey computeJFKSharedKey(BigInteger exponential, byte[] 
nI, byte[] nR, String what) throws InvalidKeyException {
                assert("0".equals(what) || "1".equals(what) || 
"2".equals(what));
                byte[] number = null;
                try {
@@ -3055,7 +3061,7 @@
                offset += NONCE_SIZE;
                System.arraycopy(number, 0, toHash, offset, number.length);
                
-               return HMAC.macWithSHA256(exponential.toByteArray(), toHash, 
HASH_LENGTH);
+               return new SecretKeySpec(HMAC.mac(HMAC.ALGORITHM.HmacSHA256, 
new SecretKeySpec(exponential.toByteArray(), "RAW"), toHash), "RAW");
        }
 
        private long timeLastReset = -1;
@@ -3080,7 +3086,10 @@
                        }
                        timeLastReset = now;
 
-                       node.random.nextBytes(transientKey);
+                        // FIXME: Use the KeyGenerator!
+                        byte[] trKey = new byte[TRANSIENT_KEY_SIZE];
+                       node.random.nextBytes(trKey);
+                        transientKey = new SecretKeySpec(trKey, "RAW");
                        
                        // reset the authenticator cache
                        authenticatorCache.clear();

Modified: trunk/freenet/src/freenet/node/FailureTable.java
===================================================================
--- trunk/freenet/src/freenet/node/FailureTable.java    2009-01-30 18:13:09 UTC 
(rev 25405)
+++ trunk/freenet/src/freenet/node/FailureTable.java    2009-01-30 18:35:33 UTC 
(rev 25406)
@@ -27,6 +27,8 @@
 import freenet.support.io.NativeThread;
 
 // FIXME it is ESSENTIAL that we delete the ULPR data on requestors etc once 
we have found the key.
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
 // Otherwise it will be much too easy to trace a request if an attacker busts 
the node afterwards.
 // We can use an HMAC or something to authenticate offers.
 
@@ -59,7 +61,7 @@
        /** Offers expire after 10 minutes */
        static final int OFFER_EXPIRY_TIME = 10*60*1000;
        /** HMAC key for the offer authenticator */
-       final byte[] offerAuthenticatorKey;
+       final SecretKey offerAuthenticatorKey;
        /** Clean up old data every 30 minutes to save memory and improve 
privacy */
        static final int CLEANUP_PERIOD = 30*60*1000;
        
@@ -70,8 +72,10 @@
                entriesByKey = new LRUHashtable<Key,FailureTableEntry>();
                blockOfferListByKey = new LRUHashtable<Key,BlockOfferList>();
                this.node = node;
-               offerAuthenticatorKey = new byte[32];
-               node.random.nextBytes(offerAuthenticatorKey);
+                // FIXME: use KeyGenerator!!
+               byte[] offerAuthenticatorKey2 = new byte[32];
+               node.random.nextBytes(offerAuthenticatorKey2);
+                offerAuthenticatorKey = new 
SecretKeySpec(offerAuthenticatorKey2, "RAW");
                logMINOR = Logger.shouldLog(Logger.MINOR, this);
                logDEBUG = Logger.shouldLog(Logger.DEBUG, this);
                offerExecutor = new SerialExecutor(NativeThread.HIGH_PRIORITY);

Modified: trunk/freenet/src/freenet/node/NodeDispatcher.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeDispatcher.java  2009-01-30 18:13:09 UTC 
(rev 25405)
+++ trunk/freenet/src/freenet/node/NodeDispatcher.java  2009-01-30 18:35:33 UTC 
(rev 25406)
@@ -21,6 +21,7 @@
 import freenet.support.Logger;
 import freenet.support.LogThresholdCallback;
 import freenet.support.ShortBuffer;
+import java.security.InvalidKeyException;
 
 /**
  * @author amphibian
@@ -258,7 +259,8 @@
                Key key = (Key) m.getObject(DMT.KEY);
                byte[] authenticator = ((ShortBuffer) 
m.getObject(DMT.OFFER_AUTHENTICATOR)).getData();
                long uid = m.getLong(DMT.UID);
-               
if(!HMAC.verifyWithSHA256(node.failureTable.offerAuthenticatorKey, 
key.getFullKey(), authenticator)) {
+                try{
+               if(!HMAC.verify(HMAC.ALGORITHM.HmacSHA256, 
node.failureTable.offerAuthenticatorKey, key.getFullKey(), authenticator)) {
                        Logger.error(this, "Invalid offer request from 
"+source+" : authenticator did not verify");
                        try {
                                
source.sendAsync(DMT.createFNPGetOfferedKeyInvalid(uid, 
DMT.GET_OFFERED_KEY_REJECTED_BAD_AUTHENTICATOR), null, 
node.failureTable.senderCounter);
@@ -267,6 +269,10 @@
                        }
                        return true;
                }
+                } catch (InvalidKeyException e) {
+                    Logger.error(this, e.getMessage(), e);
+                    return true;
+                }
                if(logMINOR) Logger.minor(this, "Valid GetOfferedKey for 
"+key+" from "+source);
                
                // Do we want it? We can RejectOverload if we don't have the 
bandwidth...

Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java        2009-01-30 18:13:09 UTC 
(rev 25405)
+++ trunk/freenet/src/freenet/node/PeerNode.java        2009-01-30 18:35:33 UTC 
(rev 25406)
@@ -72,6 +72,8 @@
 import freenet.support.math.TimeDecayingRunningAverage;
 import freenet.support.transport.ip.HostnameSyntaxException;
 import freenet.support.transport.ip.IPUtil;
+import java.security.InvalidKeyException;
+import javax.crypto.SecretKey;
 
 /**
  * @author amphibian
@@ -105,9 +107,9 @@
        private byte[] jfkBuffer;
        //TODO: sync ?
 
-       protected byte[] jfkKa;
-       protected byte[] jfkKe;
-       protected byte[] jfkKs;
+       protected SecretKey jfkKa;
+       protected SecretKey jfkKe;
+       protected SecretKey jfkKs;
        protected byte[] jfkMyRef;
        // The following is used only if we are the initiator
 
@@ -1836,7 +1838,7 @@
        * @return The ID of the new PacketTracker. If this is different to the 
passed-in trackerID, then
        * it's a new tracker. -1 to indicate failure.
        */
-       public long completedHandshake(long thisBootID, byte[] data, int 
offset, int length, BlockCipher encCipher, byte[] encKey, Peer replyTo, boolean 
unverified, int negType, long trackerID, boolean isJFK4, boolean jfk4SameAsOld) 
{
+       public long completedHandshake(long thisBootID, byte[] data, int 
offset, int length, BlockCipher encCipher, SecretKey encKey, Peer replyTo, 
boolean unverified, int negType, long trackerID, boolean isJFK4, boolean 
jfk4SameAsOld) {
                long now = System.currentTimeMillis();
                if(logMINOR) Logger.minor(this, "Tracker ID "+trackerID+" 
isJFK4="+isJFK4+" jfk4SameAsOld="+jfk4SameAsOld);
 
@@ -1966,7 +1968,7 @@
                        } else {
                                // else it's a rekey
                        }
-                       newTracker = new SessionKey(this, packets, encCipher, 
encKey);
+                       newTracker = new SessionKey(this, packets, encCipher, 
encKey.getEncoded());
                        if(logMINOR) Logger.minor(this, "New key tracker in 
completedHandshake: "+newTracker+" for "+packets+" for "+shortToString()+" neg 
type "+negType);
                        if(unverified) {
                                if(unverifiedTracker != null) {
@@ -3478,13 +3480,18 @@
        public void offer(Key key) {
                byte[] keyBytes = key.getFullKey();
                // FIXME maybe the authenticator should be shorter than 32 
bytes to save memory?
-               byte[] authenticator = 
HMAC.macWithSHA256(node.failureTable.offerAuthenticatorKey, keyBytes, 32);
-               Message msg = DMT.createFNPOfferKey(key, authenticator);
-               try {
-                       sendAsync(msg, null, node.nodeStats.sendOffersCtr);
-               } catch(NotConnectedException e) {
-               // Ignore
-               }
+               byte[] authenticator = null;
+                try {
+                     authenticator = HMAC.mac(HMAC.ALGORITHM.HmacSHA256, 
node.failureTable.offerAuthenticatorKey, keyBytes);
+                    Message msg = DMT.createFNPOfferKey(key, authenticator);
+                    try {
+                        sendAsync(msg, null, node.nodeStats.sendOffersCtr);
+                    } catch (NotConnectedException e) {
+                        // Ignore
+                    }
+                } catch (InvalidKeyException k) {
+                    Logger.error(this, "Invalid Key!", k);
+                }
        }
 
        public OutgoingPacketMangler getOutgoingMangler() {

_______________________________________________
cvs mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs

Reply via email to