Author: kryptos
Date: 2007-09-14 05:22:47 +0000 (Fri, 14 Sep 2007)
New Revision: 15154
Modified:
branches/freenet-jfk/src/freenet/node/FNPPacketMangler.java
Log:
JFK(4) generated: Address FIXME's in parsing and authentication
Modified: branches/freenet-jfk/src/freenet/node/FNPPacketMangler.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/FNPPacketMangler.java 2007-09-14
03:45:01 UTC (rev 15153)
+++ branches/freenet-jfk/src/freenet/node/FNPPacketMangler.java 2007-09-14
05:22:47 UTC (rev 15154)
@@ -414,7 +414,7 @@
* cached by the Responder.Receiving a
duplicate message simply causes
* the responder to Re-transmit the
corresponding message4
*/
- //ProcessMessage3(payload, pn, replyTo);
+ ProcessMessage3(payload, pn, replyTo);
}
else if(packetType==3){
/*
@@ -422,7 +422,7 @@
* using the same keys as in the previous
message.
* The signature is non-message recovering
*/
- //ProcessMessage4(payload,pn,replyTo);
+ ProcessMessage4(payload,pn,replyTo);
}
}
else {
@@ -762,10 +762,9 @@
return;
}
// cache the message
- // FIXME: Do we cache the entire payload?
authenticatorCache.put(authenticator,payload);
// Send reply
- sendMessage4Packet(1, 2, 3, nonceInitiator,
nonceResponder,initiatorExponential, responderExponential, pn, replyTo);
+ sendMessage4Packet(1, 2, 3, nonceInitiator,
nonceResponder,initiatorExponential, responderExponential,idI,c, pn, replyTo);
long t2=System.currentTimeMillis();
if((t2-t1)>500)
Logger.error(this,"Message1 timeout error:Sending
packet for"+pn.getPeer());
@@ -787,14 +786,13 @@
}
/*
- * Send Message3 packet
- * Also check for duplicate message
- * @param version
- * @param negType
- * @param The packet phase number
- * @param Concatenated data
- * @param The peerNode we are talking to
- * @param The peer to which we need to send the packet
+ * Format:
+ * Ni
+ * Nr
+ * g^i
+ * g^r
+ * Authenticator
+ * E[idI,S[Ni,Nr,g^i,g^r]] over the key Ka
*/
private void sendMessage3Packet(int version,int negType,int
phase,byte[] nonceInitiator,byte[] nonceResponder,byte[] hisExponential,
BigInteger hisGroup, byte[] hashedAuthenticator, PeerNode pn, Peer replyTo)
@@ -846,11 +844,12 @@
PCFBMode pk=PCFBMode.create(c);
byte[] iv=new byte[pk.lengthIV()];
node.random.nextBytes(iv);
- int encryptedDataLength = iv.length + r.length + s.length + 2;
+ byte[] idI = new byte[0];
+ int encryptedDataLength = iv.length + idI.length + r.length +
s.length + 2;
byte[] encryptedData = new byte[encryptedDataLength];
System.arraycopy(iv, 0, encryptedData, 0, iv.length);
int count = iv.length;
- byte[] idI = new byte[0];
+
System.arraycopy(idI,0, encryptedData,count,idI.length);
count += idI.length;
System.arraycopy(r, 0, encryptedData, count, r.length);
@@ -874,20 +873,67 @@
}
/*
- * Send Message4 packet
- * @param version
- * @param negType
- * @param The packet phase number
- * @param Concatenated data
- * @param The peerNode we are talking to
+ * Process Message4 packet
+ * @param Payload
+ * @param The peerNode we are talking to
* @param The peer to which we need to send the packet
*/
-
- private void sendMessage4Packet(int version,int negType,int
phase,byte[] nonceInitiator,byte[] nonceResponder,byte[] ourExponential,byte[]
hisExponential,PeerNode pn,Peer replyTo)
- {
-
+ private void ProcessMessage4( byte[] payload,PeerNode pn,Peer replyTo)
+ {
+ long t1 = System.currentTimeMillis();
+ if(logMINOR)
+ Logger.minor(this, "Got a JFK(4) message, processing it");
+ int inputOffset=3;
+ // Decrypt
+ BlockCipher c = pn.outgoingSetupCipher;
+ PCFBMode pk=PCFBMode.create(c);
+ int ivLength = pk.lengthIV();
+ pk.reset(payload,inputOffset);
+ // Decrypt the rest of the payload
+
pk.blockDecipher(payload,inputOffset,payload.length-inputOffset);
+ inputOffset += ivLength;
+ // Now verify signature
+ // FIXME: How do we verify the signature?
+ // FIXME: cache JFK(4)?
+ // FIXME: JFK handshake completion?
+ }
+ /*
+ * FOrmat:
+ * E[S[Ni,Nr,g^i,g^r,idI]]
+ */
+ private void sendMessage4Packet(int version,int negType,int
phase,byte[] nonceInitiator,byte[] nonceResponder,byte[] ourExponential,byte[]
hisExponential,byte[] idI, BlockCipher c ,PeerNode pn,Peer replyTo)
+ {
+ if(logMINOR)
+ Logger.minor(this, "Sending a JFK(4) message to "+pn);
+ long now = System.currentTimeMillis();
+ long delta = now - pn.lastSentPacketTime();
+ DiffieHellmanLightContext dhContext =
getLightDiffieHellmanContext();
+ BigInteger hisGroup = dhContext.group.p;
+ NativeBigInteger _ourExponential = new
NativeBigInteger(1,ourExponential);
+ NativeBigInteger _hisExponential = new
NativeBigInteger(1,hisExponential);
+ NativeBigInteger _hisGroup = new
NativeBigInteger(1,stripBigIntegerToNetworkFormat(hisGroup));
+ DSASignature localSignature =
signDHParams(nonceInitiator,nonceResponder,_ourExponential,_hisExponential,idI);
+ byte[] r =
localSignature.getRBytes(Node.SIGNATURE_PARAMETER_LENGTH);
+ byte[] s =
localSignature.getSBytes(Node.SIGNATURE_PARAMETER_LENGTH);
+ NativeBigInteger tempKey =
dhContext.getHMACKey(_hisExponential,_hisGroup);
+ byte[] eKey = tempKey.toByteArray();
+
c.initialize(encryptionKey.getEncKey(eKey,nonceInitiator,nonceResponder));
+ PCFBMode pk=PCFBMode.create(c);
+ byte[] iv=new byte[pk.lengthIV()];
+ node.random.nextBytes(iv);
+ int message4Length = iv.length + r.length + s.length + 2;
+ byte[] message4 = new byte[message4Length];
+ System.arraycopy(iv, 0, message4, 0, iv.length);
+ int count = iv.length;
+
+ System.arraycopy(r, 0, message4, count, r.length);
+ count += r.length;
+ System.arraycopy(s, 0, message4, count, s.length);
+ count += s.length;
+ pk.blockEncipher(message4, 0, message4Length);
+ // FIXME: How to get completed handshake?
}
/**
@@ -2166,6 +2212,21 @@
// Why is the hash returned?
return SHA256.digest(toSign);
}
+ /*
+ * Prepare params for signing in Message4
+ */
+ private byte[] assembleDHParams(byte[] nonceInitiator,byte[]
nonceResponder,BigInteger myExponential, BigInteger hisExponential, byte[] idI)
{
+ byte[] _myExponential =
stripBigIntegerToNetworkFormat(myExponential);
+ byte[] _hisExponential =
stripBigIntegerToNetworkFormat(hisExponential);
+ byte[] toSign = new byte[nonceInitiator.length +
nonceResponder.length + _myExponential.length + _hisExponential.length];
+ System.arraycopy(nonceInitiator,
0,toSign,0,nonceInitiator.length);
+ System.arraycopy(nonceResponder,0
,toSign,nonceInitiator.length,nonceResponder.length);
+ System.arraycopy(_myExponential, 0,
toSign,nonceInitiator.length+nonceResponder.length, _myExponential.length);
+ System.arraycopy(_hisExponential, 0, toSign,
nonceInitiator.length+nonceResponder.length+_myExponential.length,
_hisExponential.length);
+ System.arraycopy(idI, 0, toSign ,
nonceInitiator.length+nonceResponder.length+_myExponential.length+
_hisExponential.length,idI.length);
+
+ return SHA256.digest(toSign);
+ }
/*
* Actually sign the DH parameters for message2
*/
@@ -2178,7 +2239,12 @@
private DSASignature signDHParams(byte[] nonceInitiator,byte[]
nonceResponder,BigInteger myExponential, BigInteger hisExponential) {
return
crypto.sign(assembleDHParams(nonceInitiator,nonceResponder,myExponential,hisExponential));
}
-
+ /*
+ * Sign the params for message4
+ */
+ private DSASignature signDHParams(byte[] nonceInitiator,byte[]
nonceResponder,BigInteger myExponential, BigInteger hisExponential,byte[] idI) {
+ return
crypto.sign(assembleDHParams(nonceInitiator,nonceResponder,myExponential,hisExponential,idI));
+ }
private byte[] getTransientKey() {
synchronized (authenticatorCache) {
return transientKey;