diff options
author | iNPUTmice <daniel@gultsch.de> | 2014-06-20 17:30:19 +0200 |
---|---|---|
committer | iNPUTmice <daniel@gultsch.de> | 2014-06-20 17:30:19 +0200 |
commit | 1cf055d2fdbaa881cfc8ead6b78dc744e9dbe596 (patch) | |
tree | 51c0a3463ff3d5f005aeb6dccf6c50d05fddab42 /src/eu/siacs/conversations/xmpp/jingle | |
parent | beafb06b6a59649a4c314db820f5ce30be120e7c (diff) |
not working version of otr file transfer
Diffstat (limited to 'src/eu/siacs/conversations/xmpp/jingle')
5 files changed, 130 insertions, 27 deletions
diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 8f88688a..85110c38 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -9,11 +9,11 @@ import java.util.Map.Entry; import android.graphics.BitmapFactory; import android.util.Log; - import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.OnIqPacketReceived; import eu.siacs.conversations.xmpp.jingle.stanzas.Content; @@ -24,7 +24,7 @@ import eu.siacs.conversations.xmpp.stanzas.IqPacket; public class JingleConnection { private final String[] extensions = {"webp","jpeg","jpg","png"}; - private final String[] cryptoExtensions = {"pgp","gpg"}; + private final String[] cryptoExtensions = {"pgp","gpg","otr"}; private JingleConnectionManager mJingleConnectionManager; private XmppConnectionService mXmppConnectionService; @@ -244,6 +244,7 @@ public class JingleConnection { Element fileNameElement = fileOffer.findChild("name"); if (fileNameElement!=null) { boolean supportedFile = false; + Log.d("xmppService","file offer: "+fileNameElement.getContent()); String[] filename = fileNameElement.getContent().toLowerCase().split("\\."); if (Arrays.asList(this.extensions).contains(filename[filename.length - 1])) { supportedFile = true; @@ -251,7 +252,12 @@ public class JingleConnection { if (filename.length == 3) { if (Arrays.asList(this.extensions).contains(filename[filename.length -2])) { supportedFile = true; - this.message.setEncryption(Message.ENCRYPTION_PGP); + if (filename[filename.length - 1].equals("otr")) { + Log.d("xmppService","receiving otr file"); + this.message.setEncryption(Message.ENCRYPTION_OTR); + } else { + this.message.setEncryption(Message.ENCRYPTION_PGP); + } } } } @@ -269,6 +275,9 @@ public class JingleConnection { this.mXmppConnectionService.updateUi(conversation, true); } this.file = this.mXmppConnectionService.getFileBackend().getJingleFile(message,false); + if (message.getEncryption() == Message.ENCRYPTION_OTR) { + this.file.setKey(conversation.getSymmetricKey()); + } this.file.setExpectedSize(size); } else { this.sendCancel(); @@ -287,7 +296,14 @@ public class JingleConnection { if (message.getType() == Message.TYPE_IMAGE) { content.setTransportId(this.transportId); this.file = this.mXmppConnectionService.getFileBackend().getJingleFile(message,false); - content.setFileOffer(this.file); + if (message.getEncryption() == Message.ENCRYPTION_OTR) { + Conversation conversation = this.message.getConversation(); + this.mXmppConnectionService.renewSymmetricKey(conversation); + content.setFileOffer(this.file, true); + this.file.setKey(conversation.getSymmetricKey()); + } else { + content.setFileOffer(this.file,false); + } this.transportId = this.mJingleConnectionManager.nextRandomId(); content.setTransportId(this.transportId); content.socks5transport().setChildren(getCandidatesAsElements()); diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleFile.java b/src/eu/siacs/conversations/xmpp/jingle/JingleFile.java index 21cbd716..fd366754 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleFile.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleFile.java @@ -1,6 +1,12 @@ package eu.siacs.conversations.xmpp.jingle; import java.io.File; +import java.security.Key; + +import javax.crypto.spec.SecretKeySpec; + +import eu.siacs.conversations.utils.CryptoHelper; +import android.util.Log; public class JingleFile extends File { @@ -8,6 +14,7 @@ public class JingleFile extends File { private long expectedSize = 0; private String sha1sum; + private Key aeskey; public JingleFile(String path) { super(path); @@ -32,4 +39,23 @@ public class JingleFile extends File { public void setSha1Sum(String sum) { this.sha1sum = sum; } + + 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"); + } else if (key.length>=16) { + byte[] secretKey = new byte[15]; + System.arraycopy(key, 0, secretKey, 0, 16); + this.aeskey = new SecretKeySpec(key, "AES"); + } else { + Log.d("xmppService","weird key"); + } + } + + public Key getKey() { + return this.aeskey; + } } diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java b/src/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java index 0f2d4cae..838c7d5f 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java @@ -12,6 +12,7 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; +import android.util.Log; import eu.siacs.conversations.utils.CryptoHelper; public class JingleSocks5Transport extends JingleTransport { @@ -90,19 +91,23 @@ public class JingleSocks5Transport extends JingleTransport { @Override public void run() { - FileInputStream fileInputStream = null; + InputStream fileInputStream = null; try { MessageDigest digest = MessageDigest.getInstance("SHA-1"); digest.reset(); - fileInputStream = new FileInputStream(file); + fileInputStream = getInputStream(file); int count; + long txbytes = 0; byte[] buffer = new byte[8192]; - while ((count = fileInputStream.read(buffer)) > 0) { + while ((count = fileInputStream.read(buffer)) != -1) { + txbytes += count; outputStream.write(buffer, 0, count); digest.update(buffer, 0, count); + Log.d("xmppService","tx bytes: "+txbytes); } outputStream.flush(); file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); + //outputStream.close(); if (callback!=null) { callback.onFileTransmitted(file); } @@ -110,8 +115,7 @@ public class JingleSocks5Transport extends JingleTransport { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + Log.d("xmppService","io exception: "+e.getMessage()); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -141,36 +145,30 @@ public class JingleSocks5Transport extends JingleTransport { inputStream.skip(45); file.getParentFile().mkdirs(); file.createNewFile(); - FileOutputStream fileOutputStream = new FileOutputStream(file); + OutputStream fileOutputStream = getOutputStream(file); long remainingSize = file.getExpectedSize(); byte[] buffer = new byte[8192]; int count = buffer.length; - while(remainingSize > 0) { - if (remainingSize<=count) { - count = (int) remainingSize; - } - count = inputStream.read(buffer, 0, count); - if (count==-1) { - // TODO throw exception - } else { + //while(remainingSize > 0) { + while((count = inputStream.read(buffer)) > 0) { + Log.d("xmppService","remaining size: "+remainingSize+" reading "+count+" bytes"); + count = inputStream.read(buffer); + if (count!=-1) { fileOutputStream.write(buffer, 0, count); digest.update(buffer, 0, count); - remainingSize-=count; } + remainingSize-=count; } fileOutputStream.flush(); fileOutputStream.close(); file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest())); callback.onFileTransmitted(file); } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + Log.d("xmppService","file not found exception"); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + Log.d("xmppService","io exception: "+e.getMessage()); } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + Log.d("xmppService","no such algo"+e.getMessage()); } } }).start(); diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleTransport.java b/src/eu/siacs/conversations/xmpp/jingle/JingleTransport.java index 290bb5d3..b96fefed 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleTransport.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleTransport.java @@ -1,7 +1,66 @@ package eu.siacs.conversations.xmpp.jingle; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +import javax.crypto.Cipher; +import javax.crypto.CipherOutputStream; +import javax.crypto.CipherInputStream; +import javax.crypto.NoSuchPaddingException; + +import android.util.Log; + 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); + + protected InputStream getInputStream(JingleFile file) throws FileNotFoundException { + if (file.getKey() == null) { + return new FileInputStream(file); + } else { + try { + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, file.getKey()); + Log.d("xmppService","opening encrypted input stream"); + return new CipherInputStream(new FileInputStream(file), cipher); + } catch (NoSuchAlgorithmException e) { + Log.d("xmppService","no such algo: "+e.getMessage()); + return null; + } catch (NoSuchPaddingException e) { + Log.d("xmppService","no such padding: "+e.getMessage()); + return null; + } catch (InvalidKeyException e) { + Log.d("xmppService","invalid key: "+e.getMessage()); + return null; + } + } + } + + protected OutputStream getOutputStream(JingleFile file) throws FileNotFoundException { + if (file.getKey() == null) { + return new FileOutputStream(file); + } else { + try { + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + cipher.init(Cipher.DECRYPT_MODE, file.getKey()); + Log.d("xmppService","opening encrypted output stream"); + return new CipherOutputStream(new FileOutputStream(file), cipher); + } catch (NoSuchAlgorithmException e) { + Log.d("xmppService","no such algo: "+e.getMessage()); + return null; + } catch (NoSuchPaddingException e) { + Log.d("xmppService","no such padding: "+e.getMessage()); + return null; + } catch (InvalidKeyException e) { + Log.d("xmppService","invalid key: "+e.getMessage()); + return null; + } + } + } } diff --git a/src/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java b/src/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java index abede91a..494ff0d6 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java +++ b/src/eu/siacs/conversations/xmpp/jingle/stanzas/Content.java @@ -25,12 +25,16 @@ public class Content extends Element { this.transportId = sid; } - public void setFileOffer(JingleFile actualFile) { + public void setFileOffer(JingleFile actualFile, boolean otr) { Element description = this.addChild("description", "urn:xmpp:jingle:apps:file-transfer:3"); Element offer = description.addChild("offer"); Element file = offer.addChild("file"); file.addChild("size").setContent(""+actualFile.getSize()); - file.addChild("name").setContent(actualFile.getName()); + if (otr) { + file.addChild("name").setContent(actualFile.getName()+".otr"); + } else { + file.addChild("name").setContent(actualFile.getName()); + } } public Element getFileOffer() { |