From 4a070ab2d22adcfa8ba63b1b6c9e1358bf3badbb Mon Sep 17 00:00:00 2001
From: Chetan Hosmani <chetanspecial@gmail.com>
Date: Sun, 1 Apr 2012 22:56:20 +0530
Subject: [PATCH] Add JCACipher and modify FNPPacketMangler

---
 src/freenet/crypt/ciphers/JCACipher.java |   84 ++++++++++++++++++++++++++++++
 src/freenet/node/FNPPacketMangler.java   |   69 ++++++++++++++++---------
 2 files changed, 129 insertions(+), 24 deletions(-)
 create mode 100644 src/freenet/crypt/ciphers/JCACipher.java

diff --git a/src/freenet/crypt/ciphers/JCACipher.java b/src/freenet/crypt/ciphers/JCACipher.java
new file mode 100644
index 0000000..b4193e5
--- /dev/null
+++ b/src/freenet/crypt/ciphers/JCACipher.java
@@ -0,0 +1,84 @@
+package freenet.crypt.ciphers;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import freenet.crypt.BlockCipher;
+import freenet.support.Logger;
+
+public class JCACipher implements BlockCipher {
+	
+	private KeyGenerator keygen;
+	private SecretKey aesKey;
+	private final int keySize, blockSize;
+	private Cipher aesCipher;
+	private SecretKeySpec sKey;
+	
+	public JCACipher(int keySize, int blockSize){
+		this.keySize = keySize;
+		this.blockSize = blockSize;
+	}
+
+	@Override
+	public void initialize(byte[] key) {
+		try {
+			sKey = new SecretKeySpec(key, "AES");
+			//keygen = KeyGenerator.getInstance("AES");
+			//keygen.init(keySize);
+			//aesKey = keygen.generateKey();
+			aesCipher = Cipher.getInstance("AES/CFB" + (blockSize/8) + "/PKCS5Padding");
+			
+		} catch (NoSuchAlgorithmException e) {
+			e.printStackTrace();
+		}catch (NoSuchPaddingException e) {
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public int getKeySize() {
+		return keySize;
+	}
+
+	@Override
+	public int getBlockSize() {
+		return blockSize;
+	}
+
+	@Override
+	public void encipher(byte[] block, byte[] result) {
+		try {
+			aesCipher.init(Cipher.ENCRYPT_MODE, sKey);
+			result = aesCipher.doFinal(block);
+		} catch (IllegalBlockSizeException e) {
+			e.printStackTrace();
+		} catch (BadPaddingException e) {
+			e.printStackTrace();
+		} catch (InvalidKeyException e) {
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public void decipher(byte[] block, byte[] result) {
+		try {
+			aesCipher.init(Cipher.DECRYPT_MODE, sKey);
+			result = aesCipher.doFinal(block);
+		} catch (IllegalBlockSizeException e) {
+			e.printStackTrace();
+		} catch (BadPaddingException e) {
+			e.printStackTrace();
+		} catch (InvalidKeyException e) {
+			e.printStackTrace();
+		}
+	}
+
+}
diff --git a/src/freenet/node/FNPPacketMangler.java b/src/freenet/node/FNPPacketMangler.java
index 42d3055..3a81f3f 100644
--- a/src/freenet/node/FNPPacketMangler.java
+++ b/src/freenet/node/FNPPacketMangler.java
@@ -26,6 +26,7 @@ import freenet.crypt.HMAC;
 import freenet.crypt.PCFBMode;
 import freenet.crypt.SHA256;
 import freenet.crypt.UnsupportedCipherException;
+import freenet.crypt.ciphers.JCACipher;
 import freenet.crypt.ciphers.Rijndael;
 import freenet.io.AddressTracker;
 import freenet.io.AddressTracker.Status;
@@ -621,7 +622,7 @@ public class FNPPacketMangler implements OutgoingPacketMangler {
 			Logger.error(this, "Decrypted auth packet but invalid version: "+version);
 			return;
 		}
-		if(!(negType == 2 || negType == 4 || negType == 6 || negType == 7)) {
+		if(!(negType == 2 || negType == 4 || negType == 6 || negType == 7 || negType == 8)) {
 			Logger.error(this, "Unknown neg type: "+negType);
 			return;
 		}
@@ -668,7 +669,7 @@ public class FNPPacketMangler implements OutgoingPacketMangler {
 			Logger.error(this, "Decrypted auth packet but invalid version: "+version);
 			return;
 		}
-		if(!(negType == 2 || negType == 4 || negType == 6 || negType == 7)) {
+		if(!(negType == 2 || negType == 4 || negType == 6 || negType == 7 || negType == 8)) {
 			Logger.error(this, "Unknown neg type: "+negType);
 			return;
 		}
@@ -734,7 +735,7 @@ public class FNPPacketMangler implements OutgoingPacketMangler {
 		} else if (negType == 1) {
 			Logger.error(this, "Old StationToStation (negType 1) not supported.");
 			return;
-		} else if (negType==2 || negType == 4 || negType == 6 || negType == 7) {
+		} else if (negType==2 || negType == 4 || negType == 6 || negType == 7 || negType == 8) {
 			// negType == 3 was buggy
 			// negType == 4 => negotiate whether to use a new PacketTracker when rekeying
 			// negType == 5 => same as 4, but use new packet format after negotiation
@@ -1351,17 +1352,26 @@ public class FNPPacketMangler implements OutgoingPacketMangler {
 		BlockCipher outgoingCipher = null;
 		BlockCipher incommingCipher = null;
 		BlockCipher ivCipher = null;
-		try {
-			outgoingCipher = new Rijndael(256, 256);
-			incommingCipher = new Rijndael(256, 256);
-			ivCipher = new Rijndael(256, 256);
-		} catch (UnsupportedCipherException e) {
-			throw new RuntimeException(e);
+		if(negType != 8){
+			try {
+				outgoingCipher = new Rijndael(256, 256);
+				incommingCipher = new Rijndael(256, 256);
+				ivCipher = new Rijndael(256, 256);
+			} catch (UnsupportedCipherException e) {
+				throw new RuntimeException(e);
+			}
+			outgoingCipher.initialize(outgoingKey);
+			incommingCipher.initialize(incommingKey);
+			ivCipher.initialize(ivKey);
+		}
+		else{
+			outgoingCipher = new JCACipher(256, 256);
+			incommingCipher = new JCACipher(256, 256);
+			ivCipher = new JCACipher(256, 256);
+			outgoingCipher.initialize(outgoingKey);
+			incommingCipher.initialize(incommingKey);
+			ivCipher.initialize(ivKey);
 		}
-		outgoingCipher.initialize(outgoingKey);
-		incommingCipher.initialize(incommingKey);
-		ivCipher.initialize(ivKey);
-
 		// Promote if necessary
 		boolean dontWant = false;
 		if(oldOpennetPeer) {
@@ -1620,17 +1630,28 @@ public class FNPPacketMangler implements OutgoingPacketMangler {
 		BlockCipher ivCipher = null;
 		BlockCipher outgoingCipher = null;
 		BlockCipher incommingCipher = null;
-		try {
-			ivCipher = new Rijndael(256, 256);
-			outgoingCipher = new Rijndael(256, 256);
-			incommingCipher = new Rijndael(256, 256);
-		} catch (UnsupportedCipherException e) {
-			throw new RuntimeException(e);
+		if(negType != 8){
+			try {
+				outgoingCipher = new Rijndael(256, 256);
+				incommingCipher = new Rijndael(256, 256);
+				ivCipher = new Rijndael(256, 256);
+			} catch (UnsupportedCipherException e) {
+				throw new RuntimeException(e);
+			}
+			outgoingCipher.initialize(pn.outgoingKey);
+			incommingCipher.initialize(pn.incommingKey);
+			ivCipher.initialize(pn.ivKey);
 		}
+		else{
+			outgoingCipher = new JCACipher(256, 256);
+			incommingCipher = new JCACipher(256, 256);
+			ivCipher = new JCACipher(256, 256);
+			outgoingCipher.initialize(pn.outgoingKey);
+			incommingCipher.initialize(pn.incommingKey);
+			ivCipher.initialize(pn.ivKey);
+		}
+
 
-		outgoingCipher.initialize(pn.outgoingKey);
-		incommingCipher.initialize(pn.incommingKey);
-		ivCipher.initialize(pn.ivKey);
 
 		long newTrackerID = pn.completedHandshake(
 				bootID, hisRef, 0, hisRef.length, outgoingCipher, pn.outgoingKey, incommingCipher,
@@ -3214,9 +3235,9 @@ public class FNPPacketMangler implements OutgoingPacketMangler {
 	@Override
 	public int[] supportedNegTypes(boolean forPublic) {
 		if(forPublic)
-			return new int[] { 2, 4, 6, 7 };
+			return new int[] { 2, 4, 6, 7, 8 };
 		else
-			return new int[] { 2, 4, 6, 7 };
+			return new int[] { 2, 4, 6, 7, 8 };
 	}
 
 	@Override
-- 
1.7.5.4

