aboutsummaryrefslogtreecommitdiffstats
path: root/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2014-03-04 20:53:44 +0100
committerDominik Schürmann <dominik@dominikschuermann.de>2014-03-04 20:53:44 +0100
commit06f9134eb1c386446d56fe58fa49c35b7482ed86 (patch)
treecb2d767bfea33dae7e23ff3f8e0b001c24a8eb3d /OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service
parent89a4c38cc09425ac2e302882a63a30bdfe8a7e86 (diff)
downloadopen-keychain-06f9134eb1c386446d56fe58fa49c35b7482ed86.tar.gz
open-keychain-06f9134eb1c386446d56fe58fa49c35b7482ed86.tar.bz2
open-keychain-06f9134eb1c386446d56fe58fa49c35b7482ed86.zip
Enforce private key for applications, verify signed-only texts without passphrase input, better internal decrypt and verify method
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.java19
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java111
2 files changed, 28 insertions, 102 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 302dbea0b..9c499ebd7 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;
@@ -181,13 +182,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";
@@ -489,15 +484,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) {
@@ -867,10 +864,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/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java
index 5d2f5a815..8b34c4421 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,7 +21,6 @@ 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;
@@ -33,9 +32,10 @@ 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.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
@@ -284,98 +284,29 @@ public class OpenPgpService extends RemoteService {
Intent result = new Intent();
try {
- // TODO:
- // 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: put this code into PgpDecryptVerify class
-
- // 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 (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
- Intent passphraseBundle = getPassphraseBundleIntent(data, appSettings.getKeyId());
- return passphraseBundle;
- }
-
+ 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);
-
- 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);
- // TODO: this also decrypts with other secret keys that have no passphrase!!!
- outputBundle = builder.build().execute();
-
- //TODO: instead of using all these wrapping use OpenPgpSignatureResult directly
- // in DecryptVerify class and then in DecryptActivity
- 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);
-
- // TODO: SIGNATURE_SUCCESS_CERTIFIED is currently not implemented
- int signatureStatus = OpenPgpSignatureResult.SIGNATURE_ERROR;
- if (signatureSuccess) {
- signatureStatus = OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED;
- } 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!!!
@@ -390,11 +321,9 @@ public class OpenPgpService extends RemoteService {
result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
}
-
- OpenPgpSignatureResult sigResult = new OpenPgpSignatureResult(signatureStatus,
- signatureUserId, signatureOnly, signatureKeyId);
- result.putExtra(OpenPgpApi.RESULT_SIGNATURE, sigResult);
+ result.putExtra(OpenPgpApi.RESULT_SIGNATURE, signatureResult);
}
+
} finally {
is.close();
os.close();