Author: kryptos
Date: 2007-09-09 00:58:03 +0000 (Sun, 09 Sep 2007)
New Revision: 15078
Modified:
branches/freenet-jfk/src/freenet/node/FNPPacketMangler.java
Log:
Avoid some costly re computations
Modified: branches/freenet-jfk/src/freenet/node/FNPPacketMangler.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/FNPPacketMangler.java 2007-09-08
23:48:56 UTC (rev 15077)
+++ branches/freenet-jfk/src/freenet/node/FNPPacketMangler.java 2007-09-09
00:58:03 UTC (rev 15078)
@@ -41,10 +41,8 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
-import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
-import java.util.List;
/**
* @author amphibian
@@ -68,15 +66,15 @@
* Objects cached during JFK message exchange: Message3,Message4 and
authenticator
* The messages are cached in hashmaps because the message retrieval from
the cache
* can be performed in constant time( given the key)
- * For the authenticator we used a arrayList. This is a better option when
we just have
- * to insert into the end of the list and perform a simple 'get'. Usage of
a linkedList
- * could prove to be much slower due to the allocation time for each node
in the list.
+ * Usage of a linkedList could prove to be much slower due to the
allocation time
+ * for each node in the list.
*/
final Map message3Cache;
final Map message4Cache;
- final List authenticatorCache;
+ final Map authenticatorCache;
final eKey encryptionKey;
final DSAGroup g;
+ static DSAPrivateKey PKR,PKI;
final RandomSource r;
private static final int MAX_PACKETS_IN_FLIGHT = 256;
private static final int RANDOM_BYTES_LENGTH = 12;
@@ -114,7 +112,7 @@
myPacketDataSource = new EntropySource();
message3Cache = new HashMap();
message4Cache = new HashMap();
- authenticatorCache = new ArrayList();
+ authenticatorCache = new HashMap();
encryptionKey = new eKey();
g = Global.DSAgroupBigA;
r=node.random;
@@ -363,12 +361,16 @@
}
else if (negType==2){
/*
- * We implement Just Fast Keying key management protocol with
active identity protection for the initiator and no identity protection for the
responder
+ * We implement Just Fast Keying key management protocol with
active identity protection
+ * for the initiator and no identity protection for the
responder
* M1:
* This is a straightforward DiffieHellman exponential.
- * The Initiator Nonce serves two purposes;it allows the
initiator to use the same exponentials during different sessions while ensuring
that the resulting session key will be different,can be used to differentiate
between parallel sessions
+ * The Initiator Nonce serves two purposes;it allows the
initiator to use the same
+ * exponentials during different sessions while ensuring that
the resulting session
+ * key will be different,can be used to differentiate between
parallel sessions
* M2:
- * Responder replies with a signed copy of his own
exponential, a random nonce and an authenticator calculated from a transient
hash key private to the responder.
+ * Responder replies with a signed copy of his own
exponential, a random nonce and
+ * an authenticator which provides sufficient defense against
forgeries,replays
* We slightly deviate JFK here;we do not send any public key
information as specified in the JFK docs
* M3:
* Initiator echoes the data sent by the responder including
the authenticator.
@@ -386,20 +388,20 @@
* The Initiator Nonce serves two purposes;it allows the
initiator to use the same * exponentials during
different sessions while ensuring that the resulting *
session key will be different,can be used to differentiate between
* parallel sessions
*/
- ProcessMessage1(pn,replyTo,0);
+ ProcessMessage1(payload,pn,replyTo,0);
}
else if(packetType==1){
/*
* Responder replies with a signed copy of his own
exponential, a random
* nonce and an authenticator calculated from a transient
hash key private
- * to the responder. We slightly deviate JFK here;we do
not send any public
- * key information as specified in the JFK docs
+ * to the responder.
*/
- ProcessMessage2(pn,replyTo,1);
+ ProcessMessage2(payload,pn,replyTo,1);
}
else if(packetType==2){
- /* Initiator echoes the data sent by the responder.These
messages are
+ /*
+ * Initiator echoes the data sent by the responder.These
messages are
* cached by the Responder.Receiving a duplicate message
simply causes
* the responder to Re-transmit the corresponding
message4
*/
@@ -410,7 +412,7 @@
* Encrypted message of the signature on both nonces,
both exponentials
* using the same keys as in the previous message
*/
- ProcessMessage4(pn,replyTo,3);
+ ProcessMessage4(payload,pn,replyTo,3);
}
}
else {
@@ -484,13 +486,14 @@
* @param The peerNode we are talking to
* @param The peer to which we need to send the packet
*/
- private void ProcessMessage1(PeerNode pn,Peer replyTo,int phase)
+ private void ProcessMessage1(byte[] payload,PeerNode pn,Peer replyTo,int
phase)
{
long t1=System.currentTimeMillis();
-
- byte[] message1=new byte[iNonce().length + Gi(pn).length+1];
- System.arraycopy(iNonce(),0,message1,0,iNonce().length);
-
System.arraycopy(Gi(pn),0,message1,iNonce().length+1,Gi(pn).length);
+ byte[] Ni = iNonce();
+ byte[] DHExpi = Gi(pn);
+ byte[] message1=new byte[Ni.length + DHExpi.length+1];
+ System.arraycopy(Ni,0,message1,0,Ni.length);
+ System.arraycopy(DHExpi,0,message1,Ni.length+1,DHExpi.length);
//Send params:Version,negType,phase,data,peernode,peer
sendMessage1or2Packet(1,2,0,message1,pn,replyTo);
long t2=System.currentTimeMillis();
@@ -502,10 +505,13 @@
* Used by the responder to verify the authenticity of the received data
*/
private byte[] processMessageAuth(PeerNode pn){
- byte[] authData=new
byte[iNonce().length+rNonce().length+Gr(pn).length+1];
- System.arraycopy(iNonce(),0,authData,0,iNonce().length);
-
System.arraycopy(rNonce(),0,authData,iNonce().length+1,rNonce().length);
-
System.arraycopy(Gr(pn),0,authData,iNonce().length+rNonce().length+1,Gr(pn).length);
+ byte[] Ni = iNonce();
+ byte[] Nr = rNonce();
+ byte[] DHExpr = Gr(pn);
+ byte[] authData=new byte[Ni.length+Nr.length+DHExpr.length+1];
+ System.arraycopy(Ni,0,authData,0,Ni.length);
+ System.arraycopy(Nr,0,authData,Ni.length+1,Nr.length);
+
System.arraycopy(DHExpr,0,authData,Ni.length+Nr.length+1,DHExpr.length);
/*
* Calculate the Hash of the Concatenated data(Responder
exponentials, nonces)
* using a key that will be private to the responder
@@ -527,31 +533,42 @@
* @param The peerNode we are talking to
*/
- private void ProcessMessage2(PeerNode pn,Peer replyTo,int phase)
+ private void ProcessMessage2(byte[] payload,PeerNode pn,Peer replyTo,int
phase)
{
long t1=System.currentTimeMillis();
- byte[] signData=new byte[Gr(pn).length+1];
+ byte[] Ni = iNonce();
+ byte[] Nr = rNonce();
+ byte[] DHExpr = Gr(pn);
+ byte[] authData=new byte[Ni.length+Nr.length+DHExpr.length+1];
+ System.arraycopy(Ni,0,authData,0,Ni.length);
+ System.arraycopy(Nr,0,authData,Ni.length+1,Nr.length);
+
System.arraycopy(DHExpr,0,authData,Ni.length+Nr.length+1,DHExpr.length);
+ byte[] signData=new byte[DHExpr.length+1];
+ System.arraycopy(DHExpr,0,signData,0,DHExpr.length);
//Compute the Signature:DSA
- DSASignature sig = crypto.sign(signData);
- byte[] r = sig.getRBytes(Node.SIGNATURE_PARAMETER_LENGTH);
+ PKR=new DSAPrivateKey(g, r);
+ //Params: Data,DSAGroup,DSAPrivateKey,randomSource
+ DSASignature sig = crypto.sign(signData,g,PKR,r);
+ byte[] r = sig.getRBytes(Node.SIGNATURE_PARAMETER_LENGTH);
byte[] s = sig.getSBytes(Node.SIGNATURE_PARAMETER_LENGTH);
Logger.minor(this, "
r="+HexUtil.bytesToHex(sig.getR().toByteArray())+"
s="+HexUtil.bytesToHex(sig.getS().toByteArray()));
if(r.length > 255 || s.length > 255)
throw new IllegalStateException("R or S is too long:
r.length="+r.length+" s.length="+s.length);
//Data sent in the clear
- byte[] unVerifiedData=new
byte[iNonce().length+rNonce().length+Gr(pn).length+1];
- System.arraycopy(iNonce(),0,unVerifiedData,0,iNonce().length);
-
System.arraycopy(rNonce(),0,unVerifiedData,iNonce().length+1,rNonce().length);
-
System.arraycopy(Gr(pn),0,unVerifiedData,iNonce().length+rNonce().length+1,Gr(pn).length);
+ byte[] unVerifiedData=new
byte[Ni.length+Nr.length+DHExpr.length+1];
+ System.arraycopy(Ni,0,unVerifiedData,0,Ni.length);
+ System.arraycopy(Nr,0,unVerifiedData,Ni.length+1,Nr.length);
+
System.arraycopy(DHExpr,0,unVerifiedData,Ni.length+Nr.length+1,DHExpr.length);
/*
* Compute the authenticator
* Used by the responder in Message4 to verify the
authenticity of the message
+ * The same authenticator is used in Message3 and identified
using the DSAPrivateKey
*/
HKrGenerator trKey=new HKrGenerator(node);
byte[] hkr=trKey.getNewHKr();
HMAC hash=new HMAC(SHA1.getInstance());
- byte[] authenticator =
hash.mac(hkr,processMessageAuth(pn),hkr.length);
- authenticatorCache.add(authenticator);
+ byte[] authenticator = hash.mac(hkr,authData,hkr.length);
+ authenticatorCache.put(PKR,authenticator);
byte[] Message2=new
byte[authenticator.length+unVerifiedData.length+s.length+r.length+1];
byte[] signedData=new byte[s.length+r.length];
System.arraycopy(signedData,0,Message2,0,signedData.length);
@@ -586,7 +603,7 @@
try{
// Intrinsic lock provided by the object authenticatorCache
synchronized(authenticatorCache){
- authenticator =
getBytes(authenticatorCache.get(authenticatorCache.size()));
+ authenticator = getBytes(authenticatorCache.get(PKR));
}
}
catch(IOException e){
@@ -597,8 +614,9 @@
System.arraycopy(rNonce(),0,unVerifiedData,iNonce().length+1,rNonce().length);
System.arraycopy(Gi(pn),0,unVerifiedData,iNonce().length+rNonce().length+1,Gi(pn).length);
System.arraycopy(Gr(pn),0,unVerifiedData,iNonce().length+rNonce().length+Gi(pn).length+1,Gr(pn).length);
- DSAPrivateKey pkMessage3=new DSAPrivateKey(g, r);
- DSASignature sig = crypto.sign(unVerifiedData,g,pkMessage3,r);
+ PKI=new DSAPrivateKey(g, r);
+ //Params: Data,DSAGroup,DSAPrivateKey,randomSource
+ DSASignature sig = crypto.sign(unVerifiedData,g,PKI,r);
byte[] r = sig.getRBytes(Node.SIGNATURE_PARAMETER_LENGTH);
byte[] s = sig.getSBytes(Node.SIGNATURE_PARAMETER_LENGTH);
Logger.minor(this, "
r="+HexUtil.bytesToHex(sig.getR().toByteArray())+"
s="+HexUtil.bytesToHex(sig.getS().toByteArray()));
@@ -666,7 +684,7 @@
* @param The peerNode we are talking to
*/
- private void ProcessMessage4(PeerNode pn,Peer replyTo,int phase)
+ private void ProcessMessage4(byte[] payload,PeerNode pn,Peer replyTo,int
phase)
{
long t1=System.currentTimeMillis();
@@ -675,8 +693,7 @@
System.arraycopy(rNonce(),0,unVerifiedData,iNonce().length+1,rNonce().length);
System.arraycopy(Gi(pn),0,unVerifiedData,iNonce().length+rNonce().length+1,Gi(pn).length);
System.arraycopy(Gr(pn),0,unVerifiedData,iNonce().length+rNonce().length+Gi(pn).length+1,Gr(pn).length);
- DSAPrivateKey pkMessage4=new DSAPrivateKey(g, r);
- DSASignature sig = crypto.sign(unVerifiedData,g,pkMessage4,r);
+ DSASignature sig = crypto.sign(unVerifiedData,g,PKR,r);
byte[] r = sig.getRBytes(Node.SIGNATURE_PARAMETER_LENGTH);
byte[] s = sig.getSBytes(Node.SIGNATURE_PARAMETER_LENGTH);
Logger.minor(this, "
r="+HexUtil.bytesToHex(sig.getR().toByteArray())+"
s="+HexUtil.bytesToHex(sig.getS().toByteArray()));