aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2014-08-28 11:00:18 +0200
committerDominik Schürmann <dominik@dominikschuermann.de>2014-08-28 11:00:18 +0200
commitc0ebc926117d3e444c7c32bf3251880852000df6 (patch)
treeb84926b3eee5cf1cfd6d38a2c3bec23e8f0b6779 /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service
parentad69e47cec58287d82978b28416db50f6c3feb77 (diff)
parentb193965e585d0d492cf2744e3c86ecc9e45b71d4 (diff)
downloadopen-keychain-c0ebc926117d3e444c7c32bf3251880852000df6.tar.gz
open-keychain-c0ebc926117d3e444c7c32bf3251880852000df6.tar.bz2
open-keychain-c0ebc926117d3e444c7c32bf3251880852000df6.zip
Merge branch 'master' into yubikey
Conflicts: OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java92
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java154
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java77
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java58
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java30
6 files changed, 321 insertions, 96 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java
index 43ed2dad0..fbe914b78 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java
@@ -21,6 +21,8 @@ import android.accounts.Account;
import android.app.Service;
import android.content.AbstractThreadedSyncAdapter;
import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
import android.content.Intent;
import android.content.SyncResult;
import android.os.Bundle;
@@ -29,9 +31,11 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
+import android.provider.ContactsContract;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.KeychainApplication;
+import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.ContactHelper;
import org.sufficientlysecure.keychain.helper.EmailKeyHelper;
import org.sufficientlysecure.keychain.util.Log;
@@ -42,7 +46,7 @@ public class ContactSyncAdapterService extends Service {
private class ContactSyncAdapter extends AbstractThreadedSyncAdapter {
- private final AtomicBoolean importDone = new AtomicBoolean(false);
+// private final AtomicBoolean importDone = new AtomicBoolean(false);
public ContactSyncAdapter() {
super(ContactSyncAdapterService.this, true);
@@ -51,47 +55,59 @@ public class ContactSyncAdapterService extends Service {
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider,
final SyncResult syncResult) {
- importDone.set(false);
- KeychainApplication.setupAccountAsNeeded(ContactSyncAdapterService.this);
- EmailKeyHelper.importContacts(getContext(), new Messenger(new Handler(Looper.getMainLooper(),
- new Handler.Callback() {
- @Override
- public boolean handleMessage(Message msg) {
- Bundle data = msg.getData();
- switch (msg.arg1) {
- case KeychainIntentServiceHandler.MESSAGE_OKAY:
- Log.d(Constants.TAG, "Syncing... Done.");
- synchronized (importDone) {
- importDone.set(true);
- importDone.notifyAll();
- }
- return true;
- case KeychainIntentServiceHandler.MESSAGE_UPDATE_PROGRESS:
- if (data.containsKey(KeychainIntentServiceHandler.DATA_PROGRESS) &&
- data.containsKey(KeychainIntentServiceHandler.DATA_PROGRESS_MAX)) {
- Log.d(Constants.TAG, "Syncing... Progress: " +
- data.getInt(KeychainIntentServiceHandler.DATA_PROGRESS) + "/" +
- data.getInt(KeychainIntentServiceHandler.DATA_PROGRESS_MAX));
- return false;
- }
- default:
- Log.d(Constants.TAG, "Syncing... " + msg.toString());
- return false;
- }
- }
- })));
- synchronized (importDone) {
- try {
- if (!importDone.get()) importDone.wait();
- } catch (InterruptedException e) {
- Log.w(Constants.TAG, e);
- return;
- }
- }
+ Log.d(Constants.TAG, "Performing a sync!");
+ // TODO: Import is currently disabled for 2.8, until we implement proper origin management
+// importDone.set(false);
+// KeychainApplication.setupAccountAsNeeded(ContactSyncAdapterService.this);
+// EmailKeyHelper.importContacts(getContext(), new Messenger(new Handler(Looper.getMainLooper(),
+// new Handler.Callback() {
+// @Override
+// public boolean handleMessage(Message msg) {
+// Bundle data = msg.getData();
+// switch (msg.arg1) {
+// case KeychainIntentServiceHandler.MESSAGE_OKAY:
+// Log.d(Constants.TAG, "Syncing... Done.");
+// synchronized (importDone) {
+// importDone.set(true);
+// importDone.notifyAll();
+// }
+// return true;
+// case KeychainIntentServiceHandler.MESSAGE_UPDATE_PROGRESS:
+// if (data.containsKey(KeychainIntentServiceHandler.DATA_PROGRESS) &&
+// data.containsKey(KeychainIntentServiceHandler.DATA_PROGRESS_MAX)) {
+// Log.d(Constants.TAG, "Syncing... Progress: " +
+// data.getInt(KeychainIntentServiceHandler.DATA_PROGRESS) + "/" +
+// data.getInt(KeychainIntentServiceHandler.DATA_PROGRESS_MAX));
+// return false;
+// }
+// default:
+// Log.d(Constants.TAG, "Syncing... " + msg.toString());
+// return false;
+// }
+// }
+// })));
+// synchronized (importDone) {
+// try {
+// if (!importDone.get()) importDone.wait();
+// } catch (InterruptedException e) {
+// Log.w(Constants.TAG, e);
+// return;
+// }
+// }
ContactHelper.writeKeysToContacts(ContactSyncAdapterService.this);
}
}
+ public static void requestSync() {
+ Bundle extras = new Bundle();
+ // no need to wait for internet connection!
+ extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+ ContentResolver.requestSync(
+ new Account(Constants.ACCOUNT_NAME, Constants.ACCOUNT_TYPE),
+ ContactsContract.AUTHORITY,
+ extras);
+ }
+
@Override
public IBinder onBind(Intent intent) {
return new ContactSyncAdapter().getSyncAdapterBinder();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
index d6c470e11..021e6bc07 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
*
* 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
@@ -49,11 +50,14 @@ import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException;
+import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.service.OperationResults.ConsolidateResult;
import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult;
import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult;
+import org.sufficientlysecure.keychain.service.OperationResults.SaveKeyringResult;
import org.sufficientlysecure.keychain.util.FileImportCache;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
@@ -102,6 +106,10 @@ public class KeychainIntentService extends IntentService
public static final String ACTION_CERTIFY_KEYRING = Constants.INTENT_PREFIX + "SIGN_KEYRING";
+ public static final String ACTION_DELETE = Constants.INTENT_PREFIX + "DELETE";
+
+ public static final String ACTION_CONSOLIDATE = Constants.INTENT_PREFIX + "CONSOLIDATE";
+
/* keys for data bundle */
// encrypt, decrypt, import export
@@ -139,8 +147,13 @@ public class KeychainIntentService extends IntentService
// delete file securely
public static final String DELETE_FILE = "deleteFile";
+ // delete keyring(s)
+ public static final String DELETE_KEY_LIST = "delete_list";
+ public static final String DELETE_IS_SECRET = "delete_is_secret";
+
// import key
public static final String IMPORT_KEY_LIST = "import_key_list";
+ public static final String IMPORT_KEY_FILE = "import_key_file";
// export key
public static final String EXPORT_OUTPUT_STREAM = "export_output_stream";
@@ -162,6 +175,10 @@ public class KeychainIntentService extends IntentService
public static final String CERTIFY_KEY_PUB_KEY_ID = "sign_key_pub_key_id";
public static final String CERTIFY_KEY_UIDS = "sign_key_uids";
+ // consolidate
+ public static final String CONSOLIDATE_RECOVERY = "consolidate_recovery";
+
+
/*
* possible data keys as result send over messenger
*/
@@ -176,8 +193,6 @@ public class KeychainIntentService extends IntentService
// export
public static final String RESULT_EXPORT = "exported";
- public static final String RESULT_IMPORT = "result";
-
Messenger mMessenger;
private boolean mIsCanceled;
@@ -246,27 +261,31 @@ public class KeychainIntentService extends IntentService
String originalFilename = getOriginalFilename(data);
/* Operation */
- PgpSignEncrypt.Builder builder =
- new PgpSignEncrypt.Builder(
- new ProviderHelper(this),
- inputData, outStream);
- builder.setProgressable(this);
-
- builder.setEnableAsciiArmorOutput(useAsciiArmor)
+ PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(
+ new ProviderHelper(this),
+ inputData, outStream
+ );
+ builder.setProgressable(this)
+ .setEnableAsciiArmorOutput(useAsciiArmor)
.setVersionHeader(PgpHelper.getVersionForHeader(this))
.setCompressionId(compressionId)
.setSymmetricEncryptionAlgorithm(
Preferences.getPreferences(this).getDefaultEncryptionAlgorithm())
.setEncryptionMasterKeyIds(encryptionKeyIds)
.setSymmetricPassphrase(symmetricPassphrase)
- .setSignatureMasterKeyId(signatureKeyId)
- .setEncryptToSigner(true)
- .setSignatureHashAlgorithm(
- Preferences.getPreferences(this).getDefaultHashAlgorithm())
- .setSignaturePassphrase(
- PassphraseCacheService.getCachedPassphrase(this, signatureKeyId))
.setOriginalFilename(originalFilename);
+ try {
+ builder.setSignatureMasterKeyId(signatureKeyId)
+ .setSignaturePassphrase(
+ PassphraseCacheService.getCachedPassphrase(this, signatureKeyId))
+ .setSignatureHashAlgorithm(
+ Preferences.getPreferences(this).getDefaultHashAlgorithm())
+ .setAdditionalEncryptId(signatureKeyId);
+ } catch (PassphraseCacheService.KeyNotFoundException e) {
+ // encrypt-only
+ }
+
// this assumes that the bytes are cleartext (valid for current implementation!)
if (source == IO_BYTES) {
builder.setCleartextInput(true);
@@ -391,23 +410,41 @@ public class KeychainIntentService extends IntentService
}
/* Operation */
- ProviderHelper providerHelper = new ProviderHelper(this);
PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 10, 60, 100));
- EditKeyResult result;
+ EditKeyResult modifyResult;
if (saveParcel.mMasterKeyId != null) {
String passphrase = data.getString(SAVE_KEYRING_PASSPHRASE);
CanonicalizedSecretKeyRing secRing =
- providerHelper.getCanonicalizedSecretKeyRing(saveParcel.mMasterKeyId);
+ new ProviderHelper(this).getCanonicalizedSecretKeyRing(saveParcel.mMasterKeyId);
- result = keyOperations.modifySecretKeyRing(secRing, saveParcel, passphrase);
+ modifyResult = keyOperations.modifySecretKeyRing(secRing, saveParcel, passphrase);
} else {
- result = keyOperations.createSecretKeyRing(saveParcel);
+ modifyResult = keyOperations.createSecretKeyRing(saveParcel);
}
- UncachedKeyRing ring = result.getRing();
+ // If the edit operation didn't succeed, exit here
+ if (!modifyResult.success()) {
+ // always return SaveKeyringResult, so create one out of the EditKeyResult
+ SaveKeyringResult saveResult = new SaveKeyringResult(
+ SaveKeyringResult.RESULT_ERROR,
+ modifyResult.getLog(),
+ null);
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, saveResult);
+ return;
+ }
- providerHelper.saveSecretKeyRing(ring, new ProgressScaler(this, 60, 95, 100));
+ UncachedKeyRing ring = modifyResult.getRing();
+
+ // Save the keyring. The ProviderHelper is initialized with the previous log
+ SaveKeyringResult saveResult = new ProviderHelper(this, modifyResult.getLog())
+ .saveSecretKeyRing(ring, new ProgressScaler(this, 60, 95, 100));
+
+ // If the edit operation didn't succeed, exit here
+ if (!saveResult.success()) {
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, saveResult);
+ return;
+ }
// cache new passphrase
if (saveParcel.mNewPassphrase != null) {
@@ -417,8 +454,11 @@ public class KeychainIntentService extends IntentService
setProgress(R.string.progress_done, 100, 100);
+ // make sure new data is synced into contacts
+ ContactSyncAdapterService.requestSync();
+
/* Output */
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result);
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, saveResult);
} catch (Exception e) {
sendErrorToHandler(e);
}
@@ -454,17 +494,21 @@ public class KeychainIntentService extends IntentService
} else {
// get entries from cached file
FileImportCache<ParcelableKeyRing> cache =
- new FileImportCache<ParcelableKeyRing>(this);
+ new FileImportCache<ParcelableKeyRing>(this, "key_import.pcl");
entries = cache.readCacheIntoList();
}
- PgpImportExport pgpImportExport = new PgpImportExport(this, this);
+ ProviderHelper providerHelper = new ProviderHelper(this);
+ PgpImportExport pgpImportExport = new PgpImportExport(this, providerHelper, this);
ImportKeyResult result = pgpImportExport.importKeyRings(entries);
- Bundle resultData = new Bundle();
- resultData.putParcelable(RESULT_IMPORT, result);
+ if (result.mSecret > 0) {
+ providerHelper.consolidateDatabaseStep1(this);
+ }
+ // make sure new data is synced into contacts
+ ContactSyncAdapterService.requestSync();
- sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData);
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result);
} catch (Exception e) {
sendErrorToHandler(e);
}
@@ -549,8 +593,9 @@ public class KeychainIntentService extends IntentService
CanonicalizedPublicKeyRing keyring = providerHelper.getCanonicalizedPublicKeyRing(dataUri);
PgpImportExport pgpImportExport = new PgpImportExport(this, null);
- boolean uploaded = pgpImportExport.uploadKeyRingToServer(server, keyring);
- if (!uploaded) {
+ try {
+ pgpImportExport.uploadKeyRingToServer(server, keyring);
+ } catch (Keyserver.AddKeyException e) {
throw new PgpGeneralException("Unable to export key to selected server");
}
@@ -639,7 +684,56 @@ public class KeychainIntentService extends IntentService
} catch (Exception e) {
sendErrorToHandler(e);
}
+
+ } else if (ACTION_DELETE.equals(action)) {
+
+ try {
+
+ long[] masterKeyIds = data.getLongArray(DELETE_KEY_LIST);
+ boolean isSecret = data.getBoolean(DELETE_IS_SECRET);
+
+ if (masterKeyIds.length == 0) {
+ throw new PgpGeneralException("List of keys to delete is empty");
+ }
+
+ if (isSecret && masterKeyIds.length > 1) {
+ throw new PgpGeneralException("Secret keys can only be deleted individually!");
+ }
+
+ boolean success = false;
+ for (long masterKeyId : masterKeyIds) {
+ int count = getContentResolver().delete(
+ KeyRingData.buildPublicKeyRingUri(masterKeyId), null, null
+ );
+ success |= count > 0;
+ }
+
+ if (isSecret && success) {
+ ConsolidateResult result =
+ new ProviderHelper(this).consolidateDatabaseStep1(this);
+ }
+
+ if (success) {
+ // make sure new data is synced into contacts
+ ContactSyncAdapterService.requestSync();
+
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY);
+ }
+
+ } catch (Exception e) {
+ sendErrorToHandler(e);
+ }
+
+ } else if (ACTION_CONSOLIDATE.equals(action)) {
+ ConsolidateResult result;
+ if (data.containsKey(CONSOLIDATE_RECOVERY) && data.getBoolean(CONSOLIDATE_RECOVERY)) {
+ result = new ProviderHelper(this).consolidateDatabaseStep2(this);
+ } else {
+ result = new ProviderHelper(this).consolidateDatabaseStep1(this);
+ }
+ sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, result);
}
+
}
private void sendErrorToHandler(Exception e) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java
index d7d98fd68..142bf65cc 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
*
* 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
@@ -155,10 +156,8 @@ public class OperationResultParcel implements Parcelable {
if ((resultType & OperationResultParcel.RESULT_ERROR) == 0) {
if (getLog().containsWarnings()) {
- duration = 0;
color = Style.ORANGE;
} else {
- duration = SuperToast.Duration.LONG;
color = Style.GREEN;
}
@@ -167,7 +166,6 @@ public class OperationResultParcel implements Parcelable {
} else {
- duration = 0;
color = Style.RED;
str = "operation failed";
@@ -180,8 +178,8 @@ public class OperationResultParcel implements Parcelable {
button ? SuperToast.Type.BUTTON : SuperToast.Type.STANDARD,
Style.getStyle(color, SuperToast.Animations.POPUP));
toast.setText(str);
- toast.setDuration(duration);
- toast.setIndeterminate(duration == 0);
+ toast.setDuration(SuperToast.Duration.EXTRA_LONG);
+ toast.setIndeterminate(false);
toast.setSwipeToDismiss(true);
// If we have a log and it's non-empty, show a View Log button
if (button) {
@@ -289,6 +287,7 @@ public class OperationResultParcel implements Parcelable {
MSG_IS_SUCCESS (R.string.msg_is_success),
// keyring canonicalization
+ MSG_KC_V3_KEY (R.string.msg_kc_v3_key),
MSG_KC_PUBLIC (R.string.msg_kc_public),
MSG_KC_SECRET (R.string.msg_kc_secret),
MSG_KC_FATAL_NO_UID (R.string.msg_kc_fatal_no_uid),
@@ -324,6 +323,7 @@ public class OperationResultParcel implements Parcelable {
MSG_KC_UID_BAD_TIME (R.string.msg_kc_uid_bad_time),
MSG_KC_UID_BAD_TYPE (R.string.msg_kc_uid_bad_type),
MSG_KC_UID_BAD (R.string.msg_kc_uid_bad),
+ MSG_KC_UID_CERT_DUP (R.string.msg_kc_uid_cert_dup),
MSG_KC_UID_DUP (R.string.msg_kc_uid_dup),
MSG_KC_UID_FOREIGN (R.string.msg_kc_uid_foreign),
MSG_KC_UID_NO_CERT (R.string.msg_kc_uid_no_cert),
@@ -333,10 +333,11 @@ public class OperationResultParcel implements Parcelable {
// keyring consolidation
+ MSG_MG_ERROR_SECRET_DUMMY(R.string.msg_mg_error_secret_dummy),
+ MSG_MG_ERROR_ENCODE(R.string.msg_mg_error_encode),
+ MSG_MG_ERROR_HETEROGENEOUS(R.string.msg_mg_error_heterogeneous),
MSG_MG_PUBLIC (R.string.msg_mg_public),
MSG_MG_SECRET (R.string.msg_mg_secret),
- MSG_MG_FATAL_ENCODE (R.string.msg_mg_fatal_encode),
- MSG_MG_HETEROGENEOUS (R.string.msg_mg_heterogeneous),
MSG_MG_NEW_SUBKEY (R.string.msg_mg_new_subkey),
MSG_MG_FOUND_NEW (R.string.msg_mg_found_new),
MSG_MG_UNCHANGED (R.string.msg_mg_unchanged),
@@ -346,10 +347,16 @@ public class OperationResultParcel implements Parcelable {
MSG_CR_ERROR_NO_MASTER (R.string.msg_cr_error_no_master),
MSG_CR_ERROR_NO_USER_ID (R.string.msg_cr_error_no_user_id),
MSG_CR_ERROR_NO_CERTIFY (R.string.msg_cr_error_no_certify),
+ MSG_CR_ERROR_NULL_EXPIRY(R.string.msg_cr_error_null_expiry),
MSG_CR_ERROR_KEYSIZE_512 (R.string.msg_cr_error_keysize_512),
+ MSG_CR_ERROR_NO_KEYSIZE (R.string.msg_cr_error_no_keysize),
+ MSG_CR_ERROR_NO_CURVE (R.string.msg_cr_error_no_curve),
MSG_CR_ERROR_UNKNOWN_ALGO (R.string.msg_cr_error_unknown_algo),
MSG_CR_ERROR_INTERNAL_PGP (R.string.msg_cr_error_internal_pgp),
- MSG_CR_ERROR_MASTER_ELGAMAL (R.string.msg_cr_error_master_elgamal),
+ MSG_CR_ERROR_FLAGS_DSA (R.string.msg_cr_error_flags_dsa),
+ MSG_CR_ERROR_FLAGS_ELGAMAL (R.string.msg_cr_error_flags_elgamal),
+ MSG_CR_ERROR_FLAGS_ECDSA (R.string.msg_cr_error_flags_ecdsa),
+ MSG_CR_ERROR_FLAGS_ECDH (R.string.msg_cr_error_flags_ecdh),
// secret key modify
MSG_MF (R.string.msg_mr),
@@ -357,18 +364,27 @@ public class OperationResultParcel implements Parcelable {
MSG_MF_ERROR_FINGERPRINT (R.string.msg_mf_error_fingerprint),
MSG_MF_ERROR_KEYID (R.string.msg_mf_error_keyid),
MSG_MF_ERROR_INTEGRITY (R.string.msg_mf_error_integrity),
+ MSG_MF_ERROR_MASTER_NONE(R.string.msg_mf_error_master_none),
+ MSG_MF_ERROR_NO_CERTIFY (R.string.msg_cr_error_no_certify),
MSG_MF_ERROR_NOEXIST_PRIMARY (R.string.msg_mf_error_noexist_primary),
- MSG_MF_ERROR_REVOKED_PRIMARY (R.string.msg_mf_error_revoked_primary),
+ MSG_MF_ERROR_NOEXIST_REVOKE (R.string.msg_mf_error_noexist_revoke),
+ MSG_MF_ERROR_NULL_EXPIRY (R.string.msg_mf_error_null_expiry),
+ MSG_MF_ERROR_PASSPHRASE_MASTER(R.string.msg_mf_error_passphrase_master),
+ MSG_MF_ERROR_PAST_EXPIRY(R.string.msg_mf_error_past_expiry),
MSG_MF_ERROR_PGP (R.string.msg_mf_error_pgp),
+ MSG_MF_ERROR_REVOKED_PRIMARY (R.string.msg_mf_error_revoked_primary),
MSG_MF_ERROR_SIG (R.string.msg_mf_error_sig),
+ MSG_MF_ERROR_SUBKEY_MISSING(R.string.msg_mf_error_subkey_missing),
+ MSG_MF_MASTER (R.string.msg_mf_master),
MSG_MF_PASSPHRASE (R.string.msg_mf_passphrase),
+ MSG_MF_PASSPHRASE_KEY (R.string.msg_mf_passphrase_key),
+ MSG_MF_PASSPHRASE_EMPTY_RETRY (R.string.msg_mf_passphrase_empty_retry),
+ MSG_MF_PASSPHRASE_FAIL (R.string.msg_mf_passphrase_fail),
MSG_MF_PRIMARY_REPLACE_OLD (R.string.msg_mf_primary_replace_old),
MSG_MF_PRIMARY_NEW (R.string.msg_mf_primary_new),
MSG_MF_SUBKEY_CHANGE (R.string.msg_mf_subkey_change),
- MSG_MF_SUBKEY_MISSING (R.string.msg_mf_subkey_missing),
MSG_MF_SUBKEY_NEW_ID (R.string.msg_mf_subkey_new_id),
MSG_MF_SUBKEY_NEW (R.string.msg_mf_subkey_new),
- MSG_MF_SUBKEY_PAST_EXPIRY (R.string.msg_mf_subkey_past_expiry),
MSG_MF_SUBKEY_REVOKE (R.string.msg_mf_subkey_revoke),
MSG_MF_SUCCESS (R.string.msg_mf_success),
MSG_MF_UID_ADD (R.string.msg_mf_uid_add),
@@ -377,6 +393,32 @@ public class OperationResultParcel implements Parcelable {
MSG_MF_UID_ERROR_EMPTY (R.string.msg_mf_uid_error_empty),
MSG_MF_UNLOCK_ERROR (R.string.msg_mf_unlock_error),
MSG_MF_UNLOCK (R.string.msg_mf_unlock),
+
+ // consolidate
+ MSG_CON_CRITICAL_IN (R.string.msg_con_critical_in),
+ MSG_CON_CRITICAL_OUT (R.string.msg_con_critical_out),
+ MSG_CON_DB_CLEAR (R.string.msg_con_db_clear),
+ MSG_CON_DELETE_PUBLIC (R.string.msg_con_delete_public),
+ MSG_CON_DELETE_SECRET (R.string.msg_con_delete_secret),
+ MSG_CON_ERROR_BAD_STATE (R.string.msg_con_error_bad_state),
+ MSG_CON_ERROR_CONCURRENT(R.string.msg_con_error_concurrent),
+ MSG_CON_ERROR_DB (R.string.msg_con_error_db),
+ MSG_CON_ERROR_IO_PUBLIC (R.string.msg_con_error_io_public),
+ MSG_CON_ERROR_IO_SECRET (R.string.msg_con_error_io_secret),
+ MSG_CON_ERROR_PUBLIC (R.string.msg_con_error_public),
+ MSG_CON_ERROR_SECRET (R.string.msg_con_error_secret),
+ MSG_CON_RECOVER (R.plurals.msg_con_recover),
+ MSG_CON_RECOVER_UNKNOWN (R.string.msg_con_recover_unknown),
+ MSG_CON_REIMPORT_PUBLIC (R.plurals.msg_con_reimport_public),
+ MSG_CON_REIMPORT_PUBLIC_SKIP (R.string.msg_con_reimport_public_skip),
+ MSG_CON_REIMPORT_SECRET (R.plurals.msg_con_reimport_secret),
+ MSG_CON_REIMPORT_SECRET_SKIP (R.string.msg_con_reimport_secret_skip),
+ MSG_CON (R.string.msg_con),
+ MSG_CON_SAVE_PUBLIC (R.string.msg_con_save_public),
+ MSG_CON_SAVE_SECRET (R.string.msg_con_save_secret),
+ MSG_CON_SUCCESS (R.string.msg_con_success),
+ MSG_CON_WARN_DELETE_PUBLIC (R.string.msg_con_warn_delete_public),
+ MSG_CON_WARN_DELETE_SECRET (R.string.msg_con_warn_delete_secret),
;
private final int mMsgId;
@@ -406,7 +448,9 @@ public class OperationResultParcel implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mResult);
- dest.writeTypedList(mLog.toList());
+ if (mLog != null) {
+ dest.writeTypedList(mLog.toList());
+ }
}
public static final Creator<OperationResultParcel> CREATOR = new Creator<OperationResultParcel>() {
@@ -432,6 +476,15 @@ public class OperationResultParcel implements Parcelable {
mParcels.add(new OperationResultParcel.LogEntryParcel(level, type, indent, (Object[]) null));
}
+ public boolean containsType(LogType type) {
+ for(LogEntryParcel entry : new IterableIterator<LogEntryParcel>(mParcels.iterator())) {
+ if (entry.mType == type) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public boolean containsWarnings() {
for(LogEntryParcel entry : new IterableIterator<LogEntryParcel>(mParcels.iterator())) {
if (entry.mLevel == LogLevel.WARN || entry.mLevel == LogLevel.ERROR) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java
index 543b83edb..f3d0b9e9b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResults.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
*
* 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
@@ -28,7 +29,10 @@ import com.github.johnpersano.supertoasts.SuperToast;
import com.github.johnpersano.supertoasts.util.OnClickWrapper;
import com.github.johnpersano.supertoasts.util.Style;
+import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing;
+import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.ui.LogDisplayActivity;
import org.sufficientlysecure.keychain.ui.LogDisplayFragment;
@@ -37,7 +41,7 @@ public abstract class OperationResults {
public static class ImportKeyResult extends OperationResultParcel {
- public final int mNewKeys, mUpdatedKeys, mBadKeys;
+ public final int mNewKeys, mUpdatedKeys, mBadKeys, mSecret;
// At least one new key
public static final int RESULT_OK_NEWKEYS = 2;
@@ -49,18 +53,21 @@ public abstract class OperationResults {
public static final int RESULT_WITH_WARNINGS = 16;
// No keys to import...
- public static final int RESULT_FAIL_NOTHING = 32 +1;
+ public static final int RESULT_FAIL_NOTHING = 32 + 1;
public boolean isOkBoth() {
return (mResult & (RESULT_OK_NEWKEYS | RESULT_OK_UPDATED))
== (RESULT_OK_NEWKEYS | RESULT_OK_UPDATED);
}
+
public boolean isOkNew() {
return (mResult & RESULT_OK_NEWKEYS) == RESULT_OK_NEWKEYS;
}
+
public boolean isOkUpdated() {
return (mResult & RESULT_OK_UPDATED) == RESULT_OK_UPDATED;
}
+
public boolean isFailNothing() {
return (mResult & RESULT_FAIL_NOTHING) == RESULT_FAIL_NOTHING;
}
@@ -70,14 +77,16 @@ public abstract class OperationResults {
mNewKeys = source.readInt();
mUpdatedKeys = source.readInt();
mBadKeys = source.readInt();
+ mSecret = source.readInt();
}
public ImportKeyResult(int result, OperationLog log,
- int newKeys, int updatedKeys, int badKeys) {
+ int newKeys, int updatedKeys, int badKeys, int secret) {
super(result, log);
mNewKeys = newKeys;
mUpdatedKeys = updatedKeys;
mBadKeys = badKeys;
+ mSecret = secret;
}
@Override
@@ -86,6 +95,7 @@ public abstract class OperationResults {
dest.writeInt(mNewKeys);
dest.writeInt(mUpdatedKeys);
dest.writeInt(mBadKeys);
+ dest.writeInt(mSecret);
}
public static Creator<ImportKeyResult> CREATOR = new Creator<ImportKeyResult>() {
@@ -124,7 +134,7 @@ public abstract class OperationResults {
if (this.isOkBoth()) {
str = activity.getResources().getQuantityString(
R.plurals.import_keys_added_and_updated_1, mNewKeys, mNewKeys);
- str += " "+ activity.getResources().getQuantityString(
+ str += " " + activity.getResources().getQuantityString(
R.plurals.import_keys_added_and_updated_2, mUpdatedKeys, mUpdatedKeys, withWarnings);
} else if (isOkUpdated()) {
str = activity.getResources().getQuantityString(
@@ -185,13 +195,13 @@ public abstract class OperationResults {
public static class EditKeyResult extends OperationResultParcel {
private transient UncachedKeyRing mRing;
- public final Long mRingMasterKeyId;
+ public final long mRingMasterKeyId;
public EditKeyResult(int result, OperationLog log,
- UncachedKeyRing ring) {
+ UncachedKeyRing ring) {
super(result, log);
mRing = ring;
- mRingMasterKeyId = ring != null ? ring.getMasterKeyId() : null;
+ mRingMasterKeyId = ring != null ? ring.getMasterKeyId() : Constants.key.none;
}
public UncachedKeyRing getRing() {
@@ -224,8 +234,12 @@ public abstract class OperationResults {
public static class SaveKeyringResult extends OperationResultParcel {
- public SaveKeyringResult(int result, OperationLog log) {
+ public final long mRingMasterKeyId;
+
+ public SaveKeyringResult(int result, OperationLog log,
+ CanonicalizedKeyRing ring) {
super(result, log);
+ mRingMasterKeyId = ring != null ? ring.getMasterKeyId() : Constants.key.none;
}
// Some old key was updated
@@ -240,6 +254,34 @@ public abstract class OperationResults {
return (mResult & UPDATED) == UPDATED;
}
+ public SaveKeyringResult(Parcel source) {
+ super(source);
+ mRingMasterKeyId = source.readLong();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeLong(mRingMasterKeyId);
+ }
+
+ public static Creator<SaveKeyringResult> CREATOR = new Creator<SaveKeyringResult>() {
+ public SaveKeyringResult createFromParcel(final Parcel source) {
+ return new SaveKeyringResult(source);
+ }
+
+ public SaveKeyringResult[] newArray(final int size) {
+ return new SaveKeyringResult[size];
+ }
+ };
+ }
+
+ public static class ConsolidateResult extends OperationResultParcel {
+
+ public ConsolidateResult(int result, OperationLog log) {
+ super(result, log);
+ }
+
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
index 8cd9876eb..1b357bd65 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
@@ -78,7 +78,7 @@ public class PassphraseCacheService extends Service {
private static final int NOTIFICATION_ID = 1;
private static final int MSG_PASSPHRASE_CACHE_GET_OKAY = 1;
- private static final int MSG_PASSPHRASE_CACHE_GET_KEY_NO_FOUND = 2;
+ private static final int MSG_PASSPHRASE_CACHE_GET_KEY_NOT_FOUND = 2;
private BroadcastReceiver mIntentReceiver;
@@ -170,7 +170,7 @@ public class PassphraseCacheService extends Service {
switch (returnMessage.what) {
case MSG_PASSPHRASE_CACHE_GET_OKAY:
return returnMessage.getData().getString(EXTRA_PASSPHRASE);
- case MSG_PASSPHRASE_CACHE_GET_KEY_NO_FOUND:
+ case MSG_PASSPHRASE_CACHE_GET_KEY_NOT_FOUND:
throw new KeyNotFoundException();
default:
throw new KeyNotFoundException("should not happen!");
@@ -322,7 +322,7 @@ public class PassphraseCacheService extends Service {
msg.setData(bundle);
} catch (ProviderHelper.NotFoundException e) {
Log.e(Constants.TAG, "PassphraseCacheService: Passphrase for unknown key was requested!");
- msg.what = MSG_PASSPHRASE_CACHE_GET_KEY_NO_FOUND;
+ msg.what = MSG_PASSPHRASE_CACHE_GET_KEY_NOT_FOUND;
}
try {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java
index 490a8e738..996ce6a5a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
*
* 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
@@ -79,14 +80,16 @@ public class SaveKeyringParcel implements Parcelable {
// performance gain for using Parcelable here would probably be negligible,
// use Serializable instead.
public static class SubkeyAdd implements Serializable {
- public int mAlgorithm;
- public int mKeysize;
+ public Algorithm mAlgorithm;
+ public Integer mKeySize;
+ public Curve mCurve;
public int mFlags;
public Long mExpiry;
- public SubkeyAdd(int algorithm, int keysize, int flags, Long expiry) {
+ public SubkeyAdd(Algorithm algorithm, Integer keySize, Curve curve, int flags, Long expiry) {
mAlgorithm = algorithm;
- mKeysize = keysize;
+ mKeySize = keySize;
+ mCurve = curve;
mFlags = flags;
mExpiry = expiry;
}
@@ -94,7 +97,8 @@ public class SaveKeyringParcel implements Parcelable {
@Override
public String toString() {
String out = "mAlgorithm: " + mAlgorithm + ", ";
- out += "mKeysize: " + mKeysize + ", ";
+ out += "mKeySize: " + mKeySize + ", ";
+ out += "mCurve: " + mCurve + ", ";
out += "mFlags: " + mFlags;
out += "mExpiry: " + mExpiry;
@@ -213,4 +217,20 @@ public class SaveKeyringParcel implements Parcelable {
return out;
}
+
+ // All supported algorithms
+ public enum Algorithm {
+ RSA, DSA, ELGAMAL, ECDSA, ECDH
+ }
+
+ // All curves defined in the standard
+ // http://www.bouncycastle.org/wiki/pages/viewpage.action?pageId=362269
+ public enum Curve {
+ NIST_P256, NIST_P384, NIST_P521,
+
+ // these are supported by gpg, but they are not in rfc6637 and not supported by BouncyCastle yet
+ // (adding support would be trivial though -> JcaPGPKeyConverter.java:190)
+ // BRAINPOOL_P256, BRAINPOOL_P384, BRAINPOOL_P512
+ }
+
}