diff options
author | Dominik Schürmann <dominik@dominikschuermann.de> | 2014-03-30 18:37:32 +0200 |
---|---|---|
committer | Dominik Schürmann <dominik@dominikschuermann.de> | 2014-03-30 19:32:05 +0200 |
commit | 2947ab7e483e90d054f88ed267ea1160fd5b2f1d (patch) | |
tree | 5add118788e7144c2a4d603eb46211ac376733d7 /OpenPGP-Keychain/src | |
parent | 4cec2194e01b7213271fa1fb0d50e5ae386fb16e (diff) | |
download | open-keychain-2947ab7e483e90d054f88ed267ea1160fd5b2f1d.tar.gz open-keychain-2947ab7e483e90d054f88ed267ea1160fd5b2f1d.tar.bz2 open-keychain-2947ab7e483e90d054f88ed267ea1160fd5b2f1d.zip |
More experimental work on decrypt fragments
Diffstat (limited to 'OpenPGP-Keychain/src')
14 files changed, 831 insertions, 516 deletions
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index 571729bc5..d06898c89 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -75,7 +75,7 @@ public class PgpDecryptVerify { // optional private ProgressDialogUpdater mProgressDialogUpdater = null; private boolean mAssumeSymmetric = false; - private String mPassphrase = ""; + private String mPassphrase = null; private long mEnforcedKeyId = 0; public Builder(Context context, InputData data, OutputStream outStream) { @@ -253,8 +253,6 @@ public class PgpDecryptVerify { encryptedData = pbe; currentProgress += 5; } else { - updateProgress(R.string.progress_finding_key, currentProgress, 100); - PGPPublicKeyEncryptedData pbe = null; PGPSecretKey secretKey = null; Iterator<?> it = enc.getEncryptedDataObjects(); @@ -262,6 +260,8 @@ public class PgpDecryptVerify { while (it.hasNext()) { Object obj = it.next(); if (obj instanceof PGPPublicKeyEncryptedData) { + updateProgress(R.string.progress_finding_key, currentProgress, 100); + PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj; secretKey = ProviderHelper.getPGPSecretKeyByKeyId(mContext, encData.getKeyID()); if (secretKey != null) { @@ -294,14 +294,15 @@ public class PgpDecryptVerify { // if passphrase was not cached, return here // indicating that a passphrase is missing! if (mPassphrase == null) { - returnData.setKeyPassphraseNeeded(true); + returnData.setKeyIdPassphraseNeeded(encData.getKeyID()); + returnData.setStatus(PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED); return returnData; } } break; } - + } else if (obj instanceof PGPPBEEncryptedData) { } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java index d4a4f6075..ad240e834 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java @@ -19,27 +19,33 @@ package org.sufficientlysecure.keychain.pgp; import android.os.Parcel; import android.os.Parcelable; + import org.openintents.openpgp.OpenPgpSignatureResult; public class PgpDecryptVerifyResult implements Parcelable { - boolean mSymmetricPassphraseNeeded; - boolean mKeyPassphraseNeeded; + public static final int SUCCESS = 1; + public static final int KEY_PASSHRASE_NEEDED = 2; + public static final int SYMMETRIC_PASSHRASE_NEEDED = 3; + + int mStatus; + long mKeyIdPassphraseNeeded; + OpenPgpSignatureResult mSignatureResult; - public boolean isSymmetricPassphraseNeeded() { - return mSymmetricPassphraseNeeded; + public int getStatus() { + return mStatus; } - public void setSymmetricPassphraseNeeded(boolean symmetricPassphraseNeeded) { - this.mSymmetricPassphraseNeeded = symmetricPassphraseNeeded; + public void setStatus(int mStatus) { + this.mStatus = mStatus; } - public boolean isKeyPassphraseNeeded() { - return mKeyPassphraseNeeded; + public long getKeyIdPassphraseNeeded() { + return mKeyIdPassphraseNeeded; } - public void setKeyPassphraseNeeded(boolean keyPassphraseNeeded) { - this.mKeyPassphraseNeeded = keyPassphraseNeeded; + public void setKeyIdPassphraseNeeded(long mKeyIdPassphraseNeeded) { + this.mKeyIdPassphraseNeeded = mKeyIdPassphraseNeeded; } public OpenPgpSignatureResult getSignatureResult() { @@ -55,8 +61,8 @@ public class PgpDecryptVerifyResult implements Parcelable { } public PgpDecryptVerifyResult(PgpDecryptVerifyResult b) { - this.mSymmetricPassphraseNeeded = b.mSymmetricPassphraseNeeded; - this.mKeyPassphraseNeeded = b.mKeyPassphraseNeeded; + this.mStatus = b.mStatus; + this.mKeyIdPassphraseNeeded = b.mKeyIdPassphraseNeeded; this.mSignatureResult = b.mSignatureResult; } @@ -66,16 +72,16 @@ public class PgpDecryptVerifyResult implements Parcelable { } public void writeToParcel(Parcel dest, int flags) { - dest.writeByte((byte) (mSymmetricPassphraseNeeded ? 1 : 0)); - dest.writeByte((byte) (mKeyPassphraseNeeded ? 1 : 0)); + dest.writeInt(mStatus); + dest.writeLong(mKeyIdPassphraseNeeded); dest.writeParcelable(mSignatureResult, 0); } public static final Creator<PgpDecryptVerifyResult> CREATOR = new Creator<PgpDecryptVerifyResult>() { public PgpDecryptVerifyResult createFromParcel(final Parcel source) { PgpDecryptVerifyResult vr = new PgpDecryptVerifyResult(); - vr.mSymmetricPassphraseNeeded = source.readByte() == 1; - vr.mKeyPassphraseNeeded = source.readByte() == 1; + vr.mStatus = source.readInt(); + vr.mKeyIdPassphraseNeeded = source.readLong(); vr.mSignatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader()); return vr; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java index 2680d77af..cc40afbac 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java @@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.pgp; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; + import org.spongycastle.openpgp.*; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; @@ -43,7 +44,7 @@ public class PgpHelper { public static final Pattern PGP_MESSAGE = Pattern.compile( ".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", Pattern.DOTALL); - public static final Pattern PGP_SIGNED_MESSAGE = Pattern + public static final Pattern PGP_CLEARTEXT_SIGNATURE = Pattern .compile( ".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*", Pattern.DOTALL); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index f85e342d8..1d3bb88df 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -298,11 +298,11 @@ public class OpenPgpService extends RemoteService { // TODO: currently does not support binary signed-only content PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute(); - if (decryptVerifyResult.isKeyPassphraseNeeded()) { + if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { // get PendingIntent for passphrase input, add it to given params and return to client Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId()); return passphraseBundle; - } else if (decryptVerifyResult.isSymmetricPassphraseNeeded()) { + } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { throw new PgpGeneralException("Decryption of symmetric content not supported by API!"); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 846eb8cf9..2cc3798e0 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -100,9 +100,9 @@ public class KeychainIntentService extends IntentService public static final String ENCRYPT_PROVIDER_URI = "provider_uri"; // decrypt/verify - public static final String DECRYPT_RETURN_BYTES = "return_binary"; public static final String DECRYPT_CIPHERTEXT_BYTES = "ciphertext_bytes"; public static final String DECRYPT_ASSUME_SYMMETRIC = "assume_symmetric"; + public static final String DECRYPT_PASSPHRASE = "passphrase"; // save keyring public static final String SAVE_KEYRING_PARCEL = "save_parcel"; @@ -155,7 +155,6 @@ public class KeychainIntentService extends IntentService public static final String RESULT_URI = "result_uri"; // decrypt/verify - public static final String RESULT_DECRYPTED_STRING = "decrypted_message"; public static final String RESULT_DECRYPTED_BYTES = "decrypted_data"; public static final String RESULT_DECRYPT_VERIFY_RESULT = "signature"; @@ -387,15 +386,14 @@ public class KeychainIntentService extends IntentService /* Input */ int target = data.getInt(TARGET); - long secretKeyId = data.getLong(ENCRYPT_SECRET_KEY_ID); byte[] bytes = data.getByteArray(DECRYPT_CIPHERTEXT_BYTES); - boolean returnBytes = data.getBoolean(DECRYPT_RETURN_BYTES); boolean assumeSymmetricEncryption = data.getBoolean(DECRYPT_ASSUME_SYMMETRIC); + String passphrase = data.getString(DECRYPT_PASSPHRASE); - InputStream inStream = null; - long inLength = -1; - InputData inputData = null; - OutputStream outStream = null; + InputStream inStream; + long inLength; + InputData inputData; + OutputStream outStream; String streamFilename = null; switch (target) { case TARGET_BYTES: /* decrypting bytes directly */ @@ -469,7 +467,7 @@ public class KeychainIntentService extends IntentService builder.progressDialogUpdater(this); builder.assumeSymmetric(assumeSymmetricEncryption) - .passphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); + .passphrase(passphrase); PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute(); @@ -481,15 +479,8 @@ public class KeychainIntentService extends IntentService switch (target) { case TARGET_BYTES: - if (returnBytes) { - byte output[] = ((ByteArrayOutputStream) outStream).toByteArray(); - resultData.putByteArray(RESULT_DECRYPTED_BYTES, output); - } else { - String output = new String( - ((ByteArrayOutputStream) outStream).toByteArray()); - resultData.putString(RESULT_DECRYPTED_STRING, output); - } - + byte output[] = ((ByteArrayOutputStream) outStream).toByteArray(); + resultData.putByteArray(RESULT_DECRYPTED_BYTES, output); break; case TARGET_URI: // nothing, file was written, just send okay and verification bundle diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index 24a8854af..21e51dcd9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -17,8 +17,6 @@ package org.sufficientlysecure.keychain.ui; -import android.annotation.SuppressLint; -import android.app.ProgressDialog; import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -30,7 +28,6 @@ import android.support.v4.view.PagerTabStrip; import android.support.v4.view.ViewPager; import android.view.View; import android.view.View.OnClickListener; -import android.view.animation.AnimationUtils; import android.widget.*; import com.beardedhen.androidbootstrap.BootstrapButton; @@ -41,21 +38,16 @@ import org.spongycastle.openpgp.PGPPublicKeyRing; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; import org.sufficientlysecure.keychain.helper.ActionBarHelper; import org.sufficientlysecure.keychain.helper.FileHelper; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; -import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.pgp.exception.NoAsymmetricEncryptionException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.service.KeychainIntentService; -import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.ui.adapter.PageTabStripAdapter; -import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.util.Log; @@ -64,7 +56,8 @@ import java.io.*; import java.util.regex.Matcher; //@SuppressLint("NewApi") -public class DecryptActivity extends DrawerActivity { +public class DecryptActivity extends DrawerActivity implements DecryptSignatureResultDisplay { + /* Intents */ // without permission @@ -122,43 +115,13 @@ public class DecryptActivity extends DrawerActivity { ViewPager mViewPager; PagerTabStrip mPagerTabStrip; PageTabStripAdapter mTabsAdapter; - DecryptMessageFragment mMessageFragment; - DecryptFileFragment mFileFragment; - private void initView() { -// mSource = (ViewFlipper) findViewById(R.id.source); -// mSourceLabel = (TextView) findViewById(R.id.sourceLabel); -// mSourcePrevious = (ImageView) findViewById(R.id.sourcePrevious); -// mSourceNext = (ImageView) findViewById(R.id.sourceNext); -// -// mSourcePrevious.setClickable(true); -// mSourcePrevious.setOnClickListener(new OnClickListener() { -// public void onClick(View v) { -// mSource.setInAnimation(AnimationUtils.loadAnimation(DecryptActivity.this, -// R.anim.push_right_in)); -// mSource.setOutAnimation(AnimationUtils.loadAnimation(DecryptActivity.this, -// R.anim.push_right_out)); -// mSource.showPrevious(); -// updateSource(); -// } -// }); -// -// mSourceNext.setClickable(true); -// OnClickListener nextSourceClickListener = new OnClickListener() { -// public void onClick(View v) { -// mSource.setInAnimation(AnimationUtils.loadAnimation(DecryptActivity.this, -// R.anim.push_left_in)); -// mSource.setOutAnimation(AnimationUtils.loadAnimation(DecryptActivity.this, -// R.anim.push_left_out)); -// mSource.showNext(); -// updateSource(); -// } -// }; -// mSourceNext.setOnClickListener(nextSourceClickListener); -// -// mSourceLabel.setClickable(true); -// mSourceLabel.setOnClickListener(nextSourceClickListener); + private static final int PAGER_TAB_MESSAGE = 0; + private static final int PAGER_TAB_FILE = 1; + + + private void initView() { mSignatureLayout = (RelativeLayout) findViewById(R.id.signature); mSignatureStatusImage = (ImageView) findViewById(R.id.ic_signature_status); mUserId = (TextView) findViewById(R.id.mainUserId); @@ -171,24 +134,24 @@ public class DecryptActivity extends DrawerActivity { // int height = tmp.getMeasuredHeight(); // mMessage.setMinimumHeight(height); - mFilename = (EditText) findViewById(R.id.filename); - mBrowse = (BootstrapButton) findViewById(R.id.btn_browse); - mBrowse.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - FileHelper.openFile(DecryptActivity.this, mFilename.getText().toString(), "*/*", - RESULT_CODE_FILE); - } - }); - - mLookupKey = (BootstrapButton) findViewById(R.id.lookup_key); - mLookupKey.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - lookupUnknownKey(mSignatureKeyId); - } - }); - - mDeleteAfter = (CheckBox) findViewById(R.id.deleteAfterDecryption); +// mFilename = (EditText) findViewById(R.id.filename); +// mBrowse = (BootstrapButton) findViewById(R.id.btn_browse); +// mBrowse.setOnClickListener(new View.OnClickListener() { +// public void onClick(View v) { +// FileHelper.openFile(DecryptActivity.this, mFilename.getText().toString(), "*/*", +// RESULT_CODE_FILE); +// } +// }); +// +// mLookupKey = (BootstrapButton) findViewById(R.id.lookup_key); +// mLookupKey.setOnClickListener(new OnClickListener() { +// @Override +// public void onClick(View v) { +// lookupUnknownKey(mSignatureKeyId); +// } +// }); +// +// mDeleteAfter = (CheckBox) findViewById(R.id.deleteAfterDecryption); // default: message source // mSource.setInAnimation(null); @@ -197,23 +160,19 @@ public class DecryptActivity extends DrawerActivity { // mSource.showNext(); // } - mDecryptButton = (BootstrapButton) findViewById(R.id.action_decrypt); - mDecryptButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - decryptClicked(); - } - }); +// mDecryptButton = (BootstrapButton) findViewById(R.id.action_decrypt); +// mDecryptButton.setOnClickListener(new OnClickListener() { +// @Override +// public void onClick(View v) { +// decryptClicked(); +// } +// }); + + // Pager mViewPager = (ViewPager) findViewById(R.id.decrypt_pager); mPagerTabStrip = (PagerTabStrip) findViewById(R.id.decrypt_pager_tab_strip); - initPager(); - } - private static final int PAGER_TAB_MESSAGE = 0; - private static final int PAGER_TAB_FILE = 1; - - private void initPager() { mTabsAdapter = new PageTabStripAdapter(this); mViewPager.setAdapter(mTabsAdapter); @@ -222,20 +181,9 @@ public class DecryptActivity extends DrawerActivity { Bundle fileBundle = new Bundle(); mTabsAdapter.addTab(DecryptFileFragment.class, fileBundle, getString(R.string.label_file)); - -// mPagerTabStrip. - getSupportFragmentManager().executePendingTransactions(); -// for (Fragment f : getSupportFragmentManager().getFragments()) { -// Log.d(Constants.TAG, "f: "+f.getTag()); -// } - - DecryptMessageFragment messageFragment = (DecryptMessageFragment) getFragmentByPosition(PAGER_TAB_MESSAGE); -// mFileFragment = (DecryptFileFragment) getFragmentByPosition(PAGER_TAB_FILE); - -// Log.d(Constants.TAG, fr.getTag()); -// } + /** * find fragment * @@ -265,26 +213,6 @@ public class DecryptActivity extends DrawerActivity { // Handle intent actions handleActions(getIntent()); -// if (mSource.getCurrentView().getId() == R.id.sourceMessage -// && mMessage.getText().length() == 0) { -// -// CharSequence clipboardText = ClipboardReflection.getClipboardText(this); -// -// String data = ""; -// if (clipboardText != null) { -// Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(clipboardText); -// if (!matcher.matches()) { -// matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(clipboardText); -// } -// if (matcher.matches()) { -// data = matcher.group(1); -// mMessage.setText(data); -// AppMsg.makeText(this, R.string.using_clipboard_content, AppMsg.STYLE_INFO) -// .show(); -// } -// } -// } - mSignatureLayout.setVisibility(View.GONE); mSignatureLayout.setOnClickListener(new OnClickListener() { public void onClick(View v) { @@ -301,27 +229,6 @@ public class DecryptActivity extends DrawerActivity { } } }); - -// if (mReturnResult) { -// mSourcePrevious.setClickable(false); -// mSourcePrevious.setEnabled(false); -// mSourcePrevious.setVisibility(View.INVISIBLE); -// -// mSourceNext.setClickable(false); -// mSourceNext.setEnabled(false); -// mSourceNext.setVisibility(View.INVISIBLE); -// -// mSourceLabel.setClickable(false); -// mSourceLabel.setEnabled(false); -// } -// -// updateSource(); - -// if (mDecryptImmediately -// || (mSource.getCurrentView().getId() == R.id.sourceMessage && (mMessage.getText() -// .length() > 0 || mContentUri != null))) { -// decryptClicked(); -// } } @@ -381,20 +288,20 @@ public class DecryptActivity extends DrawerActivity { // replace non breakable spaces textData = textData.replaceAll("\\xa0", " "); - mViewPager.setCurrentItem(PAGER_TAB_MESSAGE, false); - mMessageFragment.setText(textData); +// mViewPager.setCurrentItem(PAGER_TAB_MESSAGE, false); +// mMessageFragment.setText(textData); // mMessage.setText(textData); } else { - matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(textData); + matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(textData); if (matcher.matches()) { - Log.d(Constants.TAG, "PGP_SIGNED_MESSAGE matched"); + Log.d(Constants.TAG, "PGP_CLEARTEXT_SIGNATURE matched"); textData = matcher.group(1); // replace non breakable spaces textData = textData.replaceAll("\\xa0", " "); // mMessage.setText(textData); - mViewPager.setCurrentItem(PAGER_TAB_MESSAGE, false); - mMessageFragment = (DecryptMessageFragment) getFragmentByPosition(mViewPager.getCurrentItem()); - mMessageFragment.setText(textData); +// mViewPager.setCurrentItem(PAGER_TAB_MESSAGE, false); +// mMessageFragment = (DecryptMessageFragment) getFragmentByPosition(mViewPager.getCurrentItem()); +// mMessageFragment.setText(textData); } else { Log.d(Constants.TAG, "Nothing matched!"); } @@ -426,34 +333,14 @@ public class DecryptActivity extends DrawerActivity { } } - private void guessOutputFilename() { - mInputFilename = mFilename.getText().toString(); - File file = new File(mInputFilename); - String filename = file.getName(); - if (filename.endsWith(".asc") || filename.endsWith(".gpg") || filename.endsWith(".pgp")) { - filename = filename.substring(0, filename.length() - 4); - } - mOutputFilename = Constants.Path.APP_DIR + "/" + filename; - } - -// private void updateSource() { -// switch (mSource.getCurrentView().getId()) { -// case R.id.sourceFile: { -// mSourceLabel.setText(R.string.label_file); -// mDecryptButton.setText(getString(R.string.btn_decrypt)); -// break; -// } -// -// case R.id.sourceMessage: { -// mSourceLabel.setText(R.string.label_message); -// mDecryptButton.setText(getString(R.string.btn_decrypt)); -// break; -// } -// -// default: { -// break; -// } +// private void guessOutputFilename() { +// mInputFilename = mFilename.getText().toString(); +// File file = new File(mInputFilename); +// String filename = file.getName(); +// if (filename.endsWith(".asc") || filename.endsWith(".gpg") || filename.endsWith(".pgp")) { +// filename = filename.substring(0, filename.length() - 4); // } +// mOutputFilename = Constants.Path.APP_DIR + "/" + filename; // } private void decryptClicked() { @@ -492,7 +379,7 @@ public class DecryptActivity extends DrawerActivity { if (mDecryptTarget == Id.target.message) { // String messageData = mMessage.getText().toString(); -// Matcher matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(messageData); +// Matcher matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(messageData); // if (matcher.matches()) { // mSignedOnly = true; // decryptStart(); @@ -512,7 +399,7 @@ public class DecryptActivity extends DrawerActivity { if (mDecryptTarget == Id.target.file) { askForOutputFilename(); } else { // mDecryptTarget == Id.target.message - decryptStart(); +// decryptStart(); } } } @@ -531,7 +418,7 @@ public class DecryptActivity extends DrawerActivity { if (mDecryptTarget == Id.target.file) { askForOutputFilename(); } else { - decryptStart(); +// decryptStart(); } } } @@ -623,7 +510,7 @@ public class DecryptActivity extends DrawerActivity { if (message.what == FileDialogFragment.MESSAGE_OKAY) { Bundle data = message.getData(); mOutputFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); - decryptStart(); +// decryptStart(); } } }; @@ -645,156 +532,156 @@ public class DecryptActivity extends DrawerActivity { startActivityForResult(intent, RESULT_CODE_LOOKUP_KEY); } - private void decryptStart() { - Log.d(Constants.TAG, "decryptStart"); - - // Send all information needed to service to decrypt in other thread - Intent intent = new Intent(this, KeychainIntentService.class); - - // fill values for this action - Bundle data = new Bundle(); - - intent.setAction(KeychainIntentService.ACTION_DECRYPT_VERIFY); - - // choose action based on input: decrypt stream, file or bytes - if (mContentUri != null) { - data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_STREAM); - - data.putParcelable(KeychainIntentService.ENCRYPT_PROVIDER_URI, mContentUri); - } else if (mDecryptTarget == Id.target.file) { - data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_URI); - - Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename=" - + mOutputFilename); - - data.putString(KeychainIntentService.ENCRYPT_INPUT_FILE, mInputFilename); - data.putString(KeychainIntentService.ENCRYPT_OUTPUT_FILE, mOutputFilename); - } else { - data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES); - -// String message = mMessage.getText().toString(); -// data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, message.getBytes()); - } - - data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mSecretKeyId); - - data.putBoolean(KeychainIntentService.DECRYPT_RETURN_BYTES, mReturnBinary); - data.putBoolean(KeychainIntentService.DECRYPT_ASSUME_SYMMETRIC, mAssumeSymmetricEncryption); - - intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - - // Message is received after encrypting is done in KeychainIntentService - KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, - getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) { - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { - // get returned data bundle - Bundle returnData = message.getData(); - - mSignatureKeyId = 0; - mSignatureLayout.setVisibility(View.GONE); - - AppMsg.makeText(DecryptActivity.this, R.string.decryption_successful, - AppMsg.STYLE_INFO).show(); -// if (mReturnResult) { -// Intent intent = new Intent(); -// intent.putExtras(returnData); -// setResult(RESULT_OK, intent); -// finish(); -// return; +// private void decryptStart() { +// Log.d(Constants.TAG, "decryptStart"); +// +// // Send all information needed to service to decrypt in other thread +// Intent intent = new Intent(this, KeychainIntentService.class); +// +// // fill values for this action +// Bundle data = new Bundle(); +// +// intent.setAction(KeychainIntentService.ACTION_DECRYPT_VERIFY); +// +// // choose action based on input: decrypt stream, file or bytes +// if (mContentUri != null) { +// data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_STREAM); +// +// data.putParcelable(KeychainIntentService.ENCRYPT_PROVIDER_URI, mContentUri); +// } else if (mDecryptTarget == Id.target.file) { +// data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_URI); +// +// Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename=" +// + mOutputFilename); +// +// data.putString(KeychainIntentService.ENCRYPT_INPUT_FILE, mInputFilename); +// data.putString(KeychainIntentService.ENCRYPT_OUTPUT_FILE, mOutputFilename); +// } else { +// data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES); +// +//// String message = mMessage.getText().toString(); +//// data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, message.getBytes()); +// } +// +// data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mSecretKeyId); +// +// data.putBoolean(KeychainIntentService.DECRYPT_RETURN_BYTES, mReturnBinary); +// data.putBoolean(KeychainIntentService.DECRYPT_ASSUME_SYMMETRIC, mAssumeSymmetricEncryption); +// +// intent.putExtra(KeychainIntentService.EXTRA_DATA, data); +// +// // Message is received after encrypting is done in KeychainIntentService +// KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, +// getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) { +// public void handleMessage(Message message) { +// // handle messages by standard KeychainIntentServiceHandler first +// super.handleMessage(message); +// +// if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { +// // get returned data bundle +// Bundle returnData = message.getData(); +// +// mSignatureKeyId = 0; +// mSignatureLayout.setVisibility(View.GONE); +// +// AppMsg.makeText(DecryptActivity.this, R.string.decryption_successful, +// AppMsg.STYLE_INFO).show(); +//// if (mReturnResult) { +//// Intent intent = new Intent(); +//// intent.putExtras(returnData); +//// setResult(RESULT_OK, intent); +//// finish(); +//// return; +//// } +// +// switch (mDecryptTarget) { +// case Id.target.message: +// String decryptedMessage = returnData +// .getString(KeychainIntentService.RESULT_DECRYPTED_STRING); +//// mMessage.setText(decryptedMessage); +//// mMessage.setHorizontallyScrolling(false); +// +// break; +// +// case Id.target.file: +// if (mDeleteAfter.isChecked()) { +// // Create and show dialog to delete original file +// DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment +// .newInstance(mInputFilename); +// deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog"); +// } +// break; +// +// default: +// // shouldn't happen +// break; +// // } - - switch (mDecryptTarget) { - case Id.target.message: - String decryptedMessage = returnData - .getString(KeychainIntentService.RESULT_DECRYPTED_STRING); -// mMessage.setText(decryptedMessage); -// mMessage.setHorizontallyScrolling(false); - - break; - - case Id.target.file: - if (mDeleteAfter.isChecked()) { - // Create and show dialog to delete original file - DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment - .newInstance(mInputFilename); - deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog"); - } - break; - - default: - // shouldn't happen - break; - - } - - PgpDecryptVerifyResult decryptVerifyResult = - returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT); - - OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult(); - - if (signatureResult != null) { - - String userId = signatureResult.getUserId(); - mSignatureKeyId = signatureResult.getKeyId(); - mUserIdRest.setText("id: " - + PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId)); - if (userId == null) { - userId = getResources().getString(R.string.user_id_no_name); - } - String chunks[] = userId.split(" <", 2); - userId = chunks[0]; - if (chunks.length > 1) { - mUserIdRest.setText("<" + chunks[1]); - } - mUserId.setText(userId); - - switch (signatureResult.getStatus()) { - case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: { - mSignatureStatusImage.setImageResource(R.drawable.overlay_ok); - mLookupKey.setVisibility(View.GONE); - break; - } - - // TODO! -// case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: { +// +// PgpDecryptVerifyResult decryptVerifyResult = +// returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT); +// +// OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult(); +// +// if (signatureResult != null) { +// +// String userId = signatureResult.getUserId(); +// mSignatureKeyId = signatureResult.getKeyId(); +// mUserIdRest.setText("id: " +// + PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId)); +// if (userId == null) { +// userId = getResources().getString(R.string.user_id_no_name); +// } +// String chunks[] = userId.split(" <", 2); +// userId = chunks[0]; +// if (chunks.length > 1) { +// mUserIdRest.setText("<" + chunks[1]); +// } +// mUserId.setText(userId); +// +// switch (signatureResult.getStatus()) { +// case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: { +// mSignatureStatusImage.setImageResource(R.drawable.overlay_ok); +// mLookupKey.setVisibility(View.GONE); // break; // } - - case OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY: { - mSignatureStatusImage.setImageResource(R.drawable.overlay_error); - mLookupKey.setVisibility(View.VISIBLE); - AppMsg.makeText(DecryptActivity.this, - R.string.unknown_signature, - AppMsg.STYLE_ALERT).show(); - break; - } - - default: { - mSignatureStatusImage.setImageResource(R.drawable.overlay_error); - mLookupKey.setVisibility(View.GONE); - break; - } - } - mSignatureLayout.setVisibility(View.VISIBLE); - } - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); - - // show progress dialog - saveHandler.showProgressDialog(this); - - // start service with intent - startService(intent); - } +// +// // TODO! +//// case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: { +//// break; +//// } +// +// case OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY: { +// mSignatureStatusImage.setImageResource(R.drawable.overlay_error); +// mLookupKey.setVisibility(View.VISIBLE); +// AppMsg.makeText(DecryptActivity.this, +// R.string.unknown_signature, +// AppMsg.STYLE_ALERT).show(); +// break; +// } +// +// default: { +// mSignatureStatusImage.setImageResource(R.drawable.overlay_error); +// mLookupKey.setVisibility(View.GONE); +// break; +// } +// } +// mSignatureLayout.setVisibility(View.VISIBLE); +// } +// } +// } +// }; +// +// // Create a new Messenger for the communication back +// Messenger messenger = new Messenger(saveHandler); +// intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); +// +// // show progress dialog +// saveHandler.showProgressDialog(this); +// +// // start service with intent +// startService(intent); +// } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { @@ -819,7 +706,7 @@ public class DecryptActivity extends DrawerActivity { Log.d(Constants.TAG, "Returning from Lookup Key..."); if (resultCode == RESULT_OK) { // decrypt again - decryptStart(); +// decryptStart(); } return; } @@ -832,4 +719,55 @@ public class DecryptActivity extends DrawerActivity { } } + @Override + public void onSignatureResult(OpenPgpSignatureResult signatureResult) { + + mSignatureKeyId = 0; + mSignatureLayout.setVisibility(View.GONE); + if (signatureResult != null) { + + String userId = signatureResult.getUserId(); + mSignatureKeyId = signatureResult.getKeyId(); + mUserIdRest.setText("id: " + + PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId)); + if (userId == null) { + userId = getResources().getString(R.string.user_id_no_name); + } + String chunks[] = userId.split(" <", 2); + userId = chunks[0]; + if (chunks.length > 1) { + mUserIdRest.setText("<" + chunks[1]); + } + mUserId.setText(userId); + + switch (signatureResult.getStatus()) { + case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: { + mSignatureStatusImage.setImageResource(R.drawable.overlay_ok); + mLookupKey.setVisibility(View.GONE); + break; + } + + // TODO! +// case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: { +// break; +// } + + case OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY: { + mSignatureStatusImage.setImageResource(R.drawable.overlay_error); + mLookupKey.setVisibility(View.VISIBLE); + AppMsg.makeText(DecryptActivity.this, + R.string.unknown_signature, + AppMsg.STYLE_ALERT).show(); + break; + } + + default: { + mSignatureStatusImage.setImageResource(R.drawable.overlay_error); + mLookupKey.setVisibility(View.GONE); + break; + } + } + mSignatureLayout.setVisibility(View.VISIBLE); + } + } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java index 0c8fd8c83..3d40eaf09 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java @@ -18,17 +18,39 @@ package org.sufficientlysecure.keychain.ui; import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.CheckBox; import android.widget.EditText; +import com.beardedhen.androidbootstrap.BootstrapButton; +import com.devspark.appmsg.AppMsg; + +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.FileHelper; +import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment; + +import java.io.File; public class DecryptFileFragment extends Fragment { - private EditText mMessage; + private EditText mFilename; + private CheckBox mDeleteAfter; + private BootstrapButton mBrowse; + private BootstrapButton mDecryptButton; + + + private String mInputFilename = null; + private String mOutputFilename = null; + + private static final int RESULT_CODE_FILE = 0x00007003; + /** * Creates new instance of this fragment @@ -49,14 +71,88 @@ public class DecryptFileFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.decrypt_file_fragment, container, false); - mMessage = (EditText) view.findViewById(R.id.message); + mFilename = (EditText) findViewById(R.id.filename); + mBrowse = (BootstrapButton) findViewById(R.id.btn_browse); + mBrowse.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + FileHelper.openFile(DecryptActivity.this, mFilename.getText().toString(), "*/*", + RESULT_CODE_FILE); + } + }); + mDeleteAfter = (CheckBox) findViewById(R.id.deleteAfterDecryption); + mDecryptButton = (BootstrapButton) view.findViewById(R.id.action_decrypt); + mDecryptButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + decryptAction(); + } + }); return view; } + private void guessOutputFilename() { + mInputFilename = mFilename.getText().toString(); + File file = new File(mInputFilename); + String filename = file.getName(); + if (filename.endsWith(".asc") || filename.endsWith(".gpg") || filename.endsWith(".pgp")) { + filename = filename.substring(0, filename.length() - 4); + } + mOutputFilename = Constants.Path.APP_DIR + "/" + filename; + } + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } + private void decryptAction() { + String currentFilename = mFilename.getText().toString(); + if (mInputFilename == null || !mInputFilename.equals(currentFilename)) { + guessOutputFilename(); + } + + if (mInputFilename.equals("")) { + AppMsg.makeText(getActivity(), R.string.no_file_selected, AppMsg.STYLE_ALERT).show(); + return; + } + + if (mInputFilename.startsWith("file")) { + File file = new File(mInputFilename); + if (!file.exists() || !file.isFile()) { + AppMsg.makeText( + getActivity(), + getString(R.string.error_message, + getString(R.string.error_file_not_found)), AppMsg.STYLE_ALERT) + .show(); + return; + } + } + + askForOutputFilename(); + } + + private void askForOutputFilename() { + // Message is received after passphrase is cached + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == FileDialogFragment.MESSAGE_OKAY) { + Bundle data = message.getData(); + mOutputFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); +// decryptStart(); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + mFileDialog = FileDialogFragment.newInstance(messenger, + getString(R.string.title_decrypt_to_file), + getString(R.string.specify_file_to_decrypt_to), mOutputFilename, null); + + mFileDialog.show(getSupportFragmentManager(), "fileDialog"); + } + } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java index 3fa7e89ba..c6724f6d1 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java @@ -17,7 +17,13 @@ package org.sufficientlysecure.keychain.ui; +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Intent; import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; @@ -26,27 +32,30 @@ import android.view.ViewGroup; import android.widget.EditText; import com.beardedhen.androidbootstrap.BootstrapButton; +import com.devspark.appmsg.AppMsg; +import org.openintents.openpgp.OpenPgpSignatureResult; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; +import org.sufficientlysecure.keychain.pgp.PgpHelper; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; +import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.util.Log; +import java.util.regex.Matcher; + public class DecryptMessageFragment extends Fragment { + DecryptSignatureResultDisplay mSignatureResultDisplay; private EditText mMessage; + private BootstrapButton mDecryptButton; + private BootstrapButton mDecryptFromCLipboardButton; - /** - * Creates new instance of this fragment - */ - public static DecryptMessageFragment newInstance() { - DecryptMessageFragment frag = new DecryptMessageFragment(); - - Bundle args = new Bundle(); - frag.setArguments(args); - - return frag; - } + public static final String EXTRA_CIPHERTEXT = "ciphertext"; /** * Inflate the layout for this fragment @@ -56,23 +65,175 @@ public class DecryptMessageFragment extends Fragment { View view = inflater.inflate(R.layout.decrypt_message_fragment, container, false); mMessage = (EditText) view.findViewById(R.id.message); + mDecryptButton = (BootstrapButton) view.findViewById(R.id.action_decrypt); + mDecryptFromCLipboardButton = (BootstrapButton) view.findViewById(R.id.action_decrypt_from_clipboard); + + String ciphertext = getArguments().getString(EXTRA_CIPHERTEXT); + if (ciphertext != null) { + mMessage.setText(ciphertext); + } + + mDecryptButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + decryptAction(); + } + }); + + mDecryptFromCLipboardButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + decryptFromClipboard(); + } + }); return view; } @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + try { + mSignatureResultDisplay = (DecryptSignatureResultDisplay) activity; + } catch (ClassCastException e) { + throw new ClassCastException(activity.toString() + " must implement DecryptSignatureResultDisplay"); + } + } + + + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - Log.d(Constants.TAG, "tag: " + getTag()); + Log.d(Constants.TAG, "onActivityCreated tag: " + getTag()); + + } - public String getText() { - return mMessage.getText().toString(); + private void decryptFromClipboard() { + CharSequence clipboardText = ClipboardReflection.getClipboardText(getActivity()); + + if (clipboardText != null) { + Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(clipboardText); + if (!matcher.matches()) { + matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(clipboardText); + } + if (matcher.matches()) { + String data = matcher.group(1); + mMessage.setText(data); + decryptStart(null); + } else { + AppMsg.makeText(getActivity(), R.string.error_invalid_data, AppMsg.STYLE_INFO) + .show(); + } + } else { + AppMsg.makeText(getActivity(), R.string.error_invalid_data, AppMsg.STYLE_INFO) + .show(); + } } - public void setText(String message) { - mMessage.setText(message); + private void decryptAction() { + decryptStart(null); } + private void decryptStart(String passphrase) { + Log.d(Constants.TAG, "decryptStart"); + + // Send all information needed to service to decrypt in other thread + Intent intent = new Intent(getActivity(), KeychainIntentService.class); + + // fill values for this action + Bundle data = new Bundle(); + + intent.setAction(KeychainIntentService.ACTION_DECRYPT_VERIFY); + + // data + data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES); + String message = mMessage.getText().toString(); + data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, message.getBytes()); + data.putString(KeychainIntentService.DECRYPT_PASSPHRASE, passphrase); + + // TODO + data.putBoolean(KeychainIntentService.DECRYPT_ASSUME_SYMMETRIC, false); + + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + + // Message is received after encrypting is done in KeychainIntentService + KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(), + getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + + if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { + // get returned data bundle + Bundle returnData = message.getData(); + + + PgpDecryptVerifyResult decryptVerifyResult = + returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT); + + if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { + showPassphraseDialog(decryptVerifyResult.getKeyIdPassphraseNeeded()); + } else { + + AppMsg.makeText(getActivity(), R.string.decryption_successful, + AppMsg.STYLE_INFO).show(); + + byte[] decryptedMessage = returnData + .getByteArray(KeychainIntentService.RESULT_DECRYPTED_BYTES); + mMessage.setText(new String(decryptedMessage)); + mMessage.setHorizontallyScrolling(false); + + + OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult(); + + // display signature result in activity + mSignatureResultDisplay.onSignatureResult(signatureResult); + } + + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + + // show progress dialog + saveHandler.showProgressDialog(getActivity()); + + // start service with intent + getActivity().startService(intent); + } + + private void showPassphraseDialog(long keyId) { + // Message is received after passphrase is cached + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { + String passphrase = + message.getData().getString(PassphraseDialogFragment.MESSAGE_DATA_PASSPHRASE); + decryptStart(passphrase); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + try { + PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(getActivity(), + messenger, keyId); + + passphraseDialog.show(getActivity().getSupportFragmentManager(), "passphraseDialog"); + } catch (PgpGeneralException e) { + Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); + // send message to handler to start encryption directly + returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); + } + } + + } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptSignatureResultDisplay.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptSignatureResultDisplay.java new file mode 100644 index 000000000..e167064ec --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptSignatureResultDisplay.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.ui; + +import org.openintents.openpgp.OpenPgpSignatureResult; + +public interface DecryptSignatureResultDisplay { + + public void onSignatureResult(OpenPgpSignatureResult result); + +} + diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java index 271219fa3..3c8b872b0 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java @@ -59,6 +59,8 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor public static final int MESSAGE_OKAY = 1; public static final int MESSAGE_CANCEL = 2; + public static final String MESSAGE_DATA_PASSPHRASE = "passphrase"; + private Messenger mMessenger; private EditText mPassphraseEditText; private boolean mCanKB; @@ -209,7 +211,11 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor passphrase); } - sendMessageToHandler(MESSAGE_OKAY); + // also return passphrase back to activity + Bundle data = new Bundle(); + data.putString(MESSAGE_DATA_PASSPHRASE, passphrase); + + sendMessageToHandler(MESSAGE_OKAY, data); } }); @@ -278,4 +284,25 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor } } + /** + * Send message back to handler which is initialized in a activity + * + * @param what Message integer you want to send + */ + private void sendMessageToHandler(Integer what, Bundle data) { + Message msg = Message.obtain(); + msg.what = what; + if (data != null) { + msg.setData(data); + } + + try { + mMessenger.send(msg); + } catch (RemoteException e) { + Log.w(Constants.TAG, "Exception sending message, Is handler present?", e); + } catch (NullPointerException e) { + Log.w(Constants.TAG, "Messenger is null!", e); + } + } + } diff --git a/OpenPGP-Keychain/src/main/res/layout/decrypt_content.xml b/OpenPGP-Keychain/src/main/res/layout/decrypt_content.xml index f48d4401b..4ba379c2e 100644 --- a/OpenPGP-Keychain/src/main/res/layout/decrypt_content.xml +++ b/OpenPGP-Keychain/src/main/res/layout/decrypt_content.xml @@ -8,7 +8,7 @@ <android.support.v4.view.ViewPager android:id="@+id/decrypt_pager" android:layout_width="match_parent" - android:layout_height="220dp"> + android:layout_height="match_parent"> <android.support.v4.view.PagerTabStrip android:id="@+id/decrypt_pager_tab_strip" @@ -38,128 +38,107 @@ <include layout="@layout/decrypt_signature_include" /> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal"> - - <ImageView - android:id="@+id/sourcePrevious" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:src="@drawable/ic_previous" /> - - <TextView - android:id="@+id/sourceLabel" - style="@style/SectionHeader" - android:layout_width="0dip" - android:layout_height="match_parent" - android:layout_weight="1" - android:gravity="center_horizontal|center_vertical" - android:text="@string/label_message" - android:textAppearance="?android:attr/textAppearanceMedium" /> - - <ImageView - android:id="@+id/sourceNext" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:src="@drawable/ic_next" /> - </LinearLayout> - - <ViewFlipper - android:id="@+id/source" - android:layout_width="match_parent" - android:layout_height="0dip" - android:layout_weight="1"> - - <LinearLayout - android:id="@+id/sourceMessage" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" - android:padding="4dp"> - - <EditText - android:id="@+id/message" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:gravity="top" - android:inputType="text|textCapSentences|textMultiLine|textLongMessage" - android:scrollHorizontally="true" /> - </LinearLayout> - - <LinearLayout - android:id="@+id/sourceFile" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" - android:padding="4dp"> - - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal"> - - <EditText - android:id="@+id/filename" - android:layout_width="0dip" - android:layout_height="wrap_content" - android:layout_weight="1" - android:gravity="top|left" - android:inputType="textMultiLine|textUri" - android:lines="4" - android:maxLines="10" - android:minLines="2" - android:scrollbars="vertical" /> - - <com.beardedhen.androidbootstrap.BootstrapButton - android:id="@+id/btn_browse" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_margin="4dp" - bootstrapbutton:bb_icon_left="fa-folder-open" - bootstrapbutton:bb_roundedCorners="true" - bootstrapbutton:bb_size="default" - bootstrapbutton:bb_type="default" /> - </LinearLayout> - - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal"> - - <CheckBox - android:id="@+id/deleteAfterDecryption" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center_vertical" - android:text="@string/label_delete_after_decryption" /> - </LinearLayout> - </LinearLayout> - </ViewFlipper> - - <TextView - style="@style/SectionHeader" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginBottom="4dp" - android:text="@string/section_decrypt_verify" /> - - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - android:padding="4dp"> - - <com.beardedhen.androidbootstrap.BootstrapButton - android:id="@+id/action_decrypt" - android:layout_width="match_parent" - android:layout_height="60dp" - android:padding="4dp" - android:text="@string/btn_decrypt_verify" - bootstrapbutton:bb_icon_left="fa-unlock" - bootstrapbutton:bb_type="info" /> - </LinearLayout> + <!--<LinearLayout--> + <!--android:layout_width="match_parent"--> + <!--android:layout_height="wrap_content"--> + <!--android:orientation="horizontal">--> + + <!--<ImageView--> + <!--android:id="@+id/sourcePrevious"--> + <!--android:layout_width="wrap_content"--> + <!--android:layout_height="wrap_content"--> + <!--android:src="@drawable/ic_previous" />--> + + <!--<TextView--> + <!--android:id="@+id/sourceLabel"--> + <!--style="@style/SectionHeader"--> + <!--android:layout_width="0dip"--> + <!--android:layout_height="match_parent"--> + <!--android:layout_weight="1"--> + <!--android:gravity="center_horizontal|center_vertical"--> + <!--android:text="@string/label_message"--> + <!--android:textAppearance="?android:attr/textAppearanceMedium" />--> + + <!--<ImageView--> + <!--android:id="@+id/sourceNext"--> + <!--android:layout_width="wrap_content"--> + <!--android:layout_height="wrap_content"--> + <!--android:src="@drawable/ic_next" />--> + <!--</LinearLayout>--> + + <!--<ViewFlipper--> + <!--android:id="@+id/source"--> + <!--android:layout_width="match_parent"--> + <!--android:layout_height="0dip"--> + <!--android:layout_weight="1">--> + + <!--<LinearLayout--> + <!--android:id="@+id/sourceMessage"--> + <!--android:layout_width="match_parent"--> + <!--android:layout_height="match_parent"--> + <!--android:orientation="vertical"--> + <!--android:padding="4dp">--> + + <!--<EditText--> + <!--android:id="@+id/message"--> + <!--android:layout_width="match_parent"--> + <!--android:layout_height="match_parent"--> + <!--android:gravity="top"--> + <!--android:inputType="text|textCapSentences|textMultiLine|textLongMessage"--> + <!--android:scrollHorizontally="true" />--> + <!--</LinearLayout>--> + + <!--<LinearLayout--> + <!--android:id="@+id/sourceFile"--> + <!--android:layout_width="match_parent"--> + <!--android:layout_height="match_parent"--> + <!--android:orientation="vertical"--> + <!--android:padding="4dp">--> + + <!--<LinearLayout--> + <!--android:layout_width="match_parent"--> + <!--android:layout_height="wrap_content"--> + <!--android:orientation="horizontal">--> + + <!--<EditText--> + <!--android:id="@+id/filename"--> + <!--android:layout_width="0dip"--> + <!--android:layout_height="wrap_content"--> + <!--android:layout_weight="1"--> + <!--android:gravity="top|left"--> + <!--android:inputType="textMultiLine|textUri"--> + <!--android:lines="4"--> + <!--android:maxLines="10"--> + <!--android:minLines="2"--> + <!--android:scrollbars="vertical" />--> + + <!--<com.beardedhen.androidbootstrap.BootstrapButton--> + <!--android:id="@+id/btn_browse"--> + <!--android:layout_width="wrap_content"--> + <!--android:layout_height="wrap_content"--> + <!--android:layout_margin="4dp"--> + <!--bootstrapbutton:bb_icon_left="fa-folder-open"--> + <!--bootstrapbutton:bb_roundedCorners="true"--> + <!--bootstrapbutton:bb_size="default"--> + <!--bootstrapbutton:bb_type="default" />--> + <!--</LinearLayout>--> + + <!--<LinearLayout--> + <!--android:layout_width="match_parent"--> + <!--android:layout_height="wrap_content"--> + <!--android:orientation="horizontal">--> + + <!--<CheckBox--> + <!--android:id="@+id/deleteAfterDecryption"--> + <!--android:layout_width="wrap_content"--> + <!--android:layout_height="wrap_content"--> + <!--android:layout_gravity="center_vertical"--> + <!--android:text="@string/label_delete_after_decryption" />--> + <!--</LinearLayout>--> + <!--</LinearLayout>--> + <!--</ViewFlipper>--> + + </LinearLayout> </ScrollView> </LinearLayout>
\ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/decrypt_file_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/decrypt_file_fragment.xml index f221ff8de..7347d222c 100644 --- a/OpenPGP-Keychain/src/main/res/layout/decrypt_file_fragment.xml +++ b/OpenPGP-Keychain/src/main/res/layout/decrypt_file_fragment.xml @@ -1,14 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" + android:paddingTop="4dp" + android:paddingLeft="10dp" + android:paddingRight="10dp" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="horizontal"> + android:orientation="horizontal" + android:layout_alignParentTop="true" + android:id="@+id/linearLayout"> <EditText android:id="@+id/filename" @@ -38,11 +43,44 @@ android:layout_height="wrap_content" android:orientation="horizontal"> - <CheckBox - android:id="@+id/deleteAfterDecryption" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center_vertical" - android:text="@string/label_delete_after_decryption" /> </LinearLayout> -</LinearLayout>
\ No newline at end of file + + <TextView + style="@style/SectionHeader" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/section_decrypt_verify" + android:layout_above="@+id/action_decrypt" + android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:padding="4dp"> + + </LinearLayout> + + <com.beardedhen.androidbootstrap.BootstrapButton + android:id="@+id/action_decrypt" + android:layout_width="match_parent" + android:layout_height="60dp" + android:padding="4dp" + android:text="@string/btn_decrypt_verify" + bootstrapbutton:bb_icon_left="fa-unlock" + bootstrapbutton:bb_type="info" + android:layout_alignParentBottom="true" + android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" /> + + <CheckBox + android:id="@+id/deleteAfterDecryption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:text="@string/label_delete_after_decryption" + android:layout_below="@+id/linearLayout" + android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" /> +</RelativeLayout>
\ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/decrypt_message_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/decrypt_message_fragment.xml index 3deee0eca..f11f79c1e 100644 --- a/OpenPGP-Keychain/src/main/res/layout/decrypt_message_fragment.xml +++ b/OpenPGP-Keychain/src/main/res/layout/decrypt_message_fragment.xml @@ -1,15 +1,64 @@ <?xml version="1.0" encoding="utf-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical"> + android:layout_height="match_parent" + android:fillViewport="true"> - <EditText - android:id="@+id/message" + <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" - android:gravity="top" - android:inputType="text|textCapSentences|textMultiLine|textLongMessage" - android:scrollHorizontally="true" /> -</LinearLayout> + android:paddingTop="4dp" + android:paddingLeft="10dp" + android:paddingRight="10dp" + android:orientation="vertical"> + + <EditText + android:id="@+id/message" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="top" + android:inputType="text|textCapSentences|textMultiLine|textLongMessage" + android:scrollHorizontally="true" + android:layout_above="@+id/decrypt_message_section" + android:layout_alignParentStart="true" /> + + <TextView + style="@style/SectionHeader" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/section_decrypt_verify" + android:layout_above="@+id/decrypt_buttons" + android:layout_alignParentEnd="true" + android:id="@+id/decrypt_message_section" /> + + <LinearLayout + android:id="@+id/decrypt_buttons" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:padding="4dp" + android:layout_alignParentBottom="true"> + + <com.beardedhen.androidbootstrap.BootstrapButton + android:id="@+id/action_decrypt" + android:layout_width="match_parent" + android:layout_height="60dp" + android:layout_weight="1" + android:padding="4dp" + android:text="@string/btn_decrypt_verify" + bootstrapbutton:bb_icon_left="fa-unlock" + bootstrapbutton:bb_type="info" /> + + <com.beardedhen.androidbootstrap.BootstrapButton + android:id="@+id/action_decrypt_from_clipboard" + android:layout_width="match_parent" + android:layout_height="60dp" + android:layout_weight="1" + android:padding="4dp" + android:text="@string/btn_decrypt_verify_clipboard" + bootstrapbutton:bb_icon_left="fa-unlock" + bootstrapbutton:bb_type="info" /> + </LinearLayout> + </RelativeLayout> +</ScrollView> diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml index 2e88062b7..5d325d5ec 100644 --- a/OpenPGP-Keychain/src/main/res/values/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values/strings.xml @@ -51,6 +51,7 @@ <string name="btn_certify">Certify</string> <string name="btn_decrypt">Decrypt</string> <string name="btn_decrypt_verify">Decrypt and Verify</string> + <string name="btn_decrypt_verify_clipboard">From Clipboard</string> <string name="btn_select_encrypt_keys">Select Recipients</string> <string name="btn_encrypt_file">Encrypt File</string> <string name="btn_save">Save</string> |