aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java41
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java43
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java38
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/DecryptVerifyResult.java15
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java19
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java21
6 files changed, 113 insertions, 64 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 d7107d695..4e4e8c4e0 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
@@ -49,6 +49,8 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.results.DecryptVerifyResult;
+import org.sufficientlysecure.keychain.service.results.OperationResultParcel.LogLevel;
+import org.sufficientlysecure.keychain.service.results.OperationResultParcel.LogType;
import org.sufficientlysecure.keychain.service.results.OperationResultParcel.OperationLog;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
@@ -70,6 +72,7 @@ import java.util.Set;
*/
public class PgpDecryptVerify {
private ProviderHelper mProviderHelper;
+ private PassphraseCache mPassphraseCache;
private InputData mData;
private OutputStream mOutStream;
@@ -83,6 +86,7 @@ public class PgpDecryptVerify {
private PgpDecryptVerify(Builder builder) {
// private Constructor can only be called from Builder
this.mProviderHelper = builder.mProviderHelper;
+ this.mPassphraseCache = builder.mPassphraseCache;
this.mData = builder.mData;
this.mOutStream = builder.mOutStream;
@@ -97,6 +101,7 @@ public class PgpDecryptVerify {
public static class Builder {
// mandatory parameter
private ProviderHelper mProviderHelper;
+ private PassphraseCache mPassphraseCache;
private InputData mData;
private OutputStream mOutStream;
@@ -108,8 +113,10 @@ public class PgpDecryptVerify {
private boolean mDecryptMetadataOnly = false;
private byte[] mDecryptedSessionKey = null;
- public Builder(ProviderHelper providerHelper, InputData data, OutputStream outStream) {
+ public Builder(ProviderHelper providerHelper, PassphraseCache passphraseCache,
+ InputData data, OutputStream outStream) {
this.mProviderHelper = providerHelper;
+ this.mPassphraseCache = passphraseCache;
this.mData = data;
this.mOutStream = outStream;
}
@@ -169,6 +176,16 @@ public class PgpDecryptVerify {
}
}
+ public interface PassphraseCache {
+ public String getCachedPassphrase(long masterKeyId)
+ throws NoSecretKeyException;
+ }
+
+ public static class NoSecretKeyException extends Exception {
+ public NoSecretKeyException() {
+ }
+ }
+
/**
* Decrypts and/or verifies data based on parameters of class
*/
@@ -286,12 +303,24 @@ public class PgpDecryptVerify {
encryptedDataAsymmetric = encData;
- // if passphrase was not cached, return here indicating that a passphrase is missing!
+ // if no passphrase was explicitly set try to get it from the cache service
if (mPassphrase == null) {
- DecryptVerifyResult result =
- new DecryptVerifyResult(DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE, log);
- result.setKeyIdPassphraseNeeded(subKeyId);
- return result;
+ try {
+ // returns "" if key has no passphrase
+ mPassphrase = mPassphraseCache.getCachedPassphrase(subKeyId);
+ } catch (NoSecretKeyException e) {
+ // log.add(LogLevel.ERROR, LogType.MSG_DEC_ERROR_NO_KEY);
+ return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
+ }
+
+ // if passphrase was not cached, return here
+ // indicating that a passphrase is missing!
+ if (mPassphrase == null) {
+ DecryptVerifyResult result =
+ new DecryptVerifyResult(DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE, log);
+ result.setKeyIdPassphraseNeeded(subKeyId);
+ return result;
+ }
}
// break out of while, only decrypt the first packet where we have a key
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
index 1092fe7b4..3dc6f8a6e 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
@@ -462,32 +462,23 @@ public class OpenPgpService extends RemoteService {
.setDecryptMetadataOnly(decryptMetadataOnly)
.setNfcState(nfcDecryptedSessionKey);
- DecryptVerifyResult decryptVerifyResult;
- try {
- // TODO: currently does not support binary signed-only content
- decryptVerifyResult = builder.build().execute();
-
- // throw exceptions upwards to client with meaningful messages
- } catch (PgpDecryptVerify.InvalidDataException e) {
- throw new Exception(getString(R.string.error_invalid_data));
- } catch (PgpDecryptVerify.KeyExtractionException e) {
- throw new Exception(getString(R.string.error_could_not_extract_private_key));
- } catch (PgpDecryptVerify.WrongPassphraseException e) {
- throw new Exception(getString(R.string.error_wrong_passphrase));
- } catch (PgpDecryptVerify.NoSecretKeyException e) {
- throw new Exception(getString(R.string.error_no_secret_key_found));
- } catch (PgpDecryptVerify.IntegrityCheckFailedException e) {
- throw new Exception(getString(R.string.error_integrity_check_failed));
- } catch (PgpDecryptVerify.NeedNfcDataException e) {
- // return PendingIntent to execute NFC activity
- return getNfcDecryptIntent(data, e.mPassphrase, e.mEncryptedSessionKey);
- }
-
- if (DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE == decryptVerifyResult.getStatus()) {
- // get PendingIntent for passphrase input, add it to given params and return to client
- return getPassphraseIntent(data, decryptVerifyResult.getKeyIdPassphraseNeeded());
- } else if (DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE == decryptVerifyResult.getStatus()) {
- throw new PgpGeneralException("Decryption of symmetric content not supported by API!");
+ // TODO: currently does not support binary signed-only content
+ DecryptVerifyResult decryptVerifyResult = builder.build().execute();
+
+ if (decryptVerifyResult.isPending()) {
+ switch (decryptVerifyResult.getResult()) {
+ case DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE:
+ return getPassphraseIntent(data, decryptVerifyResult.getKeyIdPassphraseNeeded());
+ case DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE:
+ throw new PgpGeneralException(
+ "Decryption of symmetric content not supported by API!");
+ case DecryptVerifyResult.RESULT_PENDING_NFC:
+ // TODO get passphrase here? currently not in DecryptVerifyResult
+ return getNfcDecryptIntent(
+ data, null, decryptVerifyResult.getNfcEncryptedSessionKey());
+ }
+ throw new PgpGeneralException(
+ "Encountered unhandled type of pending action not supported by API!");
}
OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult();
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 2366e0237..966c43597 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
@@ -337,15 +337,22 @@ public class KeychainIntentService extends IntentService implements Progressable
Bundle resultData = new Bundle();
- /* TODO find passphrase from cache, if not provided
- return PassphraseCacheService.getCachedPassphrase(
- KeychainIntentService.this, masterKeyId);
- */
-
// verifyText and decrypt returning additional resultData values for the
// verification of signatures
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(
- new ProviderHelper(this), inputData, outStream
+ new ProviderHelper(this),
+ new PgpDecryptVerify.PassphraseCache() {
+ @Override
+ public String getCachedPassphrase(long masterKeyId) {
+ try {
+ return PassphraseCacheService.getCachedPassphrase(
+ KeychainIntentService.this, masterKeyId);
+ } catch (PassphraseCacheService.KeyNotFoundException e) {
+ return null;
+ }
+ }
+ },
+ inputData, outStream
);
builder.setProgressable(this)
.setAllowSymmetricDecryption(true)
@@ -378,15 +385,22 @@ public class KeychainIntentService extends IntentService implements Progressable
Bundle resultData = new Bundle();
- /* TODO find passphrase from cache, if not provided
- return PassphraseCacheService.getCachedPassphrase(
- KeychainIntentService.this, masterKeyId);
- */
-
// verifyText and decrypt returning additional resultData values for the
// verification of signatures
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(
- new ProviderHelper(this), inputData, null
+ new ProviderHelper(this),
+ new PgpDecryptVerify.PassphraseCache() {
+ @Override
+ public String getCachedPassphrase(long masterKeyId) throws PgpDecryptVerify.NoSecretKeyException {
+ try {
+ return PassphraseCacheService.getCachedPassphrase(
+ KeychainIntentService.this, masterKeyId);
+ } catch (PassphraseCacheService.KeyNotFoundException e) {
+ throw new PgpDecryptVerify.NoSecretKeyException();
+ }
+ }
+ },
+ inputData, null
);
builder.setProgressable(this)
.setAllowSymmetricDecryption(true)
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/DecryptVerifyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/DecryptVerifyResult.java
index 909f9f9be..e7ac209bf 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/DecryptVerifyResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/DecryptVerifyResult.java
@@ -18,7 +18,6 @@
package org.sufficientlysecure.keychain.service.results;
import android.os.Parcel;
-import android.os.Parcelable;
import org.openintents.openpgp.OpenPgpMetadata;
import org.openintents.openpgp.OpenPgpSignatureResult;
@@ -34,7 +33,7 @@ public class DecryptVerifyResult extends OperationResultParcel {
public static final int RESULT_PENDING_NFC = RESULT_PENDING +48;
long mKeyIdPassphraseNeeded;
- byte[] mSessionKey;
+ byte[] mNfcSessionKey;
OpenPgpSignatureResult mSignatureResult;
OpenPgpMetadata mDecryptMetadata;
@@ -48,7 +47,11 @@ public class DecryptVerifyResult extends OperationResultParcel {
}
public void setNfcEncryptedSessionKey(byte[] sessionKey) {
- mSessionKey = sessionKey;
+ mNfcSessionKey = sessionKey;
+ }
+
+ public byte[] getNfcEncryptedSessionKey() {
+ return mNfcSessionKey;
}
public OpenPgpSignatureResult getSignatureResult() {
@@ -80,7 +83,7 @@ public class DecryptVerifyResult extends OperationResultParcel {
mKeyIdPassphraseNeeded = source.readLong();
mSignatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader());
mDecryptMetadata = source.readParcelable(OpenPgpMetadata.class.getClassLoader());
- mSessionKey = source.readInt() != 0 ? source.createByteArray() : null;
+ mNfcSessionKey = source.readInt() != 0 ? source.createByteArray() : null;
}
public int describeContents() {
@@ -92,9 +95,9 @@ public class DecryptVerifyResult extends OperationResultParcel {
dest.writeLong(mKeyIdPassphraseNeeded);
dest.writeParcelable(mSignatureResult, 0);
dest.writeParcelable(mDecryptMetadata, 0);
- if (mSessionKey != null) {
+ if (mNfcSessionKey != null) {
dest.writeInt(1);
- dest.writeByteArray(mSessionKey);
+ dest.writeByteArray(mNfcSessionKey);
} else {
dest.writeInt(0);
}
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 ec0f68ced..7d9b2b9b3 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java
@@ -261,13 +261,18 @@ public class DecryptFileFragment extends DecryptFragment {
DecryptVerifyResult result =
returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT);
- switch (result.getResult()) {
- case DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE:
- showPassphraseDialog(result.getKeyIdPassphraseNeeded());
- return;
- case DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE:
- showPassphraseDialog(Constants.key.symmetric);
- return;
+ if (result.isPending()) {
+ switch (result.getResult()) {
+ case DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE:
+ showPassphraseDialog(result.getKeyIdPassphraseNeeded());
+ return;
+ case DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE:
+ showPassphraseDialog(Constants.key.symmetric);
+ return;
+ }
+ // error, we can't work with this!
+ result.createNotify(getActivity());
+ return;
}
// display signature result in activity
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java
index 01ea4b042..75e38d5c6 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java
@@ -146,13 +146,18 @@ public class DecryptMessageFragment extends DecryptFragment {
DecryptVerifyResult result =
returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT);
- switch (result.getResult()) {
- case DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE:
- showPassphraseDialog(result.getKeyIdPassphraseNeeded());
- return;
- case DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE:
- showPassphraseDialog(Constants.key.symmetric);
- return;
+ if (result.isPending()) {
+ switch (result.getResult()) {
+ case DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE:
+ showPassphraseDialog(result.getKeyIdPassphraseNeeded());
+ return;
+ case DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE:
+ showPassphraseDialog(Constants.key.symmetric);
+ return;
+ }
+ // error, we can't work with this!
+ result.createNotify(getActivity());
+ return;
}
byte[] decryptedMessage = returnData
@@ -160,6 +165,8 @@ public class DecryptMessageFragment extends DecryptFragment {
mMessage.setText(new String(decryptedMessage));
mMessage.setHorizontallyScrolling(false);
+ result.createNotify(getActivity());
+
// display signature result in activity
onResult(result);
}