diff --git a/src/eu/siacs/conversations/utils/CryptoHelper.java b/src/eu/siacs/conversations/utils/CryptoHelper.java index 408c32fe..a70b419e 100644 --- a/src/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/eu/siacs/conversations/utils/CryptoHelper.java @@ -5,9 +5,9 @@ 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; public class CryptoHelper { @@ -28,7 +28,11 @@ public class CryptoHelper { } public static byte[] hexToBytes(String hexString) { - return new BigInteger(hexString, 16).toByteArray(); + byte[] array = new BigInteger(hexString, 16).toByteArray(); + if (array[0] == 0) { + array = Arrays.copyOfRange(array, 1, array.length); + } + return array; } public static String saslPlain(String username, String password) { diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleFile.java b/src/eu/siacs/conversations/xmpp/jingle/JingleFile.java index fd366754..3672351b 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleFile.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleFile.java @@ -25,7 +25,11 @@ public class JingleFile extends File { } public long getExpectedSize() { - return this.expectedSize; + if (this.aeskey!=null) { + return (this.expectedSize/16 + 1) * 16; + } else { + return this.expectedSize; + } } public void setExpectedSize(long size) { @@ -41,18 +45,18 @@ public class JingleFile extends File { } public void setKey(byte[] key) { - Log.d("xmppService","using aes key "+CryptoHelper.bytesToHex(key)); if (key.length>=32) { byte[] secretKey = new byte[32]; System.arraycopy(key, 0, secretKey, 0, 32); - this.aeskey = new SecretKeySpec(key, "AES"); + this.aeskey = new SecretKeySpec(secretKey, "AES"); } else if (key.length>=16) { - byte[] secretKey = new byte[15]; + byte[] secretKey = new byte[16]; System.arraycopy(key, 0, secretKey, 0, 16); - this.aeskey = new SecretKeySpec(key, "AES"); + this.aeskey = new SecretKeySpec(secretKey, "AES"); } else { Log.d("xmppService","weird key"); } + Log.d("xmppService","using aes key "+CryptoHelper.bytesToHex(this.aeskey.getEncoded())); } public Key getKey() { diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java b/src/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java index 838c7d5f..4fef0388 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java @@ -6,6 +6,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.ObjectInputStream.GetField; import java.net.Socket; import java.net.UnknownHostException; import java.security.MessageDigest; @@ -97,17 +98,16 @@ public class JingleSocks5Transport extends JingleTransport { digest.reset(); fileInputStream = getInputStream(file); int count; - long txbytes = 0; + long txBytes = 0; byte[] buffer = new byte[8192]; - while ((count = fileInputStream.read(buffer)) != -1) { - txbytes += count; + while ((count = fileInputStream.read(buffer)) > 0) { + txBytes += count; outputStream.write(buffer, 0, count); digest.update(buffer, 0, count); - Log.d("xmppService","tx bytes: "+txbytes); } + Log.d("xmppService","txBytes="+txBytes); outputStream.flush(); file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); - //outputStream.close(); if (callback!=null) { callback.onFileTransmitted(file); } @@ -115,7 +115,8 @@ public class JingleSocks5Transport extends JingleTransport { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { - Log.d("xmppService","io exception: "+e.getMessage()); + // TODO Auto-generated catch block + e.printStackTrace(); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -149,26 +150,32 @@ public class JingleSocks5Transport extends JingleTransport { long remainingSize = file.getExpectedSize(); byte[] buffer = new byte[8192]; int count = buffer.length; - //while(remainingSize > 0) { - while((count = inputStream.read(buffer)) > 0) { - Log.d("xmppService","remaining size: "+remainingSize+" reading "+count+" bytes"); + long rxBytes = 0; + while(remainingSize > 0) { count = inputStream.read(buffer); - if (count!=-1) { + if (count==-1) { + Log.d("xmppService","read end"); + } else { + rxBytes += count; fileOutputStream.write(buffer, 0, count); digest.update(buffer, 0, count); + remainingSize-=count; } - remainingSize-=count; } + Log.d("xmppService","rx bytes="+rxBytes); fileOutputStream.flush(); fileOutputStream.close(); file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); callback.onFileTransmitted(file); } catch (FileNotFoundException e) { - Log.d("xmppService","file not found exception"); + // TODO Auto-generated catch block + e.printStackTrace(); } catch (IOException e) { - Log.d("xmppService","io exception: "+e.getMessage()); + // TODO Auto-generated catch block + e.printStackTrace(); } catch (NoSuchAlgorithmException e) { - Log.d("xmppService","no such algo"+e.getMessage()); + // TODO Auto-generated catch block + e.printStackTrace(); } } }).start(); diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleTransport.java b/src/eu/siacs/conversations/xmpp/jingle/JingleTransport.java index b96fefed..5db4b715 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleTransport.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleTransport.java @@ -5,6 +5,7 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; +import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; @@ -12,6 +13,7 @@ import javax.crypto.Cipher; import javax.crypto.CipherOutputStream; import javax.crypto.CipherInputStream; import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.IvParameterSpec; import android.util.Log; @@ -19,14 +21,16 @@ public abstract class JingleTransport { public abstract void connect(final OnTransportConnected callback); public abstract void receive(final JingleFile file, final OnFileTransmitted callback); public abstract void send(final JingleFile file, final OnFileTransmitted callback); + private byte[] iv = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0xf}; protected InputStream getInputStream(JingleFile file) throws FileNotFoundException { if (file.getKey() == null) { return new FileInputStream(file); } else { try { + IvParameterSpec ips = new IvParameterSpec(iv); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - cipher.init(Cipher.ENCRYPT_MODE, file.getKey()); + cipher.init(Cipher.ENCRYPT_MODE, file.getKey(),ips); Log.d("xmppService","opening encrypted input stream"); return new CipherInputStream(new FileInputStream(file), cipher); } catch (NoSuchAlgorithmException e) { @@ -38,6 +42,9 @@ public abstract class JingleTransport { } catch (InvalidKeyException e) { Log.d("xmppService","invalid key: "+e.getMessage()); return null; + } catch (InvalidAlgorithmParameterException e) { + Log.d("xmppService","invavid iv:"+e.getMessage()); + return null; } } } @@ -47,8 +54,9 @@ public abstract class JingleTransport { return new FileOutputStream(file); } else { try { + IvParameterSpec ips = new IvParameterSpec(iv); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - cipher.init(Cipher.DECRYPT_MODE, file.getKey()); + cipher.init(Cipher.DECRYPT_MODE, file.getKey(),ips); Log.d("xmppService","opening encrypted output stream"); return new CipherOutputStream(new FileOutputStream(file), cipher); } catch (NoSuchAlgorithmException e) { @@ -60,6 +68,9 @@ public abstract class JingleTransport { } catch (InvalidKeyException e) { Log.d("xmppService","invalid key: "+e.getMessage()); return null; + } catch (InvalidAlgorithmParameterException e) { + Log.d("xmppService","invavid iv:"+e.getMessage()); + return null; } } }