From 461f2ffb16ebb877a1ab28e8815b07196e424a36 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 6 May 2014 21:34:30 +0200 Subject: basic pgp encrypted file transfer --- src/eu/siacs/conversations/crypto/PgpEngine.java | 188 +++++++++++++++++------ 1 file changed, 143 insertions(+), 45 deletions(-) (limited to 'src/eu/siacs/conversations/crypto') diff --git a/src/eu/siacs/conversations/crypto/PgpEngine.java b/src/eu/siacs/conversations/crypto/PgpEngine.java index cfe39e4c..35247ef2 100644 --- a/src/eu/siacs/conversations/crypto/PgpEngine.java +++ b/src/eu/siacs/conversations/crypto/PgpEngine.java @@ -2,6 +2,10 @@ package eu.siacs.conversations.crypto; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -11,85 +15,181 @@ import org.openintents.openpgp.util.OpenPgpApi; import org.openintents.openpgp.util.OpenPgpApi.IOpenPgpCallback; import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.xmpp.jingle.JingleFile; import android.app.PendingIntent; import android.content.Intent; +import android.graphics.BitmapFactory; import android.util.Log; public class PgpEngine { private OpenPgpApi api; + private XmppConnectionService mXmppConnectionService; - public PgpEngine(OpenPgpApi api) { + public PgpEngine(OpenPgpApi api, XmppConnectionService service) { this.api = api; + this.mXmppConnectionService = service; } public void decrypt(final Message message, final OnPgpEngineResult callback) { + Log.d("xmppService","decrypting message "+message.getUuid()); Intent params = new Intent(); params.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY); params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, message .getConversation().getAccount().getJid()); + if (message.getType() == Message.TYPE_TEXT) { + InputStream is = new ByteArrayInputStream(message.getBody().getBytes()); + final OutputStream os = new ByteArrayOutputStream(); + api.executeApiAsync(params, is, os, new IOpenPgpCallback() { + + @Override + public void onReturn(Intent result) { + switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, + OpenPgpApi.RESULT_CODE_ERROR)) { + case OpenPgpApi.RESULT_CODE_SUCCESS: + message.setBody(os.toString()); + message.setEncryption(Message.ENCRYPTION_DECRYPTED); + callback.success(); + return; + case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: + callback.userInputRequried((PendingIntent) result + .getParcelableExtra(OpenPgpApi.RESULT_INTENT)); + return; + case OpenPgpApi.RESULT_CODE_ERROR: + callback.error((OpenPgpError) result + .getParcelableExtra(OpenPgpApi.RESULT_ERROR)); + return; + default: + return; + } + } + }); + } else if (message.getType() == Message.TYPE_IMAGE) { + try { + final JingleFile inputFile = this.mXmppConnectionService.getFileBackend().getJingleFile(message, false); + final JingleFile outputFile = this.mXmppConnectionService.getFileBackend().getJingleFile(message,true); + outputFile.createNewFile(); + InputStream is = new FileInputStream(inputFile); + OutputStream os = new FileOutputStream(outputFile); + api.executeApiAsync(params, is, os, new IOpenPgpCallback() { + + @Override + public void onReturn(Intent result) { + switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, + OpenPgpApi.RESULT_CODE_ERROR)) { + case OpenPgpApi.RESULT_CODE_SUCCESS: + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inJustDecodeBounds = true; + BitmapFactory.decodeFile(outputFile.getAbsolutePath(),options); + int imageHeight = options.outHeight; + int imageWidth = options.outWidth; + message.setBody(""+outputFile.getSize()+","+imageWidth+","+imageHeight); + message.setEncryption(Message.ENCRYPTION_DECRYPTED); + PgpEngine.this.mXmppConnectionService.updateMessage(message); + PgpEngine.this.mXmppConnectionService.updateUi(message.getConversation(), false); + callback.success(); + return; + case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: + callback.userInputRequried((PendingIntent) result + .getParcelableExtra(OpenPgpApi.RESULT_INTENT)); + return; + case OpenPgpApi.RESULT_CODE_ERROR: + callback.error((OpenPgpError) result + .getParcelableExtra(OpenPgpApi.RESULT_ERROR)); + return; + default: + return; + } + } + }); + } catch (FileNotFoundException e) { + callback.error(new OpenPgpError(0, "file not found: "+e.getMessage())); + } catch (IOException e) { + callback.error(new OpenPgpError(0, "io exception: "+e.getMessage())); + } + + } + } + + public void encrypt(Account account, final Message message, + final OnPgpEngineResult callback) { + long[] keys = { message.getConversation().getContact().getPgpKeyId() }; + Intent params = new Intent(); + params.setAction(OpenPgpApi.ACTION_ENCRYPT); + params.putExtra(OpenPgpApi.EXTRA_KEY_IDS, keys); + params.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); + params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, account.getJid()); + InputStream is = new ByteArrayInputStream(message.getBody().getBytes()); final OutputStream os = new ByteArrayOutputStream(); api.executeApiAsync(params, is, os, new IOpenPgpCallback() { - + @Override public void onReturn(Intent result) { switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) { case OpenPgpApi.RESULT_CODE_SUCCESS: - message.setBody(os.toString()); - message.setEncryption(Message.ENCRYPTION_DECRYPTED); + StringBuilder encryptedMessageBody = new StringBuilder(); + String[] lines = os.toString().split("\n"); + for (int i = 3; i < lines.length - 1; ++i) { + encryptedMessageBody.append(lines[i].trim()); + } + message.setEncryptedBody(encryptedMessageBody.toString()); callback.success(); - return; + break; case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: callback.userInputRequried((PendingIntent) result .getParcelableExtra(OpenPgpApi.RESULT_INTENT)); - return; + break; case OpenPgpApi.RESULT_CODE_ERROR: callback.error((OpenPgpError) result .getParcelableExtra(OpenPgpApi.RESULT_ERROR)); - return; - default: - return; + break; } } }); + } - - public void encrypt(Account account, long keyId, Message message, - final OnPgpEngineResult callback) { - Log.d("xmppService", "called to pgpengine::encrypt"); - long[] keys = { keyId }; - Intent params = new Intent(); - params.setAction(OpenPgpApi.ACTION_ENCRYPT); - params.putExtra(OpenPgpApi.EXTRA_KEY_IDS, keys); - params.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); - params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, account.getJid()); - - InputStream is = new ByteArrayInputStream(message.getBody().getBytes()); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - Intent result = api.executeApi(params, is, os); - switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, - OpenPgpApi.RESULT_CODE_ERROR)) { - case OpenPgpApi.RESULT_CODE_SUCCESS: - StringBuilder encryptedMessageBody = new StringBuilder(); - String[] lines = os.toString().split("\n"); - for (int i = 3; i < lines.length - 1; ++i) { - encryptedMessageBody.append(lines[i].trim()); - } - message.setEncryptedBody(encryptedMessageBody.toString()); - callback.success(); - return; - case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - callback.userInputRequried((PendingIntent) result - .getParcelableExtra(OpenPgpApi.RESULT_INTENT)); - return; - case OpenPgpApi.RESULT_CODE_ERROR: - callback.error((OpenPgpError) result - .getParcelableExtra(OpenPgpApi.RESULT_ERROR)); - return; + + public void encrypt(final Message message, final OnPgpEngineResult callback) { + try { + Log.d("xmppService","calling to encrypt file"); + JingleFile inputFile = this.mXmppConnectionService.getFileBackend().getJingleFile(message, true); + JingleFile outputFile = this.mXmppConnectionService.getFileBackend().getJingleFile(message, false); + outputFile.createNewFile(); + long[] keys = { message.getConversation().getContact().getPgpKeyId() }; + Intent params = new Intent(); + params.setAction(OpenPgpApi.ACTION_ENCRYPT); + params.putExtra(OpenPgpApi.EXTRA_KEY_IDS, keys); + params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, message.getConversation().getAccount().getJid()); + InputStream is = new FileInputStream(inputFile); + OutputStream os = new FileOutputStream(outputFile); + api.executeApiAsync(params, is, os, new IOpenPgpCallback() { + + @Override + public void onReturn(Intent result) { + switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, + OpenPgpApi.RESULT_CODE_ERROR)) { + case OpenPgpApi.RESULT_CODE_SUCCESS: + callback.success(); + break; + case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: + callback.userInputRequried((PendingIntent) result + .getParcelableExtra(OpenPgpApi.RESULT_INTENT)); + break; + case OpenPgpApi.RESULT_CODE_ERROR: + callback.error((OpenPgpError) result + .getParcelableExtra(OpenPgpApi.RESULT_ERROR)); + break; + } + } + }); + } catch (FileNotFoundException e) { + Log.d("xmppService","file not found: "+e.getMessage()); + } catch (IOException e) { + Log.d("xmppService","io exception during file encrypt"); } } @@ -130,10 +230,8 @@ public class PgpEngine { return 0; } case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - Log.d("xmppService","user interaction required"); return 0; case OpenPgpApi.RESULT_CODE_ERROR: - Log.d("xmppService","pgp error"); return 0; } return 0; -- cgit v1.2.3