aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2014-08-11 17:10:47 +0200
committerDominik Schürmann <dominik@dominikschuermann.de>2014-08-11 17:10:47 +0200
commitb67356503511725df1b016d8a8513b6356cb450a (patch)
treea8a6a056fd25dfc1c9bce7d9b754c694771e94a1
parent549feb69ed0a339f8320f52da9246aac74b60ba1 (diff)
downloadopen-keychain-b67356503511725df1b016d8a8513b6356cb450a.tar.gz
open-keychain-b67356503511725df1b016d8a8513b6356cb450a.tar.bz2
open-keychain-b67356503511725df1b016d8a8513b6356cb450a.zip
Get original filename for decryption
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java23
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java81
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java95
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java9
4 files changed, 188 insertions, 20 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
index 6ce483989..2ab93ca41 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
@@ -71,6 +71,7 @@ public class PgpDecryptVerify {
private boolean mAllowSymmetricDecryption;
private String mPassphrase;
private Set<Long> mAllowedKeyIds;
+ private boolean mReturnMetadataOnly;
private PgpDecryptVerify(Builder builder) {
// private Constructor can only be called from Builder
@@ -83,6 +84,7 @@ public class PgpDecryptVerify {
this.mAllowSymmetricDecryption = builder.mAllowSymmetricDecryption;
this.mPassphrase = builder.mPassphrase;
this.mAllowedKeyIds = builder.mAllowedKeyIds;
+ this.mReturnMetadataOnly = builder.mReturnMetadataOnly;
}
public static class Builder {
@@ -97,6 +99,7 @@ public class PgpDecryptVerify {
private boolean mAllowSymmetricDecryption = true;
private String mPassphrase = null;
private Set<Long> mAllowedKeyIds = null;
+ private boolean mReturnMetadataOnly = false;
public Builder(ProviderHelper providerHelper, PassphraseCache passphraseCache,
InputData data, OutputStream outStream) {
@@ -126,7 +129,16 @@ public class PgpDecryptVerify {
* This means only ciphertexts encrypted for one of these private key can be decrypted.
*/
public Builder setAllowedKeyIds(Set<Long> allowedKeyIds) {
- this.mAllowedKeyIds = allowedKeyIds;
+ mAllowedKeyIds = allowedKeyIds;
+ return this;
+ }
+
+ /**
+ * If enabled, the actual decryption/verification of the content will not be executed.
+ * The metadata only will be decrypted and returned.
+ */
+ public Builder setReturnMetadataOnly(boolean returnMetadataOnly) {
+ mReturnMetadataOnly = returnMetadataOnly;
return this;
}
@@ -442,7 +454,7 @@ public class PgpDecryptVerify {
PGPLiteralData literalData = (PGPLiteralData) dataChunk;
// TODO: how to get the real original size?
- // this is the encrypted size
+ // this is the encrypted size so if we enable compression this value is wrong!
long originalSize = mData.getSize() - mData.getStreamPosition();
if (originalSize < 0) {
originalSize = 0;
@@ -455,6 +467,13 @@ public class PgpDecryptVerify {
originalSize);
result.setDecryptMetadata(metadata);
+ Log.d(Constants.TAG, "metadata: " + metadata);
+
+ // return here if we want to decrypt the metadata only
+ if (mReturnMetadataOnly) {
+ return result;
+ }
+
int endProgress;
if (signature != null) {
endProgress = 90;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
index 30108d52d..680f2fb27 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
@@ -86,6 +86,8 @@ public class KeychainIntentService extends IntentService
public static final String ACTION_DECRYPT_VERIFY = Constants.INTENT_PREFIX + "DECRYPT_VERIFY";
+ public static final String ACTION_DECRYPT_METADATA = Constants.INTENT_PREFIX + "DECRYPT_METADATA";
+
public static final String ACTION_SAVE_KEYRING = Constants.INTENT_PREFIX + "SAVE_KEYRING";
public static final String ACTION_DELETE_FILE_SECURELY = Constants.INTENT_PREFIX
@@ -241,6 +243,7 @@ public class KeychainIntentService extends IntentService
data.putInt(SELECTED_URI, i);
InputData inputData = createEncryptInputData(data);
OutputStream outStream = createCryptOutputStream(data);
+ String originalFilename = getOriginalFilename(data);
/* Operation */
PgpSignEncrypt.Builder builder =
@@ -262,7 +265,8 @@ public class KeychainIntentService extends IntentService
.setSignatureHashAlgorithm(
Preferences.getPreferences(this).getDefaultHashAlgorithm())
.setSignaturePassphrase(
- PassphraseCacheService.getCachedPassphrase(this, signatureKeyId));
+ PassphraseCacheService.getCachedPassphrase(this, signatureKeyId))
+ .setOriginalFilename(originalFilename);
// this assumes that the bytes are cleartext (valid for current implementation!)
if (source == IO_BYTES) {
@@ -308,10 +312,10 @@ public class KeychainIntentService extends IntentService
KeychainIntentService.this, masterKeyId);
}
},
- inputData, outStream);
- builder.setProgressable(this);
-
- builder.setAllowSymmetricDecryption(true)
+ inputData, outStream
+ );
+ builder.setProgressable(this)
+ .setAllowSymmetricDecryption(true)
.setPassphrase(passphrase);
PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute();
@@ -330,6 +334,46 @@ public class KeychainIntentService extends IntentService
} catch (Exception e) {
sendErrorToHandler(e);
}
+ } else if (ACTION_DECRYPT_METADATA.equals(action)) {
+ try {
+ /* Input */
+ String passphrase = data.getString(DECRYPT_PASSPHRASE);
+
+ InputData inputData = createDecryptInputData(data);
+
+ /* Operation */
+
+ Bundle resultData = new Bundle();
+
+ // verifyText and decrypt returning additional resultData values for the
+ // verification of signatures
+ PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(
+ new ProviderHelper(this),
+ new PgpDecryptVerify.PassphraseCache() {
+ @Override
+ public String getCachedPassphrase(long masterKeyId) {
+ return PassphraseCacheService.getCachedPassphrase(
+ KeychainIntentService.this, masterKeyId);
+ }
+ },
+ inputData, null
+ );
+ builder.setProgressable(this)
+ .setAllowSymmetricDecryption(true)
+ .setPassphrase(passphrase)
+ .setReturnMetadataOnly(true);
+
+ PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute();
+
+ resultData.putParcelable(RESULT_DECRYPT_VERIFY_RESULT, decryptVerifyResult);
+
+ /* Output */
+ OtherHelper.logDebugBundle(resultData, "resultData");
+
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
+ } catch (Exception e) {
+ sendErrorToHandler(e);
+ }
} else if (ACTION_SAVE_KEYRING.equals(action)) {
try {
/* Input */
@@ -356,7 +400,7 @@ public class KeychainIntentService extends IntentService
UncachedKeyRing ring = result.getRing();
- providerHelper.saveSecretKeyRing(ring, new ProgressScaler(this, 60, 95, 100));
+ providerHelper.saveSecretKeyRing(ring, new ProgressScaler(this, 60, 95, 100));
// cache new passphrase
if (saveParcel.mNewPassphrase != null) {
@@ -403,7 +447,7 @@ public class KeychainIntentService extends IntentService
} else {
// get entries from cached file
FileImportCache<ParcelableKeyRing> cache =
- new FileImportCache<ParcelableKeyRing>(this);
+ new FileImportCache<ParcelableKeyRing>(this);
entries = cache.readCacheIntoList();
}
@@ -576,7 +620,7 @@ public class KeychainIntentService extends IntentService
CanonicalizedPublicKeyRing publicRing = providerHelper.getCanonicalizedPublicKeyRing(pubKeyId);
CanonicalizedSecretKeyRing secretKeyRing = providerHelper.getCanonicalizedSecretKeyRing(masterKeyId);
CanonicalizedSecretKey certificationKey = secretKeyRing.getSecretKey();
- if(!certificationKey.unlock(signaturePassphrase)) {
+ if (!certificationKey.unlock(signaturePassphrase)) {
throw new PgpGeneralException("Error extracting key (bad passphrase?)");
}
UncachedKeyRing newRing = certificationKey.certifyUserIds(publicRing, userIds);
@@ -729,6 +773,27 @@ public class KeychainIntentService extends IntentService
}
}
+ private String getOriginalFilename(Bundle data) throws PgpGeneralException, FileNotFoundException {
+ int target = data.getInt(TARGET);
+ switch (target) {
+ case IO_BYTES:
+ return "";
+
+ case IO_URI:
+ Uri providerUri = data.getParcelable(ENCRYPT_INPUT_URI);
+
+ return FileHelper.getFilename(this, providerUri);
+
+ case IO_URIS:
+ providerUri = data.<Uri>getParcelableArrayList(ENCRYPT_INPUT_URIS).get(data.getInt(SELECTED_URI));
+
+ return FileHelper.getFilename(this, providerUri);
+
+ default:
+ throw new PgpGeneralException("No target choosen!");
+ }
+ }
+
private OutputStream createCryptOutputStream(Bundle data) throws PgpGeneralException, FileNotFoundException {
int target = data.getInt(TARGET);
switch (target) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java
index c33b1489a..845fbfa3b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java
@@ -23,8 +23,10 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
+import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
+import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -38,6 +40,7 @@ import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment;
+import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Notify;
@@ -113,7 +116,8 @@ public class DecryptFileFragment extends DecryptFragment {
return;
}
- askForOutputFilename();
+// askForOutputFilename();
+ decryptOriginalFilename(null);
}
private String removeEncryptedAppend(String name) {
@@ -123,8 +127,13 @@ public class DecryptFileFragment extends DecryptFragment {
return name;
}
- private void askForOutputFilename() {
- String targetName = removeEncryptedAppend(FileHelper.getFilename(getActivity(), mInputUri));
+ private void askForOutputFilename(String originalFilename) {
+ String targetName;
+ if (!TextUtils.isEmpty(originalFilename)) {
+ targetName = originalFilename;
+ } else {
+ targetName = removeEncryptedAppend(FileHelper.getFilename(getActivity(), mInputUri));
+ }
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
File file = new File(mInputUri.getPath());
File parentDir = file.exists() ? file.getParentFile() : Constants.Path.APP_DIR;
@@ -136,6 +145,82 @@ public class DecryptFileFragment extends DecryptFragment {
}
}
+ private void decryptOriginalFilename(String passphrase) {
+ Log.d(Constants.TAG, "decryptOriginalFilename");
+
+ Intent intent = new Intent(getActivity(), KeychainIntentService.class);
+
+ // fill values for this action
+ Bundle data = new Bundle();
+ intent.setAction(KeychainIntentService.ACTION_DECRYPT_METADATA);
+
+ // data
+ Log.d(Constants.TAG, "mInputUri=" + mInputUri + ", mOutputUri=" + mOutputUri);
+
+ data.putInt(KeychainIntentService.SOURCE, KeychainIntentService.IO_URI);
+ data.putParcelable(KeychainIntentService.ENCRYPT_INPUT_URI, mInputUri);
+
+ data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_URI);
+ data.putParcelable(KeychainIntentService.ENCRYPT_OUTPUT_URI, mOutputUri);
+
+ data.putString(KeychainIntentService.DECRYPT_PASSPHRASE, passphrase);
+
+ intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
+
+ // Message is received after decrypting 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()) {
+ showPassphraseDialogForFilename(decryptVerifyResult.getKeyIdPassphraseNeeded());
+ } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED ==
+ decryptVerifyResult.getStatus()) {
+ showPassphraseDialogForFilename(Constants.key.symmetric);
+ } else {
+
+ // go on...
+ askForOutputFilename(decryptVerifyResult.getDecryptMetadata().getFilename());
+ }
+ }
+ }
+ };
+
+ // 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);
+ }
+
+ protected void showPassphraseDialogForFilename(long keyId) {
+ PassphraseDialogFragment.show(getActivity(), keyId,
+ new Handler() {
+ @Override
+ public void handleMessage(Message message) {
+ if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
+ String passphrase =
+ message.getData().getString(PassphraseDialogFragment.MESSAGE_DATA_PASSPHRASE);
+ decryptOriginalFilename(passphrase);
+ }
+ }
+ }
+ );
+ }
+
@Override
protected void decryptStart(String passphrase) {
Log.d(Constants.TAG, "decryptStart");
@@ -161,7 +246,7 @@ public class DecryptFileFragment extends DecryptFragment {
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
- // Message is received after encrypting is done in KeychainIntentService
+ // Message is received after decrypting is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(),
getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
@@ -178,7 +263,7 @@ public class DecryptFileFragment extends DecryptFragment {
if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) {
showPassphraseDialog(decryptVerifyResult.getKeyIdPassphraseNeeded());
} else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED ==
- decryptVerifyResult.getStatus()) {
+ decryptVerifyResult.getStatus()) {
showPassphraseDialog(Constants.key.symmetric);
} else {
// display signature result in activity
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
index ab26d539a..a5cf4d84d 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
@@ -264,12 +264,12 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn
// fill values for this action
Bundle data = new Bundle();
- int compressionId;
if (isContentMessage()) {
data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_BYTES);
data.putByteArray(KeychainIntentService.ENCRYPT_MESSAGE_BYTES, mMessage.getBytes());
- compressionId = Preferences.getPreferences(this).getDefaultMessageCompression();
+ data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID,
+ Preferences.getPreferences(this).getDefaultMessageCompression());
} else {
data.putInt(KeychainIntentService.SOURCE, KeychainIntentService.IO_URIS);
data.putParcelableArrayList(KeychainIntentService.ENCRYPT_INPUT_URIS, mInputUris);
@@ -277,10 +277,10 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn
data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_URIS);
data.putParcelableArrayList(KeychainIntentService.ENCRYPT_OUTPUT_URIS, mOutputUris);
- compressionId = Preferences.getPreferences(this).getDefaultFileCompression();
+ data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID,
+ Preferences.getPreferences(this).getDefaultFileCompression());
}
- data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, compressionId);
// Always use armor for messages
data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, mUseArmor || isContentMessage());
@@ -429,7 +429,6 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn
if (isModeSymmetric()) {
// symmetric encryption checks
-
if (mPassphrase == null) {
Notify.showNotify(this, R.string.passphrases_do_not_match, Notify.Style.ERROR);
return false;