aboutsummaryrefslogtreecommitdiffstats
path: root/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service
diff options
context:
space:
mode:
Diffstat (limited to 'OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service')
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java39
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java10
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java413
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java30
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java37
5 files changed, 218 insertions, 311 deletions
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 24bce8eeb..d796ccf31 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
@@ -44,6 +44,7 @@ import org.sufficientlysecure.keychain.helper.OtherHelper;
import org.sufficientlysecure.keychain.helper.Preferences;
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
+import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpImportExport;
import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
@@ -176,13 +177,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial
// 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_SIGNATURE = "signature";
- public static final String RESULT_SIGNATURE_KEY_ID = "signature_key_id";
- public static final String RESULT_SIGNATURE_USER_ID = "signature_user_id";
- public static final String RESULT_CLEARTEXT_SIGNATURE_ONLY = "signature_only";
-
- public static final String RESULT_SIGNATURE_SUCCESS = "signature_success";
- public static final String RESULT_SIGNATURE_UNKNOWN = "signature_unknown";
+ public static final String RESULT_DECRYPT_VERIFY_RESULT = "signature";
// import
public static final String RESULT_IMPORT_ADDED = "added";
@@ -198,8 +193,16 @@ public class KeychainIntentService extends IntentService implements ProgressDial
Messenger mMessenger;
+ private boolean mIsCanceled;
+
public KeychainIntentService() {
- super("ApgService");
+ super("KeychainIntentService");
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ this.mIsCanceled = true;
}
/**
@@ -476,15 +479,17 @@ public class KeychainIntentService extends IntentService implements ProgressDial
// verifyText and decrypt returning additional resultData values for the
// verification of signatures
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, outStream);
- builder.progress(this);
+ builder.progressDialogUpdater(this);
builder.assumeSymmetric(assumeSymmetricEncryption)
.passphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId));
- resultData = builder.build().execute();
+ PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute();
outStream.close();
+ resultData.putParcelable(RESULT_DECRYPT_VERIFY_RESULT, decryptVerifyResult);
+
/* Output */
switch (target) {
@@ -733,7 +738,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial
*/
// need to have access to the bufferedInput, so we can reuse it for the possible
// PGPObject chunks after the first one, e.g. files with several consecutive ASCII
- // armour blocks
+ // armor blocks
BufferedInputStream bufferedInput = new BufferedInputStream(new ByteArrayInputStream(downloadedKey));
try {
@@ -805,6 +810,10 @@ public class KeychainIntentService extends IntentService implements ProgressDial
}
private void sendErrorToHandler(Exception e) {
+ // Service was canceled. Do not send error to handler.
+ if (this.mIsCanceled)
+ return;
+
Log.e(Constants.TAG, "ApgService Exception: ", e);
e.printStackTrace();
@@ -814,6 +823,10 @@ public class KeychainIntentService extends IntentService implements ProgressDial
}
private void sendMessageToHandler(Integer arg1, Integer arg2, Bundle data) {
+ // Service was canceled. Do not send message to handler.
+ if (this.mIsCanceled)
+ return;
+
Message msg = Message.obtain();
msg.arg1 = arg1;
if (arg2 != null) {
@@ -841,10 +854,10 @@ public class KeychainIntentService extends IntentService implements ProgressDial
}
/**
- * Set progress of ProgressDialog by sending message to handler on UI thread
+ * Set progressDialogUpdater of ProgressDialog by sending message to handler on UI thread
*/
public void setProgress(String message, int progress, int max) {
- Log.d(Constants.TAG, "Send message by setProgress with progress=" + progress + ", max="
+ Log.d(Constants.TAG, "Send message by setProgress with progressDialogUpdater=" + progress + ", max="
+ max);
Bundle data = new Bundle();
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
index dfea7eb04..6eba9cc83 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
@@ -21,6 +21,8 @@ import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
import org.sufficientlysecure.keychain.R;
import android.app.Activity;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -55,9 +57,15 @@ public class KeychainIntentServiceHandler extends Handler {
}
public KeychainIntentServiceHandler(Activity activity, int progressDialogMessageId, int progressDialogStyle) {
+ this(activity, progressDialogMessageId, progressDialogStyle, false, null);
+ }
+
+ public KeychainIntentServiceHandler(Activity activity, int progressDialogMessageId,
+ int progressDialogStyle, boolean cancelable,
+ OnCancelListener onCancelListener) {
this.mActivity = activity;
this.mProgressDialogFragment = ProgressDialogFragment.newInstance(progressDialogMessageId,
- progressDialogStyle);
+ progressDialogStyle, cancelable, onCancelListener);
}
public void showProgressDialog(FragmentActivity activity) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java
index 34213bd3b..f697faa6e 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java
@@ -21,21 +21,22 @@ import android.app.PendingIntent;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
-import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import org.openintents.openpgp.IOpenPgpService;
import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.OpenPgpSignatureResult;
-import org.openintents.openpgp.util.OpenPgpConstants;
+import org.openintents.openpgp.util.OpenPgpApi;
import org.spongycastle.util.Arrays;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
+import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt;
+import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
@@ -48,7 +49,7 @@ public class OpenPgpService extends RemoteService {
private static final int PRIVATE_REQUEST_CODE_PASSPHRASE = 551;
private static final int PRIVATE_REQUEST_CODE_USER_IDS = 552;
-
+ private static final int PRIVATE_REQUEST_CODE_GET_KEYS = 553;
/**
* Search database for key ids based on emails.
@@ -56,7 +57,7 @@ public class OpenPgpService extends RemoteService {
* @param encryptionUserIds
* @return
*/
- private Bundle getKeyIdsFromEmails(Bundle params, String[] encryptionUserIds) {
+ private Intent getKeyIdsFromEmails(Intent data, String[] encryptionUserIds) {
// find key ids to given emails in database
ArrayList<Long> keyIds = new ArrayList<Long>();
@@ -91,21 +92,20 @@ public class OpenPgpService extends RemoteService {
// allow the user to verify pub key selection
if (missingUserIdsCheck || dublicateUserIdsCheck) {
- // build PendingIntent for passphrase input
+ // build PendingIntent
Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
intent.setAction(RemoteServiceActivity.ACTION_SELECT_PUB_KEYS);
intent.putExtra(RemoteServiceActivity.EXTRA_SELECTED_MASTER_KEY_IDS, keyIdsArray);
intent.putExtra(RemoteServiceActivity.EXTRA_MISSING_USER_IDS, missingUserIds);
intent.putExtra(RemoteServiceActivity.EXTRA_DUBLICATE_USER_IDS, dublicateUserIds);
- intent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
+ intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_USER_IDS, intent, 0);
// return PendingIntent to be executed by client
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED);
- result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi);
-
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
return result;
}
@@ -113,44 +113,43 @@ public class OpenPgpService extends RemoteService {
return null;
}
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_SUCCESS);
- result.putLongArray(OpenPgpConstants.PARAMS_KEY_IDS, keyIdsArray);
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.EXTRA_KEY_IDS, keyIdsArray);
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
return result;
}
- private Bundle getPassphraseBundleIntent(Bundle params, long keyId) {
+ private Intent getPassphraseBundleIntent(Intent data, long keyId) {
// build PendingIntent for passphrase input
Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
intent.setAction(RemoteServiceActivity.ACTION_CACHE_PASSPHRASE);
intent.putExtra(RemoteServiceActivity.EXTRA_SECRET_KEY_ID, keyId);
// pass params through to activity that it can be returned again later to repeat pgp operation
- intent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
+ intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_PASSPHRASE, intent, 0);
// return PendingIntent to be executed by client
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED);
- result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi);
-
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
return result;
}
- private Bundle signImpl(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output,
- AppSettings appSettings) {
+ private Intent signImpl(Intent data, ParcelFileDescriptor input,
+ ParcelFileDescriptor output, AppSettings appSettings) {
try {
- boolean asciiArmor = params.getBoolean(OpenPgpConstants.PARAMS_REQUEST_ASCII_ARMOR, true);
+ boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
// get passphrase from cache, if key has "no" passphrase, this returns an empty String
String passphrase;
- if (params.containsKey(OpenPgpConstants.PARAMS_PASSPHRASE)) {
- passphrase = params.getString(OpenPgpConstants.PARAMS_PASSPHRASE);
+ if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) {
+ passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
} else {
passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId());
}
if (passphrase == null) {
// get PendingIntent for passphrase input, add it to given params and return to client
- Bundle passphraseBundle = getPassphraseBundleIntent(params, appSettings.getKeyId());
+ Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId());
return passphraseBundle;
}
@@ -174,44 +173,43 @@ public class OpenPgpService extends RemoteService {
os.close();
}
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_SUCCESS);
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
return result;
} catch (Exception e) {
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
- result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
}
- private Bundle encryptAndSignImpl(Bundle params, ParcelFileDescriptor input,
- ParcelFileDescriptor output, AppSettings appSettings,
- boolean sign) {
+ private Intent encryptAndSignImpl(Intent data, ParcelFileDescriptor input,
+ ParcelFileDescriptor output, AppSettings appSettings, boolean sign) {
try {
- boolean asciiArmor = params.getBoolean(OpenPgpConstants.PARAMS_REQUEST_ASCII_ARMOR, true);
+ boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
long[] keyIds;
- if (params.containsKey(OpenPgpConstants.PARAMS_KEY_IDS)) {
- keyIds = params.getLongArray(OpenPgpConstants.PARAMS_KEY_IDS);
- } else if (params.containsKey(OpenPgpConstants.PARAMS_USER_IDS)) {
+ if (data.hasExtra(OpenPgpApi.EXTRA_KEY_IDS)) {
+ keyIds = data.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS);
+ } else if (data.hasExtra(OpenPgpApi.EXTRA_USER_IDS)) {
// get key ids based on given user ids
- String[] userIds = params.getStringArray(OpenPgpConstants.PARAMS_USER_IDS);
+ String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS);
// give params through to activity...
- Bundle result = getKeyIdsFromEmails(params, userIds);
+ Intent result = getKeyIdsFromEmails(data, userIds);
- if (result.getInt(OpenPgpConstants.RESULT_CODE, 0) == OpenPgpConstants.RESULT_CODE_SUCCESS) {
- keyIds = result.getLongArray(OpenPgpConstants.PARAMS_KEY_IDS);
+ if (result.getIntExtra(OpenPgpApi.RESULT_CODE, 0) == OpenPgpApi.RESULT_CODE_SUCCESS) {
+ keyIds = result.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS);
} else {
// if not success -> result contains a PendingIntent for user interaction
return result;
}
} else {
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
- result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, "Missing parameter user_ids or key_ids!"));
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
@@ -235,15 +233,15 @@ public class OpenPgpService extends RemoteService {
if (sign) {
String passphrase;
- if (params.containsKey(OpenPgpConstants.PARAMS_PASSPHRASE)) {
- passphrase = params.getString(OpenPgpConstants.PARAMS_PASSPHRASE);
+ if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) {
+ passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
} else {
passphrase = PassphraseCacheService.getCachedPassphrase(getContext(),
appSettings.getKeyId());
}
if (passphrase == null) {
// get PendingIntent for passphrase input, add it to given params and return to client
- Bundle passphraseBundle = getPassphraseBundleIntent(params, appSettings.getKeyId());
+ Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId());
return passphraseBundle;
}
@@ -263,193 +261,123 @@ public class OpenPgpService extends RemoteService {
os.close();
}
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_SUCCESS);
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
return result;
} catch (Exception e) {
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
- result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
}
- private Bundle decryptAndVerifyImpl(Bundle params, ParcelFileDescriptor input,
+ private Intent decryptAndVerifyImpl(Intent data, ParcelFileDescriptor input,
ParcelFileDescriptor output, AppSettings appSettings) {
try {
// Get Input- and OutputStream from ParcelFileDescriptor
InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
- OpenPgpSignatureResult sigResult = null;
- try {
-// PGPUtil.getDecoderStream(is)
- // TODOs API 2.0:
- // implement verify-only!
- // fix the mess: http://stackoverflow.com/questions/148130/how-do-i-peek-at-the-first-two-bytes-in-an-inputstream
- // should we allow to decrypt everything under every key id or only the one set?
- // TODO: instead of trying to get the passphrase before
- // pause stream when passphrase is missing and then resume
-
-
- // TODO: this is not really needed
- // checked if it is text with BEGIN and END tags
-// String message = new String(inputBytes);
-// Log.d(Constants.TAG, "in: " + message);
-// boolean signedOnly = false;
-// Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(message);
-// if (matcher.matches()) {
-// Log.d(Constants.TAG, "PGP_MESSAGE matched");
-// message = matcher.group(1);
-// // replace non breakable spaces
-// message = message.replaceAll("\\xa0", " ");
-//
-// // overwrite inputBytes
-// inputBytes = message.getBytes();
-// } else {
-// matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(message);
-// if (matcher.matches()) {
-// signedOnly = true;
-// Log.d(Constants.TAG, "PGP_SIGNED_MESSAGE matched");
-// message = matcher.group(1);
-// // replace non breakable spaces
-// message = message.replaceAll("\\xa0", " ");
-//
-// // overwrite inputBytes
-// inputBytes = message.getBytes();
-// } else {
-// Log.d(Constants.TAG, "Nothing matched! Binary?");
-// }
-// }
- // END TODO
-
-// Log.d(Constants.TAG, "in: " + new String(inputBytes));
-
- // TODO: This allows to decrypt messages with ALL secret keys, not only the one for the
- // app, Fix this?
-
-// String passphrase = null;
-// if (!signedOnly) {
-// // BEGIN Get key
-// // TODO: this input stream is consumed after PgpMain.getDecryptionKeyId()... do it
-// // better!
-// InputStream inputStream2 = new ByteArrayInputStream(inputBytes);
-//
-// // TODO: duplicates functions from DecryptActivity!
-// long secretKeyId;
-// try {
-// if (inputStream2.markSupported()) {
-// // should probably set this to the max size of two
-// // pgpF objects, if it even needs to be anything other
-// // than 0.
-// inputStream2.mark(200);
-// }
-// secretKeyId = PgpHelper.getDecryptionKeyId(this, inputStream2);
-// if (secretKeyId == Id.key.none) {
-// throw new PgpGeneralException(getString(R.string.error_no_secret_key_found));
-// }
-// } catch (NoAsymmetricEncryptionException e) {
-// if (inputStream2.markSupported()) {
-// inputStream2.reset();
-// }
-// secretKeyId = Id.key.symmetric;
-// if (!PgpDecryptVerify.hasSymmetricEncryption(this, inputStream2)) {
-// throw new PgpGeneralException(
-// getString(R.string.error_no_known_encryption_found));
-// }
-// // we do not support symmetric decryption from the API!
-// throw new Exception("Symmetric decryption is not supported!");
-// }
-//
-// Log.d(Constants.TAG, "secretKeyId " + secretKeyId);
-
- // NOTE: currently this only gets the passphrase for the key set for this client
- String passphrase;
- if (params.containsKey(OpenPgpConstants.PARAMS_PASSPHRASE)) {
- passphrase = params.getString(OpenPgpConstants.PARAMS_PASSPHRASE);
- } else {
- passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId());
- }
- if (passphrase == null) {
- // get PendingIntent for passphrase input, add it to given params and return to client
- Bundle passphraseBundle = getPassphraseBundleIntent(params, appSettings.getKeyId());
- return passphraseBundle;
- }
-// }
+ Intent result = new Intent();
+ try {
- // build InputData and write into OutputStream
+ String passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
long inputLength = is.available();
InputData inputData = new InputData(is, inputLength);
-
- Bundle outputBundle;
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, os);
-
-// if (signedOnly) {
-// outputBundle = builder.build().verifyText();
-// } else {
- builder.assumeSymmetric(false)
+ builder.assumeSymmetric(false) // no support for symmetric encryption
+ .enforcedKeyId(appSettings.getKeyId()) // allow only the private key for this app for decryption
.passphrase(passphrase);
- // Do we want to do this: instead of trying to get the passphrase before
- // pause stream when passphrase is missing and then resume???
-
- // TODO: this also decrypts with other secret keys without passphrase!!!
- outputBundle = builder.build().execute();
-// }
-
-// outputStream.close();
-
-// byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray();
-
- // get signature informations from bundle
- boolean signature = outputBundle.getBoolean(KeychainIntentService.RESULT_SIGNATURE, false);
-
- if (signature) {
- long signatureKeyId = outputBundle
- .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, 0);
- String signatureUserId = outputBundle
- .getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID);
- boolean signatureSuccess = outputBundle
- .getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, false);
- boolean signatureUnknown = outputBundle
- .getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, false);
- boolean signatureOnly = outputBundle
- .getBoolean(KeychainIntentService.RESULT_CLEARTEXT_SIGNATURE_ONLY, false);
-
- int signatureStatus = OpenPgpSignatureResult.SIGNATURE_ERROR;
- if (signatureSuccess) {
- signatureStatus = OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED;
- } else if (signatureUnknown) {
- signatureStatus = OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY;
+ // TODO: currently does not support binary signed-only content
+ PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute();
+
+ if (decryptVerifyResult.isKeyPassphraseNeeded()) {
+ // get PendingIntent for passphrase input, add it to given params and return to client
+ Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId());
+ return passphraseBundle;
+ } else if (decryptVerifyResult.isSymmetricPassphraseNeeded()) {
+ throw new PgpGeneralException("Decryption of symmetric content not supported by API!");
+ }
+
+ OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult();
+ if (signatureResult != null) {
+ if (signatureResult.getStatus() == OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY) {
+ // If signature is unknown we return an _additional_ PendingIntent
+ // to retrieve the missing key
+ // TODO!!!
+ Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
+ intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE);
+ intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, "todo");
+ intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
+
+ PendingIntent pi = PendingIntent.getActivity(getBaseContext(),
+ PRIVATE_REQUEST_CODE_GET_KEYS, intent, 0);
+
+ result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
}
- sigResult = new OpenPgpSignatureResult(signatureStatus, signatureUserId,
- signatureOnly, signatureKeyId);
+ result.putExtra(OpenPgpApi.RESULT_SIGNATURE, signatureResult);
}
+
} finally {
is.close();
os.close();
}
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_SUCCESS);
- result.putParcelable(OpenPgpConstants.RESULT_SIGNATURE, sigResult);
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
return result;
} catch (Exception e) {
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
- result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
}
- private Bundle getKeyIdsImpl(Bundle params) {
+ private Intent getKeyImpl(Intent data) {
+ try {
+ long keyId = data.getLongExtra(OpenPgpApi.EXTRA_KEY_ID, 0);
+
+ if (ProviderHelper.getPGPPublicKeyByKeyId(this, keyId) == null) {
+ Intent result = new Intent();
+
+ // If keys are not in db we return an additional PendingIntent
+ // to retrieve the missing key
+ // TODO!!!
+ Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
+ intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE);
+ intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, "todo");
+ intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
+
+ PendingIntent pi = PendingIntent.getActivity(getBaseContext(),
+ PRIVATE_REQUEST_CODE_GET_KEYS, intent, 0);
+
+ result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
+ return result;
+ } else {
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
+ return result;
+ }
+ } catch (Exception e) {
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
+ new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
+ return result;
+ }
+ }
+
+ private Intent getKeyIdsImpl(Intent data) {
// get key ids based on given user ids
- String[] userIds = params.getStringArray(OpenPgpConstants.PARAMS_USER_IDS);
- Bundle result = getKeyIdsFromEmails(params, userIds);
+ String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS);
+ Intent result = getKeyIdsFromEmails(data, userIds);
return result;
}
@@ -459,30 +387,30 @@ public class OpenPgpService extends RemoteService {
* - has supported API version
* - is allowed to call the service (access has been granted)
*
- * @param params
+ * @param data
* @return null if everything is okay, or a Bundle with an error/PendingIntent
*/
- private Bundle checkRequirements(Bundle params) {
+ private Intent checkRequirements(Intent data) {
// params Bundle is required!
- if (params == null) {
- Bundle result = new Bundle();
+ if (data == null) {
+ Intent result = new Intent();
OpenPgpError error = new OpenPgpError(OpenPgpError.GENERIC_ERROR, "params Bundle required!");
- result.putParcelable(OpenPgpConstants.RESULT_ERRORS, error);
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
+ result.putExtra(OpenPgpApi.RESULT_ERROR, error);
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
// version code is required and needs to correspond to version code of service!
- if (params.getInt(OpenPgpConstants.PARAMS_API_VERSION) != OpenPgpConstants.API_VERSION) {
- Bundle result = new Bundle();
+ if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != OpenPgpApi.API_VERSION) {
+ Intent result = new Intent();
OpenPgpError error = new OpenPgpError(OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!");
- result.putParcelable(OpenPgpConstants.RESULT_ERRORS, error);
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
+ result.putExtra(OpenPgpApi.RESULT_ERROR, error);
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
}
// check if caller is allowed to access openpgp keychain
- Bundle result = isAllowed(params);
+ Intent result = isAllowed(data);
if (result != null) {
return result;
}
@@ -494,61 +422,30 @@ public class OpenPgpService extends RemoteService {
private final IOpenPgpService.Stub mBinder = new IOpenPgpService.Stub() {
@Override
- public Bundle sign(Bundle params, final ParcelFileDescriptor input, final ParcelFileDescriptor output) {
- final AppSettings appSettings = getAppSettings();
-
- Bundle errorResult = checkRequirements(params);
+ public Intent execute(Intent data, ParcelFileDescriptor input, ParcelFileDescriptor output) {
+ Intent errorResult = checkRequirements(data);
if (errorResult != null) {
return errorResult;
}
- return signImpl(params, input, output, appSettings);
- }
-
- @Override
- public Bundle encrypt(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) {
final AppSettings appSettings = getAppSettings();
- Bundle errorResult = checkRequirements(params);
- if (errorResult != null) {
- return errorResult;
- }
-
- return encryptAndSignImpl(params, input, output, appSettings, false);
- }
-
- @Override
- public Bundle signAndEncrypt(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) {
- final AppSettings appSettings = getAppSettings();
-
- Bundle errorResult = checkRequirements(params);
- if (errorResult != null) {
- return errorResult;
- }
-
- return encryptAndSignImpl(params, input, output, appSettings, true);
- }
-
- @Override
- public Bundle decryptAndVerify(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) {
- final AppSettings appSettings = getAppSettings();
-
- Bundle errorResult = checkRequirements(params);
- if (errorResult != null) {
- return errorResult;
- }
-
- return decryptAndVerifyImpl(params, input, output, appSettings);
- }
-
- @Override
- public Bundle getKeyIds(Bundle params) {
- Bundle errorResult = checkRequirements(params);
- if (errorResult != null) {
- return errorResult;
+ String action = data.getAction();
+ if (OpenPgpApi.ACTION_SIGN.equals(action)) {
+ return signImpl(data, input, output, appSettings);
+ } else if (OpenPgpApi.ACTION_ENCRYPT.equals(action)) {
+ return encryptAndSignImpl(data, input, output, appSettings, false);
+ } else if (OpenPgpApi.ACTION_SIGN_AND_ENCRYPT.equals(action)) {
+ return encryptAndSignImpl(data, input, output, appSettings, true);
+ } else if (OpenPgpApi.ACTION_DECRYPT_VERIFY.equals(action)) {
+ return decryptAndVerifyImpl(data, input, output, appSettings);
+ } else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) {
+ return getKeyImpl(data);
+ } else if (OpenPgpApi.ACTION_GET_KEY_IDS.equals(action)) {
+ return getKeyIdsImpl(data);
+ } else {
+ return null;
}
-
- return getKeyIdsImpl(params);
}
};
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java
index cfd2b9ec3..cb556be39 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java
@@ -21,7 +21,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import org.openintents.openpgp.OpenPgpError;
-import org.openintents.openpgp.util.OpenPgpConstants;
+import org.openintents.openpgp.util.OpenPgpApi;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.KeychainContract;
@@ -38,10 +38,6 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.net.Uri;
import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
/**
* Abstract service class for remote APIs that handle app registration and user input.
@@ -57,7 +53,7 @@ public abstract class RemoteService extends Service {
return mContext;
}
- protected Bundle isAllowed(Bundle params) {
+ protected Intent isAllowed(Intent data) {
try {
if (isCallerAllowed(false)) {
@@ -74,9 +70,9 @@ public abstract class RemoteService extends Service {
} catch (NameNotFoundException e) {
Log.e(Constants.TAG, "Should not happen, returning!", e);
// return error
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
- result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
+ result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
return result;
}
@@ -86,14 +82,14 @@ public abstract class RemoteService extends Service {
intent.setAction(RemoteServiceActivity.ACTION_REGISTER);
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageSignature);
- intent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
+ intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_REGISTER, intent, 0);
// return PendingIntent to be executed by client
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED);
- result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi);
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
+ result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
return result;
}
@@ -103,14 +99,14 @@ public abstract class RemoteService extends Service {
Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE);
intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, getString(R.string.api_error_wrong_signature));
- intent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
+ intent.putExtra(RemoteServiceActivity.EXTRA_DATA, data);
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_ERROR, intent, 0);
// return PendingIntent to be executed by client
- Bundle result = new Bundle();
- result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED);
- result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi);
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
+ result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
return result;
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java
index af8e3ade8..11b3ee217 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java
@@ -25,7 +25,7 @@ import android.os.Messenger;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
-import org.openintents.openpgp.util.OpenPgpConstants;
+import org.openintents.openpgp.util.OpenPgpApi;
import org.sufficientlysecure.htmltextview.HtmlTextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
@@ -51,6 +51,8 @@ public class RemoteServiceActivity extends ActionBarActivity {
public static final String EXTRA_MESSENGER = "messenger";
+ public static final String EXTRA_DATA = "data";
+
// passphrase action
public static final String EXTRA_SECRET_KEY_ID = "secret_key_id";
// register action
@@ -100,12 +102,9 @@ public class RemoteServiceActivity extends ActionBarActivity {
ProviderHelper.insertApiApp(RemoteServiceActivity.this,
mSettingsFragment.getAppSettings());
- // give params through for new service call
- Bundle oldParams = extras.getBundle(OpenPgpConstants.PI_RESULT_PARAMS);
-
- Intent finishIntent = new Intent();
- finishIntent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, oldParams);
- RemoteServiceActivity.this.setResult(RESULT_OK, finishIntent);
+ // give data through for new service call
+ Intent resultData = extras.getParcelable(EXTRA_DATA);
+ RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
RemoteServiceActivity.this.finish();
}
}
@@ -128,9 +127,9 @@ public class RemoteServiceActivity extends ActionBarActivity {
mSettingsFragment.setAppSettings(settings);
} else if (ACTION_CACHE_PASSPHRASE.equals(action)) {
long secretKeyId = extras.getLong(EXTRA_SECRET_KEY_ID);
- Bundle oldParams = extras.getBundle(OpenPgpConstants.PI_RESULT_PARAMS);
+ Intent resultData = extras.getParcelable(EXTRA_DATA);
- showPassphraseDialog(oldParams, secretKeyId);
+ showPassphraseDialog(resultData, secretKeyId);
} else if (ACTION_SELECT_PUB_KEYS.equals(action)) {
long[] selectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS);
ArrayList<String> missingUserIds = intent
@@ -167,13 +166,11 @@ public class RemoteServiceActivity extends ActionBarActivity {
@Override
public void onClick(View v) {
// add key ids to params Bundle for new request
- Bundle params = extras.getBundle(OpenPgpConstants.PI_RESULT_PARAMS);
- params.putLongArray(OpenPgpConstants.PARAMS_KEY_IDS,
+ Intent resultData = extras.getParcelable(EXTRA_DATA);
+ resultData.putExtra(OpenPgpApi.EXTRA_KEY_IDS,
mSelectFragment.getSelectedMasterKeyIds());
- Intent finishIntent = new Intent();
- finishIntent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
- RemoteServiceActivity.this.setResult(RESULT_OK, finishIntent);
+ RemoteServiceActivity.this.setResult(RESULT_OK, resultData);
RemoteServiceActivity.this.finish();
}
}, R.string.btn_do_not_save, new View.OnClickListener() {
@@ -222,7 +219,7 @@ public class RemoteServiceActivity extends ActionBarActivity {
@Override
public void onClick(View v) {
- RemoteServiceActivity.this.setResult(RESULT_OK);
+ RemoteServiceActivity.this.setResult(RESULT_CANCELED);
RemoteServiceActivity.this.finish();
}
});
@@ -244,16 +241,14 @@ public class RemoteServiceActivity extends ActionBarActivity {
* encryption. Based on mSecretKeyId it asks for a passphrase to open a private key or it asks
* for a symmetric passphrase
*/
- private void showPassphraseDialog(final Bundle params, long secretKeyId) {
+ private void showPassphraseDialog(final Intent data, long secretKeyId) {
// Message is received after passphrase is cached
Handler returnHandler = new Handler() {
@Override
public void handleMessage(Message message) {
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
// return given params again, for calling the service method again
- Intent finishIntent = new Intent();
- finishIntent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
- RemoteServiceActivity.this.setResult(RESULT_OK, finishIntent);
+ RemoteServiceActivity.this.setResult(RESULT_OK, data);
} else {
RemoteServiceActivity.this.setResult(RESULT_CANCELED);
}
@@ -273,9 +268,7 @@ public class RemoteServiceActivity extends ActionBarActivity {
} catch (PgpGeneralException e) {
Log.d(Constants.TAG, "No passphrase for this secret key, do pgp operation directly!");
// return given params again, for calling the service method again
- Intent finishIntent = new Intent();
- finishIntent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
- setResult(RESULT_OK, finishIntent);
+ setResult(RESULT_OK, data);
finish();
}
}