made httpconnection accept aes encrypted files

iNPUTmice created

Change summary

src/eu/siacs/conversations/entities/DownloadableFile.java           | 23 
src/eu/siacs/conversations/entities/Message.java                    |  5 
src/eu/siacs/conversations/http/HttpConnection.java                 |  9 
src/eu/siacs/conversations/utils/CryptoHelper.java                  |  9 
src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java |  3 
5 files changed, 33 insertions(+), 16 deletions(-)

Detailed changes

src/eu/siacs/conversations/entities/DownloadableFile.java 🔗

@@ -19,7 +19,6 @@ import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.SecretKeySpec;
 
 import eu.siacs.conversations.Config;
-import eu.siacs.conversations.utils.CryptoHelper;
 import android.util.Log;
 
 public class DownloadableFile extends File {
@@ -43,7 +42,11 @@ public class DownloadableFile extends File {
 
 	public long getExpectedSize() {
 		if (this.aeskey != null) {
-			return (this.expectedSize / 16 + 1) * 16;
+			if (this.expectedSize == 0) {
+				return 0;
+			} else {
+				return (this.expectedSize / 16 + 1) * 16;
+			}
 		} else {
 			return this.expectedSize;
 		}
@@ -62,7 +65,14 @@ public class DownloadableFile extends File {
 	}
 
 	public void setKey(byte[] key) {
-		if (key.length >= 32) {
+		if (key.length == 48) {
+			byte[] secretKey = new byte[32];
+			byte[] iv = new byte[16];
+			System.arraycopy(key, 0, iv, 0, 16);
+			System.arraycopy(key, 16, secretKey, 0, 32);
+			this.aeskey = new SecretKeySpec(secretKey, "AES");
+			this.iv = iv;
+		} else if (key.length >= 32) {
 			byte[] secretKey = new byte[32];
 			System.arraycopy(key, 0, secretKey, 0, 32);
 			this.aeskey = new SecretKeySpec(secretKey, "AES");
@@ -70,12 +80,7 @@ public class DownloadableFile extends File {
 			byte[] secretKey = new byte[16];
 			System.arraycopy(key, 0, secretKey, 0, 16);
 			this.aeskey = new SecretKeySpec(secretKey, "AES");
-		} else {
-			Log.d(Config.LOGTAG, "weird key");
 		}
-		Log.d(Config.LOGTAG,
-				"using aes key "
-						+ CryptoHelper.bytesToHex(this.aeskey.getEncoded()));
 	}
 
 	public Key getKey() {
@@ -123,7 +128,7 @@ public class DownloadableFile extends File {
 			}
 		} else {
 			try {
-				IvParameterSpec ips = new IvParameterSpec(iv);
+				IvParameterSpec ips = new IvParameterSpec(this.iv);
 				Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
 				cipher.init(Cipher.DECRYPT_MODE, this.getKey(), ips);
 				Log.d(Config.LOGTAG, "opening encrypted output stream");

src/eu/siacs/conversations/entities/Message.java 🔗

@@ -403,8 +403,9 @@ public class Message extends AbstractEntity {
 							extensionParts[extensionParts.length - 1])) {
 				return true;
 			} else if (extensionParts.length == 3
-					&& Arrays.asList(Downloadable.VALID_CRYPTO_EXTENSIONS)
-							.contains(extensionParts.length - 1)
+					&& Arrays
+							.asList(Downloadable.VALID_CRYPTO_EXTENSIONS)
+							.contains(extensionParts[extensionParts.length - 1])
 					&& Arrays.asList(Downloadable.VALID_EXTENSIONS).contains(
 							extensionParts[extensionParts.length - 2])) {
 				return true;

src/eu/siacs/conversations/http/HttpConnection.java 🔗

@@ -27,6 +27,7 @@ import eu.siacs.conversations.entities.Downloadable;
 import eu.siacs.conversations.entities.DownloadableFile;
 import eu.siacs.conversations.entities.Message;
 import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.utils.CryptoHelper;
 
 public class HttpConnection implements Downloadable {
 
@@ -64,6 +65,14 @@ public class HttpConnection implements Downloadable {
 			mUrl = new URL(message.getBody());
 			this.file = mXmppConnectionService.getFileBackend().getFile(
 					message, false);
+			String reference = mUrl.getRef();
+			if (reference != null && reference.length() == 96) {
+				this.file.setKey(CryptoHelper.hexToBytes(reference));
+			}
+			if (this.message.getEncryption() == Message.ENCRYPTION_OTR
+					&& this.file.getKey() == null) {
+				this.message.setEncryption(Message.ENCRYPTION_NONE);
+			}
 			checkFileSize(false);
 		} catch (MalformedURLException e) {
 			this.cancel();

src/eu/siacs/conversations/utils/CryptoHelper.java 🔗

@@ -5,7 +5,6 @@ import java.nio.charset.Charset;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
-import java.util.Arrays;
 
 import eu.siacs.conversations.entities.Account;
 import android.util.Base64;
@@ -28,9 +27,11 @@ public class CryptoHelper {
 	}
 
 	public static byte[] hexToBytes(String hexString) {
-		byte[] array = new BigInteger(hexString, 16).toByteArray();
-		if (array[0] == 0) {
-			array = Arrays.copyOfRange(array, 1, array.length);
+		int len = hexString.length();
+		byte[] array = new byte[len / 2];
+		for (int i = 0; i < len; i += 2) {
+			array[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character
+					.digit(hexString.charAt(i + 1), 16));
 		}
 		return array;
 	}

src/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java 🔗

@@ -136,7 +136,8 @@ public class JingleConnectionManager extends AbstractConnectionManager {
 		}
 		if (sid != null) {
 			for (JingleConnection connection : connections) {
-				if (connection.getAccount() == account && connection.hasTransportId(sid)) {
+				if (connection.getAccount() == account
+						&& connection.hasTransportId(sid)) {
 					JingleTransport transport = connection.getTransport();
 					if (transport instanceof JingleInbandTransport) {
 						JingleInbandTransport inbandTransport = (JingleInbandTransport) transport;