Author: nextgens
Date: 2007-12-01 15:55:19 +0000 (Sat, 01 Dec 2007)
New Revision: 16184
Removed:
trunk/freenet/src/freenet/crypt/DiffieHellmanContext.java
Modified:
trunk/freenet/src/freenet/crypt/DiffieHellman.java
trunk/freenet/src/freenet/node/FNPPacketMangler.java
Log:
deprecate StS : remove all the related code
Modified: trunk/freenet/src/freenet/crypt/DiffieHellman.java
===================================================================
--- trunk/freenet/src/freenet/crypt/DiffieHellman.java 2007-12-01 15:25:47 UTC
(rev 16183)
+++ trunk/freenet/src/freenet/crypt/DiffieHellman.java 2007-12-01 15:55:19 UTC
(rev 16184)
@@ -103,18 +103,6 @@
}
/**
- * Create a DiffieHellmanContext. This will include this side's DH
params.
- */
- public static DiffieHellmanContext generateContext() {
- long time1 = System.currentTimeMillis();
- NativeBigInteger[] params = getParams();
- long time2 = System.currentTimeMillis();
- if((time2 - time1) > 300) {
- Logger.error(null, "DiffieHellman.generateContext():
time2 is more than 300ms after time1 ("+(time2 - time1)+ ')');
- }
- return new DiffieHellmanContext(params[0], params[1], group);
- }
- /**
* Create a DiffieHellmanLightContext.
*/
public static DiffieHellmanLightContext generateLightContext() {
Deleted: trunk/freenet/src/freenet/crypt/DiffieHellmanContext.java
===================================================================
--- trunk/freenet/src/freenet/crypt/DiffieHellmanContext.java 2007-12-01
15:25:47 UTC (rev 16183)
+++ trunk/freenet/src/freenet/crypt/DiffieHellmanContext.java 2007-12-01
15:55:19 UTC (rev 16184)
@@ -1,106 +0,0 @@
-/* This code is part of Freenet. It is distributed under the GNU General
- * Public License, version 2 (or at your option any later version). See
- * http://www.gnu.org/ for further details of the GPL. */
-
-package freenet.crypt;
-
-import freenet.crypt.ciphers.Rijndael;
-import net.i2p.util.NativeBigInteger;
-import freenet.support.HexUtil;
-import freenet.support.Logger;
-
-public class DiffieHellmanContext extends KeyAgreementSchemeContext {
-
- // Set on startup
- /** My exponent. We keep this and then raise our peer's exponential to
this power. */
- final NativeBigInteger myExponent;
- /** My exponential. This is group.g ^ myExponent mod group.p */
- final NativeBigInteger myExponential;
- /** The group we both share */
- final DHGroup group;
-
- BlockCipher cipher;
- byte[] key;
-
- // Generated or set later
- NativeBigInteger peerExponential;
-
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append(super.toString());
- sb.append(": myExponent=");
- sb.append(myExponent.toHexString());
- sb.append(", myExponential=");
- sb.append(myExponential.toHexString());
- if(peerExponential != null) {
- sb.append(", peerExponential=");
- sb.append(peerExponential.toHexString());
- }
- return sb.toString();
- }
-
- public DiffieHellmanContext(NativeBigInteger myExponent, NativeBigInteger
myExponential, DHGroup group) {
- this.myExponent = myExponent;
- this.myExponential = myExponential;
- this.group = group;
- lastUsedTime = System.currentTimeMillis();
- logMINOR = Logger.shouldLog(Logger.MINOR, this);
- }
-
- public synchronized NativeBigInteger getOurExponential() {
- lastUsedTime = System.currentTimeMillis();
- return myExponential;
- }
-
- public synchronized byte[] getKey() {
- lastUsedTime = System.currentTimeMillis();
- if(key != null) return key;
-
- // Calculate key
- if(logMINOR)
- Logger.minor(this, "My exponent: "+myExponent.toHexString()+", my
exponential: "+myExponential.toHexString()+", peer's exponential:
"+peerExponential.toHexString());
- NativeBigInteger sharedSecret =
- (NativeBigInteger) peerExponential.modPow(myExponent,
group.getP());
-
- key = SHA256.digest(sharedSecret.toByteArray());
- if(logMINOR)
- Logger.minor(this, "Key="+HexUtil.bytesToHex(key));
- return key;
- }
-
- public synchronized void setOtherSideExponential(NativeBigInteger a) {
- lastUsedTime = System.currentTimeMillis();
- if(peerExponential != null) {
- if(!peerExponential.equals(a))
- throw new IllegalStateException("Assigned other side
exponential twice");
- else return;
- }
- if(a == null) throw new NullPointerException();
- peerExponential = a;
- }
-
- /**
- * @return True if getCipher() will work. If this returns false,
getCipher() will
- * probably NPE.
- */
- public boolean canGetCipher() {
- return peerExponential != null;
- }
-
- public NativeBigInteger getHisExponential() {
- return peerExponential;
- }
-
- public synchronized BlockCipher getCipher() {
- lastUsedTime = System.currentTimeMillis();
- if(cipher != null) return cipher;
- getKey();
- try {
- cipher = new Rijndael(256, 256);
- } catch (UnsupportedCipherException e1) {
- throw new Error(e1);
- }
- cipher.initialize(key);
- return cipher;
- }
-}
Modified: trunk/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/FNPPacketMangler.java 2007-12-01
15:25:47 UTC (rev 16183)
+++ trunk/freenet/src/freenet/node/FNPPacketMangler.java 2007-12-01
15:55:19 UTC (rev 16184)
@@ -17,7 +17,6 @@
import freenet.crypt.DSAGroup;
import freenet.crypt.DSASignature;
import freenet.crypt.DiffieHellman;
-import freenet.crypt.DiffieHellmanContext;
import freenet.crypt.DiffieHellmanLightContext;
import freenet.crypt.EntropySource;
import freenet.crypt.Global;
@@ -362,66 +361,11 @@
if(negType == 0) {
Logger.error(this, "Old ephemeral Diffie-Hellman
(negType 0) not supported.");
return;
- }else if (negType == 1) {
- // Four stage Diffie-Hellman. 0 = ephemeral, 1 =
payload stages are signed (not quite STS)
- // FIXME reduce to 3 stages and implement STS properly
(we have a separate validation mechanism in PeerNode)
- // AFAICS this (with negType=1) is equivalent in
security to STS; it expands the second phase into a second and a fourth phase.
- // A -> B g^x
- // B -> A g^y
- // A -> B E^k ( ... )
- // B -> A E^k ( ... )
-
- if((packetType < 0) || (packetType > 3)) {
- Logger.error(this, "Decrypted auth packet but
unknown packet type "+packetType+" from "+replyTo+" possibly from "+pn);
- return;
- }
-
- // We keep one DiffieHellmanContext per node ONLY
+ } else if (negType == 1) {
+ Logger.error(this, "Old StationToStation (negType 1)
not supported.");
+ return;
+ } else if (negType==2){
/*
- * Now, to the real meat
- * Alice, Bob share a base, g, and a modulus, p
- * Alice generates a random number r, and: 1: Alice ->
Bob: a=g^r
- * Bob receives this and generates his own random
number, s, and: 2: Bob -> Alice: b=g^s
- * Alice receives this, calculates K = b^r, and: 3:
Alice -> Bob: E_K ( H(data) data )
- * where data = [ Alice's startup number ]
- * Bob does exactly the same as Alice for packet 4.
- *
- * At this point we are done.
- */
- if(packetType == 0) {
- // We are Bob
- // We need to:
- // - Record Alice's a
- // - Generate our own s and b
- // - Send a type 1 packet back to Alice
containing this
-
- DiffieHellmanContext ctx =
- processDHZeroOrOne(0, payload, pn);
- if(ctx == null) return;
- // Send reply
- sendFirstHalfDHPacket(1, negType,
ctx.getOurExponential(), pn, replyTo);
- // Send a type 1, they will reply with a type 2
- } else if(packetType == 1) {
- // We are Alice
- DiffieHellmanContext ctx =
- processDHZeroOrOne(1, payload, pn);
- if(ctx == null) return;
- sendSignedDHCompletion(2, ctx.getCipher(), pn,
replyTo, ctx);
- // Send a type 2
- } else if(packetType == 2) {
- // We are Bob
- // Receiving a completion packet
- // Verify the packet, then complete
- // Format: IV E_K ( H(data) data )
- // Where data = [ long: bob's startup number ]
- processSignedDHTwoOrThree(2, payload, pn,
replyTo, true, oldOpennetPeer);
- } else if(packetType == 3) {
- // We are Alice
- processSignedDHTwoOrThree(3, payload, pn,
replyTo, false, oldOpennetPeer);
- }
- }
- 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
* M1:
@@ -478,8 +422,7 @@
*/
processJFKMessage4(payload, pn, replyTo,
oldOpennetPeer);
}
- }
- else {
+ } else {
Logger.error(this, "Decrypted auth packet but unknown
negotiation type "+negType+" from "+replyTo+" possibly from "+pn);
return;
}
@@ -1225,89 +1168,6 @@
}
/**
- * Send a signed DH completion message.
- * Format:
- * IV
- * Signature on { My exponential, his exponential, data }
- * Data
- * @param phase The packet phase number. Either 2 or 3.
- * @param cipher The negotiated cipher.
- * @param pn The PeerNode which we are talking to.
- * @param replyTo The Peer to which to send the packet (not necessarily
the same
- * as the one on pn as the IP may have changed).
- */
- private void sendSignedDHCompletion(int phase, BlockCipher cipher,
PeerNode pn, Peer replyTo, DiffieHellmanContext ctx) {
- PCFBMode pcfb = PCFBMode.create(cipher);
- byte[] iv = new byte[pcfb.lengthIV()];
-
- byte[] myRef = crypto.myCompressedSetupRef();
- byte[] data = new byte[myRef.length + 8];
- System.arraycopy(Fields.longToBytes(node.bootID), 0, data, 0,
8);
- System.arraycopy(myRef, 0, data, 8, myRef.length);
- byte[] myExp = ctx.getOurExponential().toByteArray();
- byte[] hisExp = ctx.getHisExponential().toByteArray();
-
- MessageDigest md = SHA256.getMessageDigest();
- md.update(myExp);
- md.update(hisExp);
- md.update(data);
- byte[] hash = md.digest();
-
- DSASignature sig = crypto.sign(hash);
-
- byte[] r = sig.getRBytes(Node.SIGNATURE_PARAMETER_LENGTH);
- byte[] s = sig.getSBytes(Node.SIGNATURE_PARAMETER_LENGTH);
-
- Logger.minor(this, "Sending DH completion: "+pn+" hash
"+HexUtil.bytesToHex(hash)+" r="+HexUtil.bytesToHex(sig.getR().toByteArray())+"
s="+HexUtil.bytesToHex(sig.getS().toByteArray()));
-
- int outputLength = iv.length + data.length + r.length +
s.length + 2;
-
- byte[] output = new byte[outputLength];
-
- System.arraycopy(iv, 0, output, 0, iv.length);
- int count = iv.length;
- if(r.length > 255 || s.length > 255)
- throw new IllegalStateException("R or S is too long:
r.length="+r.length+" s.length="+s.length);
- output[count++] = (byte) r.length;
- System.arraycopy(r, 0, output, count, r.length);
- count += r.length;
- output[count++] = (byte) s.length;
- System.arraycopy(s, 0, output, count, s.length);
- count += s.length;
- System.arraycopy(data, 0, output, count, data.length);
-
- pcfb.blockEncipher(output, 0, output.length);
-
- sendAuthPacket(1, 1, phase, output, pn, replyTo);
- }
-
- /**
- * Send a first-half (phase 0 or 1) DH negotiation packet to the node.
- * @param phase The phase of the message to be sent (0 or 1).
- * @param negType The negotiation type.
- * @param integer Our exponential
- * @param replyTo The peer to reply to
- */
- private void sendFirstHalfDHPacket(int phase, int negType,
NativeBigInteger integer, PeerNode pn, Peer replyTo) {
- long time1 = System.currentTimeMillis();
- if(logMINOR) Logger.minor(this, "Sending ("+phase+")
"+integer.toHexString()+" to "+pn.getPeer());
- byte[] data = stripBigIntegerToNetworkFormat(integer);
- if(logMINOR) Logger.minor(this, "Processed:
"+HexUtil.bytesToHex(data));
- long time2 = System.currentTimeMillis();
- if((time2 - time1) > 200) {
- Logger.error(this, "sendFirstHalfDHPacket: time2 is
more than 200ms after time1 ("+(time2 - time1)+") working on "+replyTo+" of
"+pn.userToString());
- }
- sendAuthPacket(1, negType, phase, data, pn, replyTo);
- long time3 = System.currentTimeMillis();
- if((time3 - time2) > 500) {
- Logger.error(this,
"sendFirstHalfDHPacket:sendAuthPacket() time3 is more than half a second after
time2 ("+(time3 - time2)+") working on "+replyTo+" of "+pn.userToString());
- }
- if((time3 - time1) > 500) {
- Logger.error(this, "sendFirstHalfDHPacket: time3 is
more than half a second after time1 ("+(time3 - time1)+") working on
"+replyTo+" of "+pn.userToString());
- }
- }
-
- /**
* Send an auth packet.
*/
private void sendAuthPacket(int version, int negType, int phase, byte[]
data, PeerNode pn, Peer replyTo) {
@@ -1369,126 +1229,6 @@
}
/**
- * Process a stage 2 or stage 3 auth packet.
- * Send a signed DH completion message.
- * Format:
- * IV
- * Signature on { My exponential, his exponential, data }
- * Data
- *
- * May decrypt in place.
- * @param oldOpennetPeer If true, the peer we are negotiating with is
not in
- * the primary routing table, it needs to be promoted from the list of
old opennet
- * nodes.
- */
- private DiffieHellmanContext processSignedDHTwoOrThree(int phase,
byte[] payload, PeerNode pn, Peer replyTo, boolean sendCompletion, boolean
oldOpennetPeer) {
- if(logMINOR) Logger.minor(this, "Handling signed stage
"+phase+" auth packet");
- // Get context, cipher, IV
- DiffieHellmanContext ctx = (DiffieHellmanContext)
pn.getKeyAgreementSchemeContext();
- if((ctx == null) || !ctx.canGetCipher()) {
- if(shouldLogErrorInHandshake()) {
- Logger.error(this, "Cannot get cipher");
- }
- return null;
- }
- byte[] encKey = ctx.getKey();
- BlockCipher cipher = ctx.getCipher();
- PCFBMode pcfb = PCFBMode.create(cipher);
- int ivLength = pcfb.lengthIV();
- if(payload.length-3 < HASH_LENGTH + ivLength + 8) {
- Logger.error(this, "Too short phase "+phase+" packet
from "+replyTo+" probably from "+pn);
- return null;
- }
- pcfb.reset(payload, 3); // IV
-
- // Decrypt the rest
- pcfb.blockDecipher(payload, 3, payload.length - 3);
-
- int count = 3 + ivLength;
-
- // R
- int rLen = payload[count++] & 0xFF;
- if(rLen > pn.getSigParamsByteLength()) {
- String msg = "R too long - changed key? Can happen on
startup";
- if(node.getUptime() < 15*60*1000)
- Logger.minor(this, msg);
- else Logger.error(this, msg);
- return null;
- }
- byte[] rBytes = new byte[rLen];
- System.arraycopy(payload, count, rBytes, 0, rLen);
- count += rLen;
- NativeBigInteger r = new NativeBigInteger(1, rBytes);
-
- // S
- int sLen = payload[count++] & 0xFF;
- if(rLen > pn.getSigParamsByteLength()) {
- String msg = "S too long - changed key? Can happen on
startup";
- if(node.getUptime() < 15*60*1000)
- Logger.minor(this, msg);
- else Logger.error(this, msg);
- return null;
- }
- byte[] sBytes = new byte[sLen];
- System.arraycopy(payload, count, sBytes, 0, sLen);
- count += sLen;
- NativeBigInteger s = new NativeBigInteger(1, sBytes);
-
- DSASignature sig = new DSASignature(r, s);
-
- // Data
- byte[] data = new byte[payload.length - count];
- System.arraycopy(payload, count, data, 0, payload.length -
count);
-
- // Now verify
- MessageDigest md = SHA256.getMessageDigest();
- md.update(ctx.getHisExponential().toByteArray());
- md.update(ctx.getOurExponential().toByteArray());
- md.update(data);
- byte[] hash = md.digest();
- if(!pn.verify(hash, sig)) {
- Logger.error(this, "Signature verification failed for
"+pn+" hash "+HexUtil.bytesToHex(hash)+"
r="+HexUtil.bytesToHex(sig.getR().toByteArray())+"
s="+HexUtil.bytesToHex(sig.getS().toByteArray()));
- return null;
- }
-
- // Success!
- long bootID = Fields.bytesToLong(data);
-
- // Promote if necessary
- boolean dontWant = false;
- if(oldOpennetPeer) {
- OpennetManager opennet = node.getOpennet();
- if(opennet == null) {
- Logger.normal(this, "Dumping incoming
old-opennet peer as opennet just turned off: "+pn+".");
- return null;
- }
- if(!opennet.wantPeer(pn, true)) {
- Logger.normal(this, "No longer want peer "+pn+"
- dumping it after connecting");
- dontWant = true;
- }
- // wantPeer will call node.peers.addPeer(), we don't
have to.
- }
-
- // Send the completion before parsing the data, because this is
easiest
- // Doesn't really matter - if it fails, we get loads of errors
anyway...
- // Only downside is that the other side might still think we
are connected for a while.
- // But this should be extremely rare.
- // REDFLAG?
- // We need to send the completion before the PN sends any
packets, that's all...
- if(pn.completedHandshake(bootID, data, 8, data.length-8,
cipher, encKey, replyTo, phase == 2)) {
- if(sendCompletion)
- sendSignedDHCompletion(3, ctx.getCipher(), pn,
replyTo, ctx);
- if(dontWant)
- node.peers.disconnect(pn, true, false);
- else
- pn.maybeSendInitialMessages();
- } else {
- Logger.error(this, "Handshake not completed");
- }
- return ctx;
- }
-
- /**
* Should we log an error for an event that could easily be
* caused by a handshake across a restart boundary?
*/
@@ -1500,50 +1240,6 @@
}
/**
- * Process a phase-0 or phase-1 Diffie-Hellman packet.
- * @return a DiffieHellmanContext if we succeeded, otherwise null.
- */
- private DiffieHellmanContext processDHZeroOrOne(int phase, byte[]
payload, PeerNode pn) {
-
- if((phase == 0) &&
pn.hasLiveHandshake(System.currentTimeMillis())) {
- if(logMINOR) Logger.minor(this, "Rejecting phase
"+phase+" handshake on "+pn+" - already running one");
- return null;
- }
-
- // First, get the BigInteger
- int length = DiffieHellman.modulusLengthInBytes();
- if(payload.length < length + 3) {
- Logger.error(this, "Packet too short:
"+payload.length+" after decryption in DH("+phase+"), should be "+(length + 3));
- return null;
- }
- byte[] aAsBytes = new byte[length];
- System.arraycopy(payload, 3, aAsBytes, 0, length);
- NativeBigInteger a = new NativeBigInteger(1, aAsBytes);
- if(!DiffieHellman.checkDHExponentialValidity(this.getClass(),
a)) {
- Logger.error(this, "We can't accept the exponential the
other end sent us!!");
- return null;
- }
- DiffieHellmanContext ctx;
- if(phase == 1) {
- ctx = (DiffieHellmanContext)
pn.getKeyAgreementSchemeContext();
- if(ctx == null) {
- if(shouldLogErrorInHandshake())
- Logger.error(this, "Could not get
context for phase 1 handshake from "+pn);
- return null;
- }
- } else {
- ctx = DiffieHellman.generateContext();
- // Don't calculate the key until we need it
- pn.setKeyAgreementSchemeContext(ctx);
- }
- ctx.setOtherSideExponential(a);
- if(logMINOR) Logger.minor(this, "His exponential:
"+a.toHexString());
- // REDFLAG: This is of course easily DoS'ed if you know the
node.
- // We will fix this by means of JFKi.
- return ctx;
- }
-
- /**
* Try to process an incoming packet with a given PeerNode.
* We need to know where the packet has come from in order to
* decrypt and authenticate it.
@@ -2409,7 +2105,6 @@
Logger.normal(this, "Cannot send handshake to "+pn+"
because no common negTypes, choosing random negType of "+negType);
}
if(logMINOR) Logger.minor(this, "Possibly sending handshake to
"+pn+" negotiation type "+negType);
- DiffieHellmanContext ctx = null;
Peer[] handshakeIPs;
if(!pn.shouldSendHandshake()) {
if(logMINOR) Logger.minor(this, "Not sending handshake
to "+pn.getPeer()+" because pn.shouldSendHandshake() returned false");
@@ -2426,13 +2121,6 @@
if((thirdTime - secondTime) > 1000)
Logger.error(this, "couldNotSendHandshake()
(after getHandshakeIPs()) took more than a second to execute ("+(thirdTime -
secondTime)+") working on "+pn.userToString());
return;
- } else if(negType < 2){
- long DHTime1 = System.currentTimeMillis();
- ctx = DiffieHellman.generateContext();
- long DHTime2 = System.currentTimeMillis();
- if((DHTime2 - DHTime1) > 1000)
- Logger.error(this, "DHTime2 is more than a
second after DHTime1 ("+(DHTime2 - DHTime1)+") working on "+pn.userToString());
- pn.setKeyAgreementSchemeContext(ctx);
}
int sentCount = 0;
long loopTime1 = System.currentTimeMillis();
@@ -2451,10 +2139,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;
}
- if(negType == 1)
- sendFirstHalfDHPacket(0, negType,
ctx.getOurExponential(), pn, peer);
- else
- sendJFKMessage1(pn, peer);
+ sendJFKMessage1(pn, peer);
if(logMINOR)
Logger.minor(this, "Sending handshake to
"+peer+" for "+pn+" ("+i+" of "+handshakeIPs.length);
pn.sentHandshake();