aboutsummaryrefslogtreecommitdiffstats
path: root/OpenPGP-Keychain/src/main
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2014-02-17 20:03:38 +0100
committerDominik Schürmann <dominik@dominikschuermann.de>2014-02-17 20:03:38 +0100
commit2e3d0d444180ef7217e6e960d2092e4f3de4c198 (patch)
tree778dc901f287fff9aeb1c9d3d41d7053eeccf1b0 /OpenPGP-Keychain/src/main
parent7b819e65de71a17827a3264a1a8663ca0d30b48c (diff)
parentd3181f4478ce29fc96d101f5f72b4e82c03ec5e0 (diff)
downloadopen-keychain-2e3d0d444180ef7217e6e960d2092e4f3de4c198.tar.gz
open-keychain-2e3d0d444180ef7217e6e960d2092e4f3de4c198.tar.bz2
open-keychain-2e3d0d444180ef7217e6e960d2092e4f3de4c198.zip
Merge pull request #277 from openpgp-keychain/new-api
New api
Diffstat (limited to 'OpenPGP-Keychain/src/main')
-rw-r--r--OpenPGP-Keychain/src/main/AndroidManifest.xml66
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/NoUserIdsException.java10
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/UserInteractionRequiredException.java10
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/WrongPassphraseException.java10
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/ExtendedApiService.java122
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java798
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java217
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java172
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/WrongPackageSignatureException.java (renamed from OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/WrongPackageSignatureException.java)2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java1
-rw-r--r--OpenPGP-Keychain/src/main/res/values/strings.xml4
14 files changed, 514 insertions, 904 deletions
diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml
index 6de35571f..95f148686 100644
--- a/OpenPGP-Keychain/src/main/AndroidManifest.xml
+++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml
@@ -30,7 +30,7 @@
-->
<uses-sdk
- android:minSdkVersion="8"
+ android:minSdkVersion="9"
android:targetSdkVersion="19" />
<uses-feature
@@ -153,12 +153,19 @@
android:windowSoftInputMode="stateHidden">
<!-- Keychain's own Actions -->
+ <!-- ENCRYPT with text as extra -->
<intent-filter>
<action android:name="org.sufficientlysecure.keychain.action.ENCRYPT" />
<category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <!-- ENCRYPT with data Uri -->
+ <intent-filter>
+ <action android:name="org.sufficientlysecure.keychain.action.ENCRYPT" />
- <data android:mimeType="*/*" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <!-- TODO: accept other schemes! -->
+ <data android:scheme="file" />
</intent-filter>
<!-- Android's Send Action -->
<intent-filter android:label="@string/intent_send_encrypt">
@@ -176,12 +183,19 @@
android:windowSoftInputMode="stateHidden">
<!-- Keychain's own Actions -->
+ <!-- DECRYPT with text as extra -->
<intent-filter>
<action android:name="org.sufficientlysecure.keychain.action.DECRYPT" />
<category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <!-- DECRYPT with data Uri -->
+ <intent-filter>
+ <action android:name="org.sufficientlysecure.keychain.action.DECRYPT" />
- <data android:mimeType="*/*" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <!-- TODO: accept other schemes! -->
+ <data android:scheme="file" />
</intent-filter>
<!-- Android's Send Action -->
<intent-filter android:label="@string/intent_send_decrypt">
@@ -282,6 +296,7 @@
<data android:mimeType="application/pgp-keys" />
</intent-filter>
<!-- Keychain's own Actions -->
+ <!-- IMPORT_KEY with files TODO: does this work? -->
<intent-filter android:label="@string/intent_import_key">
<action android:name="org.sufficientlysecure.keychain.action.IMPORT_KEY" />
@@ -289,11 +304,19 @@
<data android:mimeType="*/*" />
</intent-filter>
- <!-- IMPORT again without mimeType to also allow data only without filename -->
+ <!-- IMPORT_KEY with mimeType 'application/pgp-keys' -->
+ <intent-filter>
+ <action android:name="org.sufficientlysecure.keychain.action.IMPORT_KEY" />
+
+ <category android:name="android.intent.category.DEFAULT" />
+ <!-- mime type as defined in http://tools.ietf.org/html/rfc3156, section 7 -->
+ <data android:mimeType="application/pgp-keys" />
+ </intent-filter>
+ <!-- IMPORT_KEY without mimeType to allow import with extras Bundle -->
<intent-filter android:label="@string/intent_import_key">
<action android:name="org.sufficientlysecure.keychain.action.IMPORT_KEY" />
<action android:name="org.sufficientlysecure.keychain.action.IMPORT_KEY_FROM_QR_CODE" />
- <action android:name="org.sufficientlysecure.keychain.action.IMPORT_KEY_FROM_KEY_SERVER" />
+ <action android:name="org.sufficientlysecure.keychain.action.IMPORT_KEY_FROM_KEYSERVER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
@@ -362,10 +385,9 @@
<activity
android:name="org.sufficientlysecure.keychain.service.remote.RemoteServiceActivity"
android:exported="false"
- android:label="@string/app_name"
- android:launchMode="singleTop"
- android:process=":remote_api"
- android:taskAffinity=":remote_api" />
+ android:label="@string/app_name" />
+ <!--android:launchMode="singleTop"-->
+ <!--android:process=":remote_api"-->
<activity
android:name="org.sufficientlysecure.keychain.service.remote.RegisteredAppsListActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
@@ -392,19 +414,19 @@
</service>
<!-- Extended Remote API -->
- <service
- android:name="org.sufficientlysecure.keychain.service.remote.ExtendedApiService"
- android:enabled="true"
- android:exported="true"
- android:process=":remote_api">
- <intent-filter>
- <action android:name="org.sufficientlysecure.keychain.service.remote.IExtendedApiService" />
- </intent-filter>
-
- <meta-data
- android:name="api_version"
- android:value="1" />
- </service>
+ <!--<service-->
+ <!--android:name="org.sufficientlysecure.keychain.service.remote.ExtendedApiService"-->
+ <!--android:enabled="true"-->
+ <!--android:exported="true"-->
+ <!--android:process=":remote_api">-->
+ <!--<intent-filter>-->
+ <!--<action android:name="org.sufficientlysecure.keychain.service.remote.IExtendedApiService" />-->
+ <!--</intent-filter>-->
+
+ <!--<meta-data-->
+ <!--android:name="api_version"-->
+ <!--android:value="1" />-->
+ <!--</service>-->
<!-- TODO: authority! Make this API with content provider uris -->
<!-- <provider -->
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 870e45ea5..1de9ab985 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
@@ -235,7 +235,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial
String action = intent.getAction();
- // execute action from extra bundle
+ // executeServiceMethod action from extra bundle
if (ACTION_ENCRYPT_SIGN.equals(action)) {
try {
/* Input */
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/NoUserIdsException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/NoUserIdsException.java
deleted file mode 100644
index 555303238..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/NoUserIdsException.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.sufficientlysecure.keychain.service.exception;
-
-public class NoUserIdsException extends Exception {
-
- private static final long serialVersionUID = 7009311527126696207L;
-
- public NoUserIdsException(String message) {
- super(message);
- }
-} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/UserInteractionRequiredException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/UserInteractionRequiredException.java
deleted file mode 100644
index 1152d6796..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/UserInteractionRequiredException.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.sufficientlysecure.keychain.service.exception;
-
-public class UserInteractionRequiredException extends Exception {
-
- private static final long serialVersionUID = -60128148603511936L;
-
- public UserInteractionRequiredException(String message) {
- super(message);
- }
-} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/WrongPassphraseException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/WrongPassphraseException.java
deleted file mode 100644
index 14b774eb5..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/WrongPassphraseException.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.sufficientlysecure.keychain.service.exception;
-
-public class WrongPassphraseException extends Exception {
-
- private static final long serialVersionUID = -5309689232853485740L;
-
- public WrongPassphraseException(String message) {
- super(message);
- }
-} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/ExtendedApiService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/ExtendedApiService.java
deleted file mode 100644
index 427e6bb8f..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/ExtendedApiService.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.service.remote;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintWriter;
-import java.security.cert.X509Certificate;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.PasswordCallback;
-
-import org.spongycastle.openpgp.PGPPrivateKey;
-import org.spongycastle.openpgp.PGPSecretKey;
-import org.spongycastle.openssl.PEMWriter;
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.pgp.PgpToX509;
-import org.sufficientlysecure.keychain.util.Log;
-
-import android.content.Intent;
-import android.os.IBinder;
-import android.os.RemoteException;
-
-public class ExtendedApiService extends RemoteService {
-
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
-
- private void selfSignedX509CertSafe(String subjAltNameURI, IExtendedApiCallback callback,
- AppSettings appSettings) {
-
- // TODO: for pgp keyrings with password
- CallbackHandler pgpPwdCallbackHandler = new PgpToX509.PredefinedPasswordCallbackHandler("");
-
- try {
- long keyId = appSettings.getKeyId();
- PGPSecretKey pgpSecretKey = PgpKeyHelper.getSigningKey(this, keyId);
-
- PasswordCallback pgpSecKeyPasswordCallBack = new PasswordCallback("pgp passphrase?",
- false);
- pgpPwdCallbackHandler.handle(new Callback[] { pgpSecKeyPasswordCallBack });
- PGPPrivateKey pgpPrivKey = pgpSecretKey.extractPrivateKey(
- pgpSecKeyPasswordCallBack.getPassword(), Constants.BOUNCY_CASTLE_PROVIDER_NAME);
- pgpSecKeyPasswordCallBack.clearPassword();
-
- X509Certificate selfSignedCert = PgpToX509.createSelfSignedCert(pgpSecretKey,
- pgpPrivKey, subjAltNameURI);
-
- // Write x509cert and privKey into files
- // FileOutputStream fosCert = context.openFileOutput(CERT_FILENAME,
- // Context.MODE_PRIVATE);
- ByteArrayOutputStream outStream = new ByteArrayOutputStream();
- PEMWriter pemWriterCert = new PEMWriter(new PrintWriter(outStream));
- pemWriterCert.writeObject(selfSignedCert);
- pemWriterCert.close();
-
- byte[] outputBytes = outStream.toByteArray();
-
- callback.onSuccess(outputBytes);
- } catch (Exception e) {
- Log.e(Constants.TAG, "ExtendedApiService", e);
- try {
- callback.onError(e.getMessage());
- } catch (RemoteException e1) {
- Log.e(Constants.TAG, "ExtendedApiService", e);
- }
- }
-
- // TODO: no private key at the moment! Don't give it to others
- // PrivateKey privKey = pgpPrivKey.getKey();
- // FileOutputStream fosKey = context.openFileOutput(PRIV_KEY_FILENAME,
- // Context.MODE_PRIVATE);
- // PEMWriter pemWriterKey = new PEMWriter(new PrintWriter(fosKey));
- // pemWriterKey.writeObject(privKey);
- // pemWriterKey.close();
- }
-
- private final IExtendedApiService.Stub mBinder = new IExtendedApiService.Stub() {
-
- @Override
- public void encrypt(byte[] inputBytes, String passphrase, IExtendedApiCallback callback)
- throws RemoteException {
- // TODO : implement
-
- }
-
- @Override
- public void selfSignedX509Cert(final String subjAltNameURI,
- final IExtendedApiCallback callback) throws RemoteException {
- final AppSettings settings = getAppSettings();
-
- Runnable r = new Runnable() {
- @Override
- public void run() {
- selfSignedX509CertSafe(subjAltNameURI, callback, settings);
- }
- };
-
- checkAndEnqueue(r);
- }
-
- };
-
-}
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 6db091ed0..31c5662dc 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
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2013-2014 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
@@ -17,108 +17,46 @@
package org.sufficientlysecure.keychain.service.remote;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.regex.Matcher;
+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.IOpenPgpCallback;
-import org.openintents.openpgp.IOpenPgpKeyIdsCallback;
import org.openintents.openpgp.IOpenPgpService;
-import org.openintents.openpgp.OpenPgpData;
import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.OpenPgpSignatureResult;
+import org.openintents.openpgp.util.OpenPgpConstants;
import org.spongycastle.util.Arrays;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.Preferences;
-import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpOperation;
-import org.sufficientlysecure.keychain.pgp.exception.NoAsymmetricEncryptionException;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
-import org.sufficientlysecure.keychain.service.exception.NoUserIdsException;
-import org.sufficientlysecure.keychain.service.exception.UserInteractionRequiredException;
-import org.sufficientlysecure.keychain.service.exception.WrongPassphraseException;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
public class OpenPgpService extends RemoteService {
- private String getCachedPassphrase(long keyId, boolean allowUserInteraction)
- throws UserInteractionRequiredException {
- String passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), keyId);
-
- if (passphrase == null) {
- if (!allowUserInteraction) {
- throw new UserInteractionRequiredException(
- "Passphrase not found in cache, please enter your passphrase!");
- }
-
- Log.d(Constants.TAG, "No passphrase! Activity required!");
-
- // start passphrase dialog
- PassphraseActivityCallback callback = new PassphraseActivityCallback();
- Bundle extras = new Bundle();
- extras.putLong(RemoteServiceActivity.EXTRA_SECRET_KEY_ID, keyId);
- pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_CACHE_PASSPHRASE, callback,
- extras);
-
- if (callback.isSuccess()) {
- Log.d(Constants.TAG, "New passphrase entered!");
-
- // get again after it was entered
- passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), keyId);
- } else {
- Log.d(Constants.TAG, "Passphrase dialog canceled!");
-
- return null;
- }
-
- }
-
- return passphrase;
- }
-
- public class PassphraseActivityCallback extends UserInputCallback {
+ private static final int PRIVATE_REQUEST_CODE_PASSPHRASE = 551;
+ private static final int PRIVATE_REQUEST_CODE_USER_IDS = 552;
- private boolean success = false;
-
- public boolean isSuccess() {
- return success;
- }
-
- @Override
- public void handleUserInput(Message msg) {
- if (msg.arg1 == OKAY) {
- success = true;
- } else {
- success = false;
- }
- }
- };
/**
* Search database for key ids based on emails.
- *
+ *
* @param encryptionUserIds
* @return
*/
- private long[] getKeyIdsFromEmails(String[] encryptionUserIds, boolean allowUserInteraction)
- throws UserInteractionRequiredException {
+ private Bundle getKeyIdsFromEmails(Bundle params, String[] encryptionUserIds) {
// find key ids to given emails in database
ArrayList<Long> keyIds = new ArrayList<Long>();
@@ -152,96 +90,118 @@ public class OpenPgpService extends RemoteService {
}
// allow the user to verify pub key selection
- if (allowUserInteraction && (missingUserIdsCheck || dublicateUserIdsCheck)) {
- SelectPubKeysActivityCallback callback = new SelectPubKeysActivityCallback();
-
- Bundle extras = new Bundle();
- extras.putLongArray(RemoteServiceActivity.EXTRA_SELECTED_MASTER_KEY_IDS, keyIdsArray);
- extras.putStringArrayList(RemoteServiceActivity.EXTRA_MISSING_USER_IDS, missingUserIds);
- extras.putStringArrayList(RemoteServiceActivity.EXTRA_DUBLICATE_USER_IDS,
- dublicateUserIds);
-
- pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_SELECT_PUB_KEYS, callback,
- extras);
-
- if (callback.isSuccess()) {
- Log.d(Constants.TAG, "New selection of pub keys!");
- keyIdsArray = callback.getPubKeyIds();
- } else {
- Log.d(Constants.TAG, "Pub key selection canceled!");
- return null;
- }
- }
-
- // if no user interaction is allow throw exceptions on duplicate or missing pub keys
- if (!allowUserInteraction) {
- if (missingUserIdsCheck)
- throw new UserInteractionRequiredException(
- "Pub keys for these user ids are missing:" + missingUserIds.toString());
- if (dublicateUserIdsCheck)
- throw new UserInteractionRequiredException(
- "More than one pub key with these user ids exist:"
- + dublicateUserIds.toString());
+ if (missingUserIdsCheck || dublicateUserIdsCheck) {
+ // build PendingIntent for passphrase input
+ 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);
+
+ 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);
+
+ return result;
}
if (keyIdsArray.length == 0) {
return null;
}
- return keyIdsArray;
+
+ Bundle result = new Bundle();
+ result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_SUCCESS);
+ result.putLongArray(OpenPgpConstants.PARAMS_KEY_IDS, keyIdsArray);
+ return result;
}
- public class SelectPubKeysActivityCallback extends UserInputCallback {
- public static final String PUB_KEY_IDS = "pub_key_ids";
+ private Bundle getPassphraseBundleIntent(Bundle params, 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);
+ 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);
+
+ return result;
+ }
- private boolean success = false;
- private long[] pubKeyIds;
- public boolean isSuccess() {
- return success;
- }
-
- public long[] getPubKeyIds() {
- return pubKeyIds;
- }
-
- @Override
- public void handleUserInput(Message msg) {
- if (msg.arg1 == OKAY) {
- success = true;
- pubKeyIds = msg.getData().getLongArray(PUB_KEY_IDS);
+ // TODO: asciiArmor?!
+ private Bundle signImpl(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output,
+ AppSettings appSettings) {
+ try {
+ // 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);
} else {
- success = false;
+ 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;
}
- }
- };
- private synchronized void getKeyIdsSafe(String[] userIds, boolean allowUserInteraction,
- IOpenPgpKeyIdsCallback callback, AppSettings appSettings) {
- try {
- long[] keyIds = getKeyIdsFromEmails(userIds, allowUserInteraction);
- if (keyIds == null) {
- throw new NoUserIdsException("No user ids!");
+ // Get Input- and OutputStream from ParcelFileDescriptor
+ InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
+ OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
+ try {
+ long inputLength = is.available();
+ InputData inputData = new InputData(is, inputLength);
+
+ PgpOperation operation = new PgpOperation(getContext(), null, inputData, os);
+ operation.signText(appSettings.getKeyId(), passphrase, appSettings.getHashAlgorithm(),
+ Preferences.getPreferences(this).getForceV3Signatures());
+ } finally {
+ is.close();
+ os.close();
}
- callback.onSuccess(keyIds);
- } catch (UserInteractionRequiredException e) {
- callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage());
- } catch (NoUserIdsException e) {
- callbackOpenPgpError(callback, OpenPgpError.NO_USER_IDS, e.getMessage());
+ Bundle result = new Bundle();
+ result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_SUCCESS);
+ return result;
} catch (Exception e) {
- callbackOpenPgpError(callback, OpenPgpError.GENERIC_ERROR, e.getMessage());
+ Bundle result = new Bundle();
+ result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
+ result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
+ new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
+ return result;
}
}
- private synchronized void encryptAndSignSafe(OpenPgpData inputData,
- final OpenPgpData outputData, long[] keyIds, boolean allowUserInteraction,
- IOpenPgpCallback callback, AppSettings appSettings, boolean sign) {
+ private Bundle encryptAndSignImpl(Bundle params, ParcelFileDescriptor input,
+ ParcelFileDescriptor output, AppSettings appSettings,
+ boolean sign) {
try {
- // TODO: other options of OpenPgpData!
- byte[] inputBytes = getInput(inputData);
- boolean asciiArmor = false;
- if (outputData.getType() == OpenPgpData.TYPE_STRING) {
- asciiArmor = true;
+ boolean asciiArmor = params.getBoolean(OpenPgpConstants.PARAMS_REQUEST_ASCII_ARMOR, false);
+
+ long[] keyIds;
+ if (params.containsKey(OpenPgpConstants.PARAMS_KEY_IDS)) {
+ keyIds = params.getLongArray(OpenPgpConstants.PARAMS_KEY_IDS);
+ } else {
+ // get key ids based on given user ids
+ String[] userIds = params.getStringArray(OpenPgpConstants.PARAMS_USER_IDS);
+ // give params through to activity...
+ Bundle result = getKeyIdsFromEmails(params, userIds);
+
+ if (result.getInt(OpenPgpConstants.RESULT_CODE, 0) == OpenPgpConstants.RESULT_CODE_SUCCESS) {
+ keyIds = result.getLongArray(OpenPgpConstants.PARAMS_KEY_IDS);
+ } else {
+ // if not success -> result contains a PendingIntent for user interaction
+ return result;
+ }
}
// add own key for encryption
@@ -249,349 +209,319 @@ public class OpenPgpService extends RemoteService {
keyIds[keyIds.length - 1] = appSettings.getKeyId();
// build InputData and write into OutputStream
- InputStream inputStream = new ByteArrayInputStream(inputBytes);
- long inputLength = inputBytes.length;
- InputData inputDt = new InputData(inputStream, inputLength);
-
- OutputStream outputStream = new ByteArrayOutputStream();
+ // Get Input- and OutputStream from ParcelFileDescriptor
+ InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
+ OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
+ try {
+ long inputLength = is.available();
+ InputData inputData = new InputData(is, inputLength);
+
+ PgpOperation operation = new PgpOperation(getContext(), null, inputData, os);
+ if (sign) {
+ 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;
+ }
- PgpOperation operation = new PgpOperation(getContext(), null, inputDt, outputStream);
- if (sign) {
- String passphrase = getCachedPassphrase(appSettings.getKeyId(),
- allowUserInteraction);
- if (passphrase == null) {
- throw new WrongPassphraseException("No or wrong passphrase!");
+ operation.signAndEncrypt(asciiArmor, appSettings.getCompression(), keyIds, null,
+ appSettings.getEncryptionAlgorithm(), appSettings.getKeyId(),
+ appSettings.getHashAlgorithm(), true, passphrase);
+ } else {
+ operation.signAndEncrypt(asciiArmor, appSettings.getCompression(), keyIds, null,
+ appSettings.getEncryptionAlgorithm(), Id.key.none,
+ appSettings.getHashAlgorithm(), true, null);
}
-
- operation.signAndEncrypt(asciiArmor, appSettings.getCompression(), keyIds, null,
- appSettings.getEncryptionAlgorithm(), appSettings.getKeyId(),
- appSettings.getHashAlgorithm(), true, passphrase);
- } else {
- operation.signAndEncrypt(asciiArmor, appSettings.getCompression(), keyIds, null,
- appSettings.getEncryptionAlgorithm(), Id.key.none,
- appSettings.getHashAlgorithm(), true, null);
+ } finally {
+ is.close();
+ os.close();
}
- outputStream.close();
-
- byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray();
-
- OpenPgpData output = null;
- if (asciiArmor) {
- output = new OpenPgpData(new String(outputBytes));
- } else {
- output = new OpenPgpData(outputBytes);
- }
-
- // return over handler on client side
- callback.onSuccess(output, null);
- } catch (UserInteractionRequiredException e) {
- callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage());
- } catch (WrongPassphraseException e) {
- callbackOpenPgpError(callback, OpenPgpError.NO_OR_WRONG_PASSPHRASE, e.getMessage());
- } catch (Exception e) {
- callbackOpenPgpError(callback, OpenPgpError.GENERIC_ERROR, e.getMessage());
- }
- }
-
- // TODO: asciiArmor?!
- private void signSafe(byte[] inputBytes, boolean allowUserInteraction,
- IOpenPgpCallback callback, AppSettings appSettings) {
- try {
- // build InputData and write into OutputStream
- InputStream inputStream = new ByteArrayInputStream(inputBytes);
- long inputLength = inputBytes.length;
- InputData inputData = new InputData(inputStream, inputLength);
-
- OutputStream outputStream = new ByteArrayOutputStream();
-
- String passphrase = getCachedPassphrase(appSettings.getKeyId(), allowUserInteraction);
- if (passphrase == null) {
- throw new WrongPassphraseException("No or wrong passphrase!");
- }
-
- PgpOperation operation = new PgpOperation(getContext(), null, inputData, outputStream);
- operation.signText(appSettings.getKeyId(), passphrase, appSettings.getHashAlgorithm(),
- Preferences.getPreferences(this).getForceV3Signatures());
-
- outputStream.close();
-
- byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray();
- OpenPgpData output = new OpenPgpData(new String(outputBytes));
-
- // return over handler on client side
- callback.onSuccess(output, null);
- } catch (UserInteractionRequiredException e) {
- callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage());
- } catch (WrongPassphraseException e) {
- callbackOpenPgpError(callback, OpenPgpError.NO_OR_WRONG_PASSPHRASE, e.getMessage());
+ Bundle result = new Bundle();
+ result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_SUCCESS);
+ return result;
} catch (Exception e) {
- callbackOpenPgpError(callback, OpenPgpError.GENERIC_ERROR, e.getMessage());
+ Bundle result = new Bundle();
+ result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
+ result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
+ new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
+ return result;
}
}
- private synchronized void decryptAndVerifySafe(byte[] inputBytes, boolean allowUserInteraction,
- IOpenPgpCallback callback, AppSettings appSettings) {
+ private Bundle decryptAndVerifyImpl(Bundle params, ParcelFileDescriptor input,
+ ParcelFileDescriptor output, AppSettings appSettings) {
try {
- // 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();
+ // Get Input- and OutputStream from ParcelFileDescriptor
+ InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
+ OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
+ OpenPgpSignatureResult sigResult = null;
+ try {
+
+
+ // 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 (!PgpOperation.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 saved key
+ String passphrase;
+ if (params.containsKey(OpenPgpConstants.PARAMS_PASSPHRASE)) {
+ passphrase = params.getString(OpenPgpConstants.PARAMS_PASSPHRASE);
} else {
- Log.d(Constants.TAG, "Nothing matched! Binary?");
+ passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId());
}
- }
- // 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 (!PgpOperation.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!");
+ 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;
}
+// }
- Log.d(Constants.TAG, "secretKeyId " + secretKeyId);
+ // build InputData and write into OutputStream
+ long inputLength = is.available();
+ InputData inputData = new InputData(is, inputLength);
- passphrase = getCachedPassphrase(secretKeyId, allowUserInteraction);
- if (passphrase == null) {
- throw new WrongPassphraseException("No or wrong passphrase!");
- }
- }
- // build InputData and write into OutputStream
- InputStream inputStream = new ByteArrayInputStream(inputBytes);
- long inputLength = inputBytes.length;
- InputData inputData = new InputData(inputStream, inputLength);
+ Bundle outputBundle;
+ PgpOperation operation = new PgpOperation(getContext(), null, inputData, os);
+ if (signedOnly) {
+ outputBundle = operation.verifyText();
+ } else {
+ // BIG TODO: instead of trying to get the passphrase before
+ // pause stream when passphrase is missing and then resume
+ outputBundle = operation.decryptAndVerify(passphrase, false);
+ }
- OutputStream outputStream = new ByteArrayOutputStream();
+// outputStream.close();
- Bundle outputBundle;
- PgpOperation operation = new PgpOperation(getContext(), null, inputData, outputStream);
- if (signedOnly) {
- outputBundle = operation.verifyText();
- } else {
- outputBundle = operation.decryptAndVerify(passphrase, false);
- }
+// byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray();
- outputStream.close();
+ // get signature informations from bundle
+ boolean signature = outputBundle.getBoolean(KeychainIntentService.RESULT_SIGNATURE);
- byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray();
+ if (signature) {
+ long signatureKeyId = outputBundle
+ .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID);
+ String signatureUserId = outputBundle
+ .getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID);
+ boolean signatureSuccess = outputBundle
+ .getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS);
+ boolean signatureUnknown = outputBundle
+ .getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN);
- // get signature informations from bundle
- boolean signature = outputBundle.getBoolean(KeychainIntentService.RESULT_SIGNATURE);
+ int signatureStatus = OpenPgpSignatureResult.SIGNATURE_ERROR;
+ if (signatureSuccess) {
+ signatureStatus = OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED;
+ } else if (signatureUnknown) {
+ signatureStatus = OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY;
+ }
- OpenPgpSignatureResult sigResult = null;
- if (signature) {
- long signatureKeyId = outputBundle
- .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID);
- String signatureUserId = outputBundle
- .getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID);
- boolean signatureSuccess = outputBundle
- .getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS);
- boolean signatureUnknown = outputBundle
- .getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN);
-
- int signatureStatus = OpenPgpSignatureResult.SIGNATURE_ERROR;
- if (signatureSuccess) {
- signatureStatus = OpenPgpSignatureResult.SIGNATURE_SUCCESS_TRUSTED;
- } else if (signatureUnknown) {
- signatureStatus = OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY;
+ sigResult = new OpenPgpSignatureResult(signatureStatus, signatureUserId,
+ signedOnly, signatureKeyId);
}
-
- sigResult = new OpenPgpSignatureResult(signatureStatus, signatureUserId,
- signedOnly, signatureKeyId);
+ } finally {
+ is.close();
+ os.close();
}
- OpenPgpData output = new OpenPgpData(new String(outputBytes));
-
- // return over handler on client side
- callback.onSuccess(output, sigResult);
- } catch (UserInteractionRequiredException e) {
- callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage());
- } catch (WrongPassphraseException e) {
- callbackOpenPgpError(callback, OpenPgpError.NO_OR_WRONG_PASSPHRASE, e.getMessage());
+
+ Bundle result = new Bundle();
+ result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_SUCCESS);
+ result.putParcelable(OpenPgpConstants.RESULT_SIGNATURE, sigResult);
+ return result;
} catch (Exception e) {
- callbackOpenPgpError(callback, OpenPgpError.GENERIC_ERROR, e.getMessage());
+ Bundle result = new Bundle();
+ result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
+ result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
+ new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
+ return result;
}
}
+ private Bundle getKeyIdsImpl(Bundle params) {
+ // get key ids based on given user ids
+ String[] userIds = params.getStringArray(OpenPgpConstants.PARAMS_USER_IDS);
+ Bundle result = getKeyIdsFromEmails(params, userIds);
+ return result;
+ }
+
/**
- * Returns error to IOpenPgpCallback
- *
- * @param callback
- * @param errorId
- * @param message
+ * Checks that params != null and API version fits
+ *
+ * @param params
+ * @return
*/
- private void callbackOpenPgpError(IOpenPgpCallback callback, int errorId, String message) {
- try {
- callback.onError(new OpenPgpError(0, message));
- } catch (Exception t) {
- Log.e(Constants.TAG,
- "Exception while returning OpenPgpError to client via callback.onError()", t);
+ private Bundle checkRequirements(Bundle params) {
+ // params Bundle is required!
+ if (params == null) {
+ Bundle result = new Bundle();
+ 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);
+ return result;
}
- }
- private void callbackOpenPgpError(IOpenPgpKeyIdsCallback callback, int errorId, String message) {
- try {
- callback.onError(new OpenPgpError(0, message));
- } catch (Exception t) {
- Log.e(Constants.TAG,
- "Exception while returning OpenPgpError to client via callback.onError()", t);
+ // 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();
+ 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);
+ return result;
}
+
+ // check if caller is allowed to access openpgp keychain
+ Bundle result = isAllowed(params);
+ if (result != null) {
+ return result;
+ }
+
+ return null;
}
+ // TODO: multi-threading
private final IOpenPgpService.Stub mBinder = new IOpenPgpService.Stub() {
@Override
- public void encrypt(final OpenPgpData input, final OpenPgpData output, final long[] keyIds,
- final IOpenPgpCallback callback) throws RemoteException {
- final AppSettings settings = getAppSettings();
-
- Runnable r = new Runnable() {
- @Override
- public void run() {
- encryptAndSignSafe(input, output, keyIds, true, callback, settings, false);
- }
- };
+ public Bundle sign(Bundle params, final ParcelFileDescriptor input, final ParcelFileDescriptor output) {
+ final AppSettings appSettings = getAppSettings();
- checkAndEnqueue(r);
- }
-
- @Override
- public void signAndEncrypt(final OpenPgpData input, final OpenPgpData output,
- final long[] keyIds, final IOpenPgpCallback callback) throws RemoteException {
- final AppSettings settings = getAppSettings();
-
- Runnable r = new Runnable() {
- @Override
- public void run() {
- encryptAndSignSafe(input, output, keyIds, true, callback, settings, true);
- }
- };
+ Bundle errorResult = checkRequirements(params);
+ if (errorResult != null) {
+ return errorResult;
+ }
- checkAndEnqueue(r);
+ return signImpl(params, input, output, appSettings);
}
@Override
- public void sign(final OpenPgpData input, final OpenPgpData output,
- final IOpenPgpCallback callback) throws RemoteException {
- final AppSettings settings = getAppSettings();
-
- Runnable r = new Runnable() {
- @Override
- public void run() {
- signSafe(getInput(input), true, callback, settings);
- }
- };
+ public Bundle encrypt(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) {
+ final AppSettings appSettings = getAppSettings();
+
+ Bundle errorResult = checkRequirements(params);
+ if (errorResult != null) {
+ return errorResult;
+ }
- checkAndEnqueue(r);
+ return encryptAndSignImpl(params, input, output, appSettings, false);
}
@Override
- public void decryptAndVerify(final OpenPgpData input, final OpenPgpData output,
- final IOpenPgpCallback callback) throws RemoteException {
+ public Bundle signAndEncrypt(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) {
+ final AppSettings appSettings = getAppSettings();
- final AppSettings settings = getAppSettings();
-
- Runnable r = new Runnable() {
- @Override
- public void run() {
- decryptAndVerifySafe(getInput(input), true, callback, settings);
- }
- };
+ Bundle errorResult = checkRequirements(params);
+ if (errorResult != null) {
+ return errorResult;
+ }
- checkAndEnqueue(r);
+ return encryptAndSignImpl(params, input, output, appSettings, true);
}
@Override
- public void getKeyIds(final String[] userIds, final boolean allowUserInteraction,
- final IOpenPgpKeyIdsCallback callback) throws RemoteException {
-
- final AppSettings settings = getAppSettings();
+ public Bundle decryptAndVerify(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) {
+ final AppSettings appSettings = getAppSettings();
- Runnable r = new Runnable() {
- @Override
- public void run() {
- getKeyIdsSafe(userIds, allowUserInteraction, callback, settings);
- }
- };
+ Bundle errorResult = checkRequirements(params);
+ if (errorResult != null) {
+ return errorResult;
+ }
- checkAndEnqueue(r);
+ return decryptAndVerifyImpl(params, input, output, appSettings);
}
- };
-
- private static byte[] getInput(OpenPgpData data) {
- // TODO: support Uri and ParcelFileDescriptor
-
- byte[] inBytes = null;
- switch (data.getType()) {
- case OpenPgpData.TYPE_STRING:
- inBytes = data.getString().getBytes();
- break;
-
- case OpenPgpData.TYPE_BYTE_ARRAY:
- inBytes = data.getBytes();
- break;
+ @Override
+ public Bundle getKeyIds(Bundle params) {
+ Bundle errorResult = checkRequirements(params);
+ if (errorResult != null) {
+ return errorResult;
+ }
- default:
- Log.e(Constants.TAG, "Uri and ParcelFileDescriptor not supported right now!");
- break;
+ return getKeyIdsImpl(params);
}
- return inBytes;
- }
+ };
@Override
public IBinder onBind(Intent intent) {
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 bc513d532..cfd2b9ec3 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
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2013-2014 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
@@ -19,17 +19,16 @@ package org.sufficientlysecure.keychain.service.remote;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.TimeUnit;
+import org.openintents.openpgp.OpenPgpError;
+import org.openintents.openpgp.util.OpenPgpConstants;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.service.exception.WrongPackageSignatureException;
import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.util.PausableThreadPoolExecutor;
+import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
@@ -50,66 +49,19 @@ import android.os.Messenger;
public abstract class RemoteService extends Service {
Context mContext;
- private final ArrayBlockingQueue<Runnable> mPoolQueue = new ArrayBlockingQueue<Runnable>(100);
- // TODO: Are these parameters okay?
- private PausableThreadPoolExecutor mThreadPool = new PausableThreadPoolExecutor(2, 4, 10,
- TimeUnit.SECONDS, mPoolQueue);
+ private static final int PRIVATE_REQUEST_CODE_REGISTER = 651;
+ private static final int PRIVATE_REQUEST_CODE_ERROR = 652;
- private final Object userInputLock = new Object();
-
- /**
- * Override handleUserInput() to handle OKAY (1) and CANCEL (0). After handling the waiting
- * threads will be notified and the queue resumed
- */
- protected class UserInputCallback extends BaseCallback {
-
- public void handleUserInput(Message msg) {
- }
-
- @Override
- public boolean handleMessage(Message msg) {
- handleUserInput(msg);
-
- // resume
- synchronized (userInputLock) {
- userInputLock.notifyAll();
- }
- mThreadPool.resume();
- return true;
- }
-
- }
-
- /**
- * Extends Handler.Callback with OKAY (1), CANCEL (0) variables
- */
- private class BaseCallback implements Handler.Callback {
- public static final int OKAY = 1;
- public static final int CANCEL = 0;
-
- @Override
- public boolean handleMessage(Message msg) {
- return false;
- }
-
- }
public Context getContext() {
return mContext;
}
- /**
- * Should be used from Stub implementations of AIDL interfaces to enqueue a runnable for
- * execution
- *
- * @param r
- */
- protected void checkAndEnqueue(Runnable r) {
+ protected Bundle isAllowed(Bundle params) {
try {
if (isCallerAllowed(false)) {
- mThreadPool.execute(r);
- Log.d(Constants.TAG, "Enqueued runnable…");
+ return null;
} else {
String[] callingPackages = getPackageManager().getPackagesForUid(
Binder.getCallingUid());
@@ -121,32 +73,46 @@ public abstract class RemoteService extends Service {
packageSignature = getPackageSignature(packageName);
} catch (NameNotFoundException e) {
Log.e(Constants.TAG, "Should not happen, returning!", e);
- return;
- }
- Log.e(Constants.TAG,
- "Not allowed to use service! Starting activity for registration!");
- Bundle extras = new Bundle();
- extras.putString(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
- extras.putByteArray(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageSignature);
- RegisterActivityCallback callback = new RegisterActivityCallback();
-
- pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_REGISTER, callback,
- extras);
-
- if (callback.isAllowed()) {
- mThreadPool.execute(r);
- Log.d(Constants.TAG, "Enqueued runnable…");
- } else {
- Log.d(Constants.TAG, "User disallowed app!");
+ // return error
+ Bundle result = new Bundle();
+ result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
+ result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
+ new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
+ return result;
}
+ Log.e(Constants.TAG, "Not allowed to use service! return PendingIntent for registration!");
+
+ Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
+ 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);
+
+ 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);
+
+ return result;
}
} catch (WrongPackageSignatureException e) {
- Log.e(Constants.TAG, e.getMessage());
+ Log.e(Constants.TAG, "wrong signature!", e);
+
+ 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);
+
+ 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);
- Bundle extras = new Bundle();
- extras.putString(RemoteServiceActivity.EXTRA_ERROR_MESSAGE,
- getString(R.string.api_error_wrong_signature));
- pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_ERROR_MESSAGE, null, extras);
+ return result;
}
}
@@ -161,40 +127,8 @@ public abstract class RemoteService extends Service {
}
/**
- * Locks current thread and pauses execution of runnables and starts activity for user input
- *
- * @param action
- * @param messenger
- * @param extras
- */
- protected void pauseAndStartUserInteraction(String action, BaseCallback callback, Bundle extras) {
- synchronized (userInputLock) {
- mThreadPool.pause();
-
- Log.d(Constants.TAG, "starting activity...");
- Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.setAction(action);
-
- Messenger messenger = new Messenger(new Handler(getMainLooper(), callback));
-
- extras.putParcelable(RemoteServiceActivity.EXTRA_MESSENGER, messenger);
- intent.putExtras(extras);
-
- startActivity(intent);
-
- // lock current thread for user input
- try {
- userInputLock.wait();
- } catch (InterruptedException e) {
- Log.e(Constants.TAG, "CryptoService", e);
- }
- }
- }
-
- /**
* Retrieves AppSettings from database for the application calling this remote service
- *
+ *
* @return
*/
protected AppSettings getAppSettings() {
@@ -215,66 +149,11 @@ public abstract class RemoteService extends Service {
return null;
}
- class RegisterActivityCallback extends BaseCallback {
- public static final String PACKAGE_NAME = "package_name";
-
- private boolean allowed = false;
- private String packageName;
-
- public boolean isAllowed() {
- return allowed;
- }
-
- public String getPackageName() {
- return packageName;
- }
-
- @Override
- public boolean handleMessage(Message msg) {
- if (msg.arg1 == OKAY) {
- allowed = true;
- packageName = msg.getData().getString(PACKAGE_NAME);
-
- // resume threads
- try {
- if (isPackageAllowed(packageName)) {
- synchronized (userInputLock) {
- userInputLock.notifyAll();
- }
- mThreadPool.resume();
- } else {
- // Should not happen!
- Log.e(Constants.TAG, "Should not happen! Emergency shutdown!");
- mThreadPool.shutdownNow();
- }
- } catch (WrongPackageSignatureException e) {
- Log.e(Constants.TAG, e.getMessage());
-
- Bundle extras = new Bundle();
- extras.putString(RemoteServiceActivity.EXTRA_ERROR_MESSAGE,
- getString(R.string.api_error_wrong_signature));
- pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_ERROR_MESSAGE, null,
- extras);
- }
- } else {
- allowed = false;
-
- synchronized (userInputLock) {
- userInputLock.notifyAll();
- }
- mThreadPool.resume();
- }
- return true;
- }
-
- }
-
/**
* Checks if process that binds to this service (i.e. the package name corresponding to the
* process) is in the list of allowed package names.
- *
- * @param allowOnlySelf
- * allow only Keychain app itself
+ *
+ * @param allowOnlySelf allow only Keychain app itself
* @return true if process is allowed to use this service
* @throws WrongPackageSignatureException
*/
@@ -308,7 +187,7 @@ public abstract class RemoteService extends Service {
/**
* Checks if packageName is a registered app for the API. Does not return true for own package!
- *
+ *
* @param packageName
* @return
* @throws WrongPackageSignatureException
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 7ab39fce1..af8e3ade8 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
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2013-2014 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
@@ -17,8 +17,15 @@
package org.sufficientlysecure.keychain.service.remote;
-import java.util.ArrayList;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Messenger;
+import android.support.v7.app.ActionBarActivity;
+import android.view.View;
+import org.openintents.openpgp.util.OpenPgpConstants;
import org.sufficientlysecure.htmltextview.HtmlTextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
@@ -30,15 +37,7 @@ import org.sufficientlysecure.keychain.ui.SelectPublicKeyFragment;
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.support.v7.app.ActionBarActivity;
-import android.view.View;
-import android.widget.Toast;
+import java.util.ArrayList;
public class RemoteServiceActivity extends ActionBarActivity {
@@ -64,17 +63,11 @@ public class RemoteServiceActivity extends ActionBarActivity {
// error message
public static final String EXTRA_ERROR_MESSAGE = "error_message";
- private Messenger mMessenger;
-
// register view
private AppSettingsFragment mSettingsFragment;
// select pub keys view
private SelectPublicKeyFragment mSelectFragment;
- // has the user clicked one of the buttons
- // or do we need to handle the callback in onStop()
- private boolean finishHandled;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -82,36 +75,12 @@ public class RemoteServiceActivity extends ActionBarActivity {
handleActions(getIntent(), savedInstanceState);
}
- @Override
- protected void onStop() {
- super.onStop();
-
- if (!finishHandled) {
- Message msg = Message.obtain();
- msg.arg1 = RemoteService.RegisterActivityCallback.CANCEL;
- try {
- mMessenger.send(msg);
- } catch (RemoteException e) {
- Log.e(Constants.TAG, "CryptoServiceActivity", e);
- }
- }
- }
-
protected void handleActions(Intent intent, Bundle savedInstanceState) {
- finishHandled = false;
String action = intent.getAction();
- Bundle extras = intent.getExtras();
+ final Bundle extras = intent.getExtras();
- if (extras == null) {
- extras = new Bundle();
- }
- mMessenger = extras.getParcelable(EXTRA_MESSENGER);
-
- /**
- * com.android.crypto actions
- */
if (ACTION_REGISTER.equals(action)) {
final String packageName = extras.getString(EXTRA_PACKAGE_NAME);
final byte[] packageSignature = extras.getByteArray(EXTRA_PACKAGE_SIGNATURE);
@@ -131,37 +100,21 @@ public class RemoteServiceActivity extends ActionBarActivity {
ProviderHelper.insertApiApp(RemoteServiceActivity.this,
mSettingsFragment.getAppSettings());
- Message msg = Message.obtain();
- msg.arg1 = RemoteService.RegisterActivityCallback.OKAY;
- Bundle data = new Bundle();
- data.putString(RemoteService.RegisterActivityCallback.PACKAGE_NAME,
- packageName);
- msg.setData(data);
- try {
- mMessenger.send(msg);
- } catch (RemoteException e) {
- Log.e(Constants.TAG, "CryptoServiceActivity", e);
- }
-
- finishHandled = true;
- finish();
+ // 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);
+ RemoteServiceActivity.this.finish();
}
}
}, R.string.api_register_disallow, new View.OnClickListener() {
@Override
public void onClick(View v) {
// Disallow
-
- Message msg = Message.obtain();
- msg.arg1 = RemoteService.RegisterActivityCallback.CANCEL;
- try {
- mMessenger.send(msg);
- } catch (RemoteException e) {
- Log.e(Constants.TAG, "CryptoServiceActivity", e);
- }
-
- finishHandled = true;
- finish();
+ RemoteServiceActivity.this.setResult(RESULT_CANCELED);
+ RemoteServiceActivity.this.finish();
}
}
);
@@ -175,8 +128,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);
- showPassphraseDialog(secretKeyId);
+ showPassphraseDialog(oldParams, secretKeyId);
} else if (ACTION_SELECT_PUB_KEYS.equals(action)) {
long[] selectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS);
ArrayList<String> missingUserIds = intent
@@ -184,8 +138,8 @@ public class RemoteServiceActivity extends ActionBarActivity {
ArrayList<String> dublicateUserIds = intent
.getStringArrayListExtra(EXTRA_DUBLICATE_USER_IDS);
- String text = new String();
- text += "<b>" + getString(R.string.api_select_pub_keys_text) + "</b>";
+ // TODO: do this with spannable instead of HTML to prevent parsing failures with weird user ids
+ String text = "<b>" + getString(R.string.api_select_pub_keys_text) + "</b>";
text += "<br/><br/>";
if (missingUserIds != null && missingUserIds.size() > 0) {
text += getString(R.string.api_select_pub_keys_missing_text);
@@ -212,40 +166,22 @@ public class RemoteServiceActivity extends ActionBarActivity {
new View.OnClickListener() {
@Override
public void onClick(View v) {
- // ok
-
- Message msg = Message.obtain();
- msg.arg1 = OpenPgpService.SelectPubKeysActivityCallback.OKAY;
- Bundle data = new Bundle();
- data.putLongArray(
- OpenPgpService.SelectPubKeysActivityCallback.PUB_KEY_IDS,
+ // add key ids to params Bundle for new request
+ Bundle params = extras.getBundle(OpenPgpConstants.PI_RESULT_PARAMS);
+ params.putLongArray(OpenPgpConstants.PARAMS_KEY_IDS,
mSelectFragment.getSelectedMasterKeyIds());
- msg.setData(data);
- try {
- mMessenger.send(msg);
- } catch (RemoteException e) {
- Log.e(Constants.TAG, "CryptoServiceActivity", e);
- }
- finishHandled = true;
- finish();
+ Intent finishIntent = new Intent();
+ finishIntent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
+ RemoteServiceActivity.this.setResult(RESULT_OK, finishIntent);
+ RemoteServiceActivity.this.finish();
}
}, R.string.btn_do_not_save, new View.OnClickListener() {
@Override
public void onClick(View v) {
// cancel
-
- Message msg = Message.obtain();
- msg.arg1 = OpenPgpService.SelectPubKeysActivityCallback.CANCEL;
- ;
- try {
- mMessenger.send(msg);
- } catch (RemoteException e) {
- Log.e(Constants.TAG, "CryptoServiceActivity", e);
- }
-
- finishHandled = true;
- finish();
+ RemoteServiceActivity.this.setResult(RESULT_CANCELED);
+ RemoteServiceActivity.this.finish();
}
}
);
@@ -278,8 +214,7 @@ public class RemoteServiceActivity extends ActionBarActivity {
} else if (ACTION_ERROR_MESSAGE.equals(action)) {
String errorMessage = intent.getStringExtra(EXTRA_ERROR_MESSAGE);
- String text = new String();
- text += "<font color=\"red\">" + errorMessage + "</font>";
+ String text = "<font color=\"red\">" + errorMessage + "</font>";
// Inflate a "Done" custom action bar view
ActionBarHelper.setDoneView(getSupportActionBar(), R.string.btn_okay,
@@ -287,7 +222,8 @@ public class RemoteServiceActivity extends ActionBarActivity {
@Override
public void onClick(View v) {
- finish();
+ RemoteServiceActivity.this.setResult(RESULT_OK);
+ RemoteServiceActivity.this.finish();
}
});
@@ -297,7 +233,8 @@ public class RemoteServiceActivity extends ActionBarActivity {
HtmlTextView textView = (HtmlTextView) findViewById(R.id.api_app_error_message_text);
textView.setHtmlFromString(text);
} else {
- Log.e(Constants.TAG, "Wrong action!");
+ Log.e(Constants.TAG, "Action does not exist!");
+ setResult(RESULT_CANCELED);
finish();
}
}
@@ -307,31 +244,21 @@ 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(long secretKeyId) {
+ private void showPassphraseDialog(final Bundle params, 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) {
- Message msg = Message.obtain();
- msg.arg1 = OpenPgpService.PassphraseActivityCallback.OKAY;
- try {
- mMessenger.send(msg);
- } catch (RemoteException e) {
- Log.e(Constants.TAG, "CryptoServiceActivity", e);
- }
+ // 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);
} else {
- Message msg = Message.obtain();
- msg.arg1 = OpenPgpService.PassphraseActivityCallback.CANCEL;
- try {
- mMessenger.send(msg);
- } catch (RemoteException e) {
- Log.e(Constants.TAG, "CryptoServiceActivity", e);
- }
+ RemoteServiceActivity.this.setResult(RESULT_CANCELED);
}
- finishHandled = true;
- finish();
+ RemoteServiceActivity.this.finish();
}
};
@@ -344,9 +271,12 @@ public class RemoteServiceActivity extends ActionBarActivity {
passphraseDialog.show(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);
+ 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);
+ finish();
}
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/WrongPackageSignatureException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/WrongPackageSignatureException.java
index cef002265..cc08548e8 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/WrongPackageSignatureException.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/WrongPackageSignatureException.java
@@ -1,4 +1,4 @@
-package org.sufficientlysecure.keychain.service.exception;
+package org.sufficientlysecure.keychain.service.remote;
public class WrongPackageSignatureException extends Exception {
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 3dd077d12..b8eed83c9 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
@@ -300,7 +300,7 @@ public class DecryptActivity extends DrawerActivity {
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
if (sharedText != null) {
// handle like normal text decryption, override action and extras to later
- // execute ACTION_DECRYPT in main actions
+ // executeServiceMethod ACTION_DECRYPT in main actions
extras.putString(EXTRA_TEXT, sharedText);
action = ACTION_DECRYPT;
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
index 81446db99..85bfba224 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
@@ -173,7 +173,7 @@ public class EncryptActivity extends DrawerActivity {
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
if (sharedText != null) {
// handle like normal text encryption, override action and extras to later
- // execute ACTION_ENCRYPT in main actions
+ // executeServiceMethod ACTION_ENCRYPT in main actions
extras.putString(EXTRA_TEXT, sharedText);
extras.putBoolean(EXTRA_ASCII_ARMOR, true);
action = ACTION_ENCRYPT;
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
index e0f25b632..1864e0d9d 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
@@ -57,6 +57,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
+ "IMPORT_KEY_FROM_QR_CODE";
public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER = Constants.INTENT_PREFIX
+ "IMPORT_KEY_FROM_KEYSERVER";
+ // TODO: implement:
public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN = Constants.INTENT_PREFIX
+ "IMPORT_KEY_FROM_KEY_SERVER_AND_RETURN";
diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml
index 88ad10a0a..d34fe0105 100644
--- a/OpenPGP-Keychain/src/main/res/values/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values/strings.xml
@@ -295,7 +295,7 @@
<string name="progress_saving">saving…</string>
<string name="progress_importing">importing…</string>
<string name="progress_exporting">exporting…</string>
- <string name="progress_generating">generating key, this can take a while…</string>
+ <string name="progress_generating">generating key, this can take up to 3 minutes…</string>
<string name="progress_building_key">building key…</string>
<string name="progress_preparing_master_key">preparing master key…</string>
<string name="progress_certifying_master_key">certifying master key…</string>
@@ -383,7 +383,7 @@
<string name="api_settings_revoke">Revoke access</string>
<string name="api_settings_package_name">Package Name</string>
<string name="api_settings_package_signature">SHA-256 of Package Signature</string>
- <string name="api_register_text">The following application requests access to OpenPGP Keychain.\n\nAllow permanent access?</string>
+ <string name="api_register_text">The displayed application requests access to OpenPGP Keychain.\nAllow access?\n\nWARNING: If you do not know why this screen appeared, disallow access! You can revoke access later using the \'Registered Applications\' screen.</string>
<string name="api_register_allow">Allow access</string>
<string name="api_register_disallow">Disallow access</string>
<string name="api_register_error_select_key">Please select a key!</string>