From aa0bd4c9e06857b9e44b8feb284a4a1081f4abff Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Tue, 23 Jun 2015 15:04:10 +0530 Subject: introduced CryptoOperationHelper in ImportKeysActivity --- .../keychain/operations/ImportExportOperation.java | 274 +++++++++++++++++- .../keychain/provider/ProviderHelper.java | 4 +- .../keychain/service/ImportKeyringParcel.java | 74 +++++ .../keychain/service/KeychainNewService.java | 17 +- .../keychain/service/KeychainService.java | 291 ++----------------- .../keychain/service/ServiceProgressHandler.java | 4 +- .../keychain/ui/ImportKeysActivity.java | 121 ++++---- .../keychain/ui/base/CryptoOperationFragment.java | 197 ++----------- .../keychain/ui/base/CryptoOperationHelper.java | 307 +++++++++++++++++++++ 9 files changed, 778 insertions(+), 511 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportKeyringParcel.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java index cdda42dae..c7f0ef423 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java @@ -22,6 +22,7 @@ import android.content.Context; import android.database.Cursor; import android.net.Uri; +import android.os.Parcelable; import org.spongycastle.bcpg.ArmoredOutputStream; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; @@ -33,6 +34,7 @@ import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.ConsolidateResult; import org.sufficientlysecure.keychain.operations.results.ExportResult; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult; @@ -45,6 +47,9 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.ContactSyncAdapterService; +import org.sufficientlysecure.keychain.service.ImportKeyringParcel; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.FileHelper; import org.sufficientlysecure.keychain.util.Log; @@ -59,9 +64,18 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.net.Proxy; import java.util.ArrayList; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; /** An operation class which implements high level import and export @@ -87,7 +101,7 @@ import java.util.concurrent.atomic.AtomicBoolean; * TODO rework uploadKeyRingToServer * */ -public class ImportExportOperation extends BaseOperation { +public class ImportExportOperation extends BaseOperation { public ImportExportOperation(Context context, ProviderHelper providerHelper, Progressable progressable) { super(context, providerHelper, progressable); @@ -127,23 +141,41 @@ public class ImportExportOperation extends BaseOperation { } } - public ImportKeyResult importKeyRings(List entries, String keyServerUri) { + // Overloaded functions for using progressable supplied in constructor during import + public ImportKeyResult serialKeyRingImport(Iterator entries, int num, + String keyServerUri) { + return serialKeyRingImport(entries, num, keyServerUri, mProgressable); + } + + public ImportKeyResult serialKeyRingImport(List entries, + String keyServerUri) { Iterator it = entries.iterator(); int numEntries = entries.size(); - return importKeyRings(it, numEntries, keyServerUri); + return serialKeyRingImport(it, numEntries, keyServerUri, mProgressable); } - public ImportKeyResult importKeyRings(ParcelableFileCache cache, String keyServerUri) { + public ImportKeyResult serialKeyRingImport(List entries, String keyServerUri, + Progressable progressable) { + + Iterator it = entries.iterator(); + int numEntries = entries.size(); + + return serialKeyRingImport(it, numEntries, keyServerUri, progressable); + + } + + public ImportKeyResult serialKeyRingImport(ParcelableFileCache cache, + String keyServerUri) { // get entries from cached file try { IteratorWithSize it = cache.readCache(); int numEntries = it.getSize(); - return importKeyRings(it, numEntries, keyServerUri); + return serialKeyRingImport(it, numEntries, keyServerUri, mProgressable); } catch (IOException e) { // Special treatment here, we need a lot @@ -157,15 +189,18 @@ public class ImportExportOperation extends BaseOperation { } /** - * Since the introduction of multithreaded import, we expect calling functions to handle the key sync i,e - * ContactSyncAdapterService.requestSync() + * Since the introduction of multithreaded import, we expect calling functions to handle the + * key sync i,eContactSyncAdapterService.requestSync() * - * @param entries keys to import - * @param num number of keys to import + * @param entries keys to import + * @param num number of keys to import * @param keyServerUri contains uri of keyserver to import from, if it is an import from cloud + * @param progressable Allows multi-threaded import to supply a progressable that ignores the + * progress of a single key being imported * @return */ - public ImportKeyResult importKeyRings(Iterator entries, int num, String keyServerUri) { + public ImportKeyResult serialKeyRingImport(Iterator entries, int num, + String keyServerUri, Progressable progressable) { updateProgress(R.string.progress_importing, 0, 100); OperationLog log = new OperationLog(); @@ -224,7 +259,8 @@ public class ImportExportOperation extends BaseOperation { byte[] data; // Download by fingerprint, or keyId - whichever is available if (entry.mExpectedFingerprint != null) { - log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER, 2, "0x" + entry.mExpectedFingerprint.substring(24)); + log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER, 2, "0x" + + entry.mExpectedFingerprint.substring(24)); data = keyServer.get("0x" + entry.mExpectedFingerprint).getBytes(); } else { log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER, 2, entry.mKeyIdHex); @@ -302,10 +338,12 @@ public class ImportExportOperation extends BaseOperation { mProviderHelper.clearLog(); if (key.isSecret()) { result = mProviderHelper.saveSecretKeyRing(key, - new ProgressScaler(mProgressable, (int)(position*progSteps), (int)((position+1)*progSteps), 100)); + new ProgressScaler(progressable, (int)(position*progSteps), + (int)((position+1)*progSteps), 100)); } else { result = mProviderHelper.savePublicKeyRing(key, - new ProgressScaler(mProgressable, (int)(position*progSteps), (int)((position+1)*progSteps), 100)); + new ProgressScaler(progressable, (int)(position*progSteps), + (int)((position+1)*progSteps), 100)); } if (!result.success()) { badKeys += 1; @@ -333,7 +371,7 @@ public class ImportExportOperation extends BaseOperation { // Special: consolidate on secret key import (cannot be cancelled!) if (secret > 0) { setPreventCancel(); - ConsolidateResult result = mProviderHelper.consolidateDatabaseStep1(mProgressable); + ConsolidateResult result = mProviderHelper.consolidateDatabaseStep1(progressable); log.add(result, 1); } @@ -590,4 +628,210 @@ public class ImportExportOperation extends BaseOperation { } -} + @Override + public ImportKeyResult execute(ImportKeyringParcel input, CryptoInputParcel cryptoInput) { + + return importKeys(input.mKeyList, input.mKeyserver); + } + + public ImportKeyResult importKeys(ArrayList keyList, String keyServer) { + + ImportKeyResult result; + + if (keyList == null) {// import from file, do serially + ParcelableFileCache cache = new ParcelableFileCache<>(mContext, + "key_import.pcl"); + + result = serialKeyRingImport(cache, keyServer); + } else { + // if there is more than one key with the same fingerprint, we do a serial import to prevent + // https://github.com/open-keychain/open-keychain/issues/1221 + HashSet keyFingerprintSet = new HashSet<>(); + for (int i = 0; i < keyList.size(); i++) { + keyFingerprintSet.add(keyList.get(i).mExpectedFingerprint); + } + if (keyFingerprintSet.size() == keyList.size()) { + // all keys have unique fingerprints + result = multiThreadedKeyImport(keyList.iterator(), keyList.size(), keyServer); + } else { + result = serialKeyRingImport(keyList, keyServer); + } + } + + ContactSyncAdapterService.requestSync(); + return result; + } + + private ImportKeyResult multiThreadedKeyImport(Iterator keyListIterator, + int totKeys, final String keyServer) { + Log.d(Constants.TAG, "Multi-threaded key import starting"); + if (keyListIterator != null) { + KeyImportAccumulator accumulator = new KeyImportAccumulator(totKeys, mProgressable); + + final Progressable ignoreProgressable = new Progressable() { + @Override + public void setProgress(String message, int current, int total) { + + } + + @Override + public void setProgress(int resourceId, int current, int total) { + + } + + @Override + public void setProgress(int current, int total) { + + } + + @Override + public void setPreventCancel() { + + } + }; + + + final int maxThreads = 200; + ExecutorService importExecutor = new ThreadPoolExecutor(0, maxThreads, + 30L, TimeUnit.SECONDS, + new SynchronousQueue()); + + ExecutorCompletionService importCompletionService = + new ExecutorCompletionService(importExecutor); + + while (keyListIterator.hasNext()) { // submit all key rings to be imported + + final ParcelableKeyRing pkRing = keyListIterator.next(); + + Callable importOperationCallable = new Callable() { + + @Override + public ImportKeyResult call() { + + ArrayList list = new ArrayList<>(); + list.add(pkRing); + + return serialKeyRingImport(list, keyServer, ignoreProgressable); + } + }; + + importCompletionService.submit(importOperationCallable); + } + + while (!accumulator.isImportFinished()) { // accumulate the results of each import + try { + accumulator.accumulateKeyImport(importCompletionService.take().get()); + } catch (InterruptedException | ExecutionException e) { + Log.e(Constants.TAG, "A key could not be imported during multi-threaded import", e); + // do nothing? + if (e instanceof ExecutionException) { + // Since serialKeyRingImport does not throw any exceptions, this is what would have happened if + // we were importing the key on this thread + throw new RuntimeException(); + } + } + } + return accumulator.getConsolidatedResult(); + } + return null; // TODO: Decide if we should just crash instead of returning null + } + + /** + * Used to accumulate the results of individual key imports + */ + private class KeyImportAccumulator { + private OperationResult.OperationLog mImportLog = new OperationResult.OperationLog(); + Progressable mProgressable; + private int mTotalKeys; + private int mImportedKeys = 0; + ArrayList mImportedMasterKeyIds = new ArrayList(); + private int mBadKeys = 0; + private int mNewKeys = 0; + private int mUpdatedKeys = 0; + private int mSecret = 0; + private int mResultType = 0; + + /** + * Accumulates keyring imports and updates the progressable whenever a new key is imported. + * Also sets the progress to 0 on instantiation. + * + * @param totalKeys total number of keys to be imported + * @param externalProgressable the external progressable to be updated every time a key is imported + */ + public KeyImportAccumulator(int totalKeys, Progressable externalProgressable) { + mTotalKeys = totalKeys; + mProgressable = externalProgressable; + mProgressable.setProgress(0, totalKeys); + } + + public int getTotalKeys() { + return mTotalKeys; + } + + public int getImportedKeys() { + return mImportedKeys; + } + + public synchronized void accumulateKeyImport(ImportKeyResult result) { + mImportedKeys++; + + mProgressable.setProgress(mImportedKeys, mTotalKeys); + + mImportLog.addAll(result.getLog().toList());//accumulates log + mBadKeys += result.mBadKeys; + mNewKeys += result.mNewKeys; + mUpdatedKeys += result.mUpdatedKeys; + mSecret += result.mSecret; + + long[] masterKeyIds = result.getImportedMasterKeyIds(); + for (long masterKeyId : masterKeyIds) { + mImportedMasterKeyIds.add(masterKeyId); + } + + // if any key import has been cancelled, set result type to cancelled + // resultType is added to in getConsolidatedKayImport to account for remaining factors + mResultType |= result.getResult() & ImportKeyResult.RESULT_CANCELLED; + } + + /** + * returns accumulated result of all imports so far + */ + public ImportKeyResult getConsolidatedResult() { + + // adding required information to mResultType + // special case,no keys requested for import + if (mBadKeys == 0 && mNewKeys == 0 && mUpdatedKeys == 0) { + mResultType = ImportKeyResult.RESULT_FAIL_NOTHING; + } else { + if (mNewKeys > 0) { + mResultType |= ImportKeyResult.RESULT_OK_NEWKEYS; + } + if (mUpdatedKeys > 0) { + mResultType |= ImportKeyResult.RESULT_OK_UPDATED; + } + if (mBadKeys > 0) { + mResultType |= ImportKeyResult.RESULT_WITH_ERRORS; + if (mNewKeys == 0 && mUpdatedKeys == 0) { + mResultType |= ImportKeyResult.RESULT_ERROR; + } + } + if (mImportLog.containsWarnings()) { + mResultType |= ImportKeyResult.RESULT_WARNINGS; + } + } + + long masterKeyIds[] = new long[mImportedMasterKeyIds.size()]; + for (int i = 0; i < masterKeyIds.length; i++) { + masterKeyIds[i] = mImportedMasterKeyIds.get(i); + } + + return new ImportKeyResult(mResultType, mImportLog, mNewKeys, mUpdatedKeys, mBadKeys, + mSecret, masterKeyIds); + } + + public boolean isImportFinished() { + return mTotalKeys == mImportedKeys; + } + } + +} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index bf7014853..5fbc7f6c7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -1250,7 +1250,7 @@ public class ProviderHelper { ImportKeyResult result = new ImportExportOperation(mContext, this, new ProgressFixedScaler(progress, 10, 25, 100, R.string.progress_con_reimport)) - .importKeyRings(itSecrets, numSecrets, null); + .serialKeyRingImport(itSecrets, numSecrets, null); log.add(result, indent); } else { log.add(LogType.MSG_CON_REIMPORT_SECRET_SKIP, indent); @@ -1278,7 +1278,7 @@ public class ProviderHelper { ImportKeyResult result = new ImportExportOperation(mContext, this, new ProgressFixedScaler(progress, 25, 99, 100, R.string.progress_con_reimport)) - .importKeyRings(itPublics, numPublics, null); + .serialKeyRingImport(itPublics, numPublics, null); log.add(result, indent); } else { log.add(LogType.MSG_CON_REIMPORT_PUBLIC_SKIP, indent); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportKeyringParcel.java new file mode 100644 index 000000000..a41dd71cb --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportKeyringParcel.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2015 Dominik Schürmann + * Copyright (C) 2015 Adithya Abraham Philip + * + * 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 . + */ + +package org.sufficientlysecure.keychain.service; + +import android.os.Parcel; +import android.os.Parcelable; +import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; + +import java.util.ArrayList; + +public class ImportKeyringParcel implements Parcelable { + // if null, keys are expected to be read from a cache file in ImportExportOperations + public ArrayList mKeyList; + public String mKeyserver; // must be set if keys are to be imported from a keyserver + + public ImportKeyringParcel (ArrayList keyList, String keyserver) { + mKeyList = keyList; + mKeyserver = keyserver; + } + + protected ImportKeyringParcel(Parcel in) { + if (in.readByte() == 0x01) { + mKeyList = new ArrayList<>(); + in.readList(mKeyList, ParcelableKeyRing.class.getClassLoader()); + } else { + mKeyList = null; + } + mKeyserver = in.readString(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + if (mKeyList == null) { + dest.writeByte((byte) (0x00)); + } else { + dest.writeByte((byte) (0x01)); + dest.writeList(mKeyList); + } + dest.writeString(mKeyserver); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public ImportKeyringParcel createFromParcel(Parcel in) { + return new ImportKeyringParcel(in); + } + + @Override + public ImportKeyringParcel[] newArray(int size) { + return new ImportKeyringParcel[size]; + } + }; +} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java index 9e33a1421..822c2b12e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java @@ -31,10 +31,7 @@ import android.os.Parcelable; import android.os.RemoteException; import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.operations.BaseOperation; -import org.sufficientlysecure.keychain.operations.CertifyOperation; -import org.sufficientlysecure.keychain.operations.EditKeyOperation; -import org.sufficientlysecure.keychain.operations.SignEncryptOperation; +import org.sufficientlysecure.keychain.operations.*; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; @@ -96,13 +93,19 @@ public class KeychainNewService extends Service implements Progressable { // just for brevity KeychainNewService outerThis = KeychainNewService.this; if (inputParcel instanceof SignEncryptParcel) { - op = new SignEncryptOperation(outerThis, new ProviderHelper(outerThis), outerThis, mActionCanceled); + op = new SignEncryptOperation(outerThis, new ProviderHelper(outerThis), + outerThis, mActionCanceled); } else if (inputParcel instanceof PgpDecryptVerifyInputParcel) { op = new PgpDecryptVerify(outerThis, new ProviderHelper(outerThis), outerThis); } else if (inputParcel instanceof SaveKeyringParcel) { - op = new EditKeyOperation(outerThis, new ProviderHelper(outerThis), outerThis, mActionCanceled); + op = new EditKeyOperation(outerThis, new ProviderHelper(outerThis), outerThis, + mActionCanceled); } else if (inputParcel instanceof CertifyAction) { - op = new CertifyOperation(outerThis, new ProviderHelper(outerThis), outerThis, mActionCanceled); + op = new CertifyOperation(outerThis, new ProviderHelper(outerThis), outerThis, + mActionCanceled); + } else if (inputParcel instanceof ImportKeyringParcel){ + op = new ImportExportOperation(outerThis, new ProviderHelper(outerThis), + outerThis, mActionCanceled); } else { return; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java index ba877c2a2..bcd5d837f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java @@ -37,13 +37,10 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; import org.sufficientlysecure.keychain.keyimport.Keyserver; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; -import org.sufficientlysecure.keychain.operations.CertifyOperation; import org.sufficientlysecure.keychain.operations.DeleteOperation; import org.sufficientlysecure.keychain.operations.EditKeyOperation; import org.sufficientlysecure.keychain.operations.ImportExportOperation; import org.sufficientlysecure.keychain.operations.PromoteKeyOperation; -import org.sufficientlysecure.keychain.operations.SignEncryptOperation; -import org.sufficientlysecure.keychain.operations.results.CertifyResult; import org.sufficientlysecure.keychain.operations.results.ConsolidateResult; import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; import org.sufficientlysecure.keychain.operations.results.DeleteResult; @@ -52,30 +49,21 @@ import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult; -import org.sufficientlysecure.keychain.operations.results.SignEncryptResult; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; import org.sufficientlysecure.keychain.pgp.Progressable; -import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus; import org.sufficientlysecure.keychain.util.Log; -import org.sufficientlysecure.keychain.util.ParcelableFileCache; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import de.measite.minidns.Client; @@ -156,11 +144,6 @@ public class KeychainService extends Service implements Progressable { // this attribute can possibly merged with the one above? not sure... private AtomicBoolean mActionCanceled = new AtomicBoolean(false); - - private KeyImportAccumulator mKeyImportAccumulator; - - private KeychainService mKeychainService; - @Override public IBinder onBind(Intent intent) { return null; @@ -171,7 +154,6 @@ public class KeychainService extends Service implements Progressable { */ @Override public int onStartCommand(final Intent intent, int flags, int startId) { - mKeychainService = this; if (ACTION_CANCEL.equals(intent.getAction())) { mActionCanceled.set(true); @@ -208,7 +190,7 @@ public class KeychainService extends Service implements Progressable { Log.logDebugBundle(data, "EXTRA_DATA"); - ProviderHelper providerHelper = new ProviderHelper(mKeychainService); + ProviderHelper providerHelper = new ProviderHelper(KeychainService.this); String action = intent.getAction(); @@ -219,9 +201,9 @@ public class KeychainService extends Service implements Progressable { // Operation ConsolidateResult result; if (data.containsKey(CONSOLIDATE_RECOVERY) && data.getBoolean(CONSOLIDATE_RECOVERY)) { - result = providerHelper.consolidateDatabaseStep2(mKeychainService); + result = providerHelper.consolidateDatabaseStep2(KeychainService.this); } else { - result = providerHelper.consolidateDatabaseStep1(mKeychainService); + result = providerHelper.consolidateDatabaseStep1(KeychainService.this); } // Result @@ -284,8 +266,8 @@ public class KeychainService extends Service implements Progressable { } } - PgpDecryptVerify op = new PgpDecryptVerify(mKeychainService, providerHelper, - mKeychainService); + PgpDecryptVerify op = new PgpDecryptVerify(KeychainService.this, providerHelper, + KeychainService.this); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(messageBytes) .setSignedLiteralData(true) @@ -330,7 +312,7 @@ public class KeychainService extends Service implements Progressable { boolean isSecret = data.getBoolean(DELETE_IS_SECRET); // Operation - DeleteOperation op = new DeleteOperation(mKeychainService, providerHelper, mKeychainService); + DeleteOperation op = new DeleteOperation(KeychainService.this, providerHelper, KeychainService.this); DeleteResult result = op.execute(masterKeyIds, isSecret); // Result @@ -345,8 +327,8 @@ public class KeychainService extends Service implements Progressable { CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT); // Operation - EditKeyOperation op = new EditKeyOperation(mKeychainService, providerHelper, - mKeychainService, mActionCanceled); + EditKeyOperation op = new EditKeyOperation(KeychainService.this, providerHelper, + KeychainService.this, mActionCanceled); OperationResult result = op.execute(saveParcel, cryptoInput); // Result @@ -363,7 +345,7 @@ public class KeychainService extends Service implements Progressable { // Operation PromoteKeyOperation op = new PromoteKeyOperation( - mKeychainService, providerHelper, mKeychainService, + KeychainService.this, providerHelper, KeychainService.this, mActionCanceled); PromoteKeyResult result = op.execute(keyRingId, cardAid, subKeyIds); @@ -384,7 +366,7 @@ public class KeychainService extends Service implements Progressable { // Operation ImportExportOperation importExportOperation = new ImportExportOperation( - mKeychainService, providerHelper, mKeychainService); + KeychainService.this, providerHelper, KeychainService.this); ExportResult result; if (outputFile != null) { result = importExportOperation.exportToFile(masterKeyIds, exportSecret, outputFile); @@ -403,23 +385,16 @@ public class KeychainService extends Service implements Progressable { String keyServer = data.getString(IMPORT_KEY_SERVER); ArrayList keyList = data.getParcelableArrayList(IMPORT_KEY_LIST); - // either keyList or cache must be null, no guarantees otherwise - if (keyList == null) {// import from file, do serially - serialKeyImport(null, keyServer, providerHelper); - } else { - // if there is more than one key with the same fingerprint, we do a serial import to prevent - // https://github.com/open-keychain/open-keychain/issues/1221 - HashSet keyFingerprintSet = new HashSet<>(); - for (int i = 0; i < keyList.size(); i++) { - keyFingerprintSet.add(keyList.get(i).mExpectedFingerprint); - } - if (keyFingerprintSet.size() == keyList.size()) { - // all keys have unique fingerprints - multiThreadedKeyImport(keyList.iterator(), keyList.size(), keyServer); - } else { - serialKeyImport(keyList, keyServer, providerHelper); - } - } + ImportExportOperation importExportOperation = new ImportExportOperation( + KeychainService.this, + providerHelper, KeychainService.this, mActionCanceled); + + ImportKeyringParcel inputParcel = new ImportKeyringParcel(keyList, keyServer); + CryptoInputParcel cryptoInputParcel = new CryptoInputParcel(); + + ImportKeyResult result = importExportOperation.execute(inputParcel, cryptoInputParcel); + + sendMessageToHandler(MessageStatus.OKAY, result); break; } @@ -434,8 +409,8 @@ public class KeychainService extends Service implements Progressable { HkpKeyserver server = new HkpKeyserver(keyServer); CanonicalizedPublicKeyRing keyring = providerHelper.getCanonicalizedPublicKeyRing(dataUri); - ImportExportOperation importExportOperation = new ImportExportOperation(mKeychainService, - providerHelper, mKeychainService); + ImportExportOperation importExportOperation = new ImportExportOperation( + KeychainService.this, providerHelper, KeychainService.this); try { importExportOperation.uploadKeyRingToServer(server, keyring); @@ -450,16 +425,13 @@ public class KeychainService extends Service implements Progressable { break; } } - if (!intent.getAction().equals(ACTION_IMPORT_KEYRING)) { - // import keyring handles stopping service on its own - stopSelf(); - } + stopSelf(); } }; Thread actionThread = new Thread(actionRunnable); actionThread.start(); - + return START_NOT_STICKY; } @@ -484,7 +456,7 @@ public class KeychainService extends Service implements Progressable { // contextualize the exception, if necessary String message; if (e instanceof PgpGeneralMsgIdException) { - e = ((PgpGeneralMsgIdException) e).getContextualized(mKeychainService); + e = ((PgpGeneralMsgIdException) e).getContextualized(KeychainService.this); message = e.getMessage(); } else { message = e.getMessage(); @@ -563,215 +535,4 @@ public class KeychainService extends Service implements Progressable { public void setPreventCancel() { sendMessageToHandler(MessageStatus.PREVENT_CANCEL); } - - public void serialKeyImport(ArrayList keyList, final String keyServer, - ProviderHelper providerHelper) { - Log.d(Constants.TAG, "serial key import starting"); - ParcelableFileCache cache = - new ParcelableFileCache<>(mKeychainService, "key_import.pcl"); - - // Operation - ImportExportOperation importExportOperation = new ImportExportOperation( - mKeychainService, providerHelper, mKeychainService, - mActionCanceled); - // Either list or cache must be null, no guarantees otherwise. - ImportKeyResult result = keyList != null - ? importExportOperation.importKeyRings(keyList, keyServer) - : importExportOperation.importKeyRings(cache, keyServer); - - ContactSyncAdapterService.requestSync(); - // Result - sendMessageToHandler(MessageStatus.OKAY, result); - - stopSelf(); - } - - public void multiThreadedKeyImport(Iterator keyListIterator, int totKeys, final String - keyServer) { - Log.d(Constants.TAG, "Multi-threaded key import starting"); - if (keyListIterator != null) { - mKeyImportAccumulator = new KeyImportAccumulator(totKeys, mKeychainService); - setProgress(0, totKeys); - - final int maxThreads = 200; - ExecutorService importExecutor = new ThreadPoolExecutor(0, maxThreads, - 30L, TimeUnit.SECONDS, - new SynchronousQueue()); - - while (keyListIterator.hasNext()) { - - final ParcelableKeyRing pkRing = keyListIterator.next(); - - Runnable importOperationRunnable = new Runnable() { - - @Override - public void run() { - ImportKeyResult result = null; - try { - ImportExportOperation importExportOperation = new ImportExportOperation( - mKeychainService, - new ProviderHelper(mKeychainService), - mKeyImportAccumulator.getImportProgressable(), - mActionCanceled); - - ArrayList list = new ArrayList<>(); - list.add(pkRing); - - result = importExportOperation.importKeyRings(list, - keyServer); - } finally { - // in the off-chance that importKeyRings does something to crash the - // thread before it can call singleKeyRingImportCompleted, our imported - // key count will go wrong. This will cause the service to never die, - // and the progress dialog to stay displayed. The finally block was - // originally meant to ensure singleKeyRingImportCompleted was called, - // and checks for null were to be introduced, but in such a scenario, - // knowing an uncaught error exists in importKeyRings is more important. - - // if a null gets passed, something wrong is happening. We want a crash. - - mKeyImportAccumulator.singleKeyRingImportCompleted(result); - } - } - }; - - importExecutor.execute(importOperationRunnable); - } - } - } - - /** - * Used to accumulate the results of individual key imports - */ - private class KeyImportAccumulator { - private OperationResult.OperationLog mImportLog = new OperationResult.OperationLog(); - private int mTotalKeys; - private int mImportedKeys = 0; - private Progressable mInternalProgressable; - ArrayList mImportedMasterKeyIds = new ArrayList(); - private int mBadKeys = 0; - private int mNewKeys = 0; - private int mUpdatedKeys = 0; - private int mSecret = 0; - private int mResultType = 0; - - /** - * meant to be used with a service due to stopSelf() in singleKeyRingImportCompleted. Remove this if - * generalising. - * - * @param totalKeys total number of keys to be imported - * @param externalProgressable the external progressable to be updated every time a key is imported - */ - public KeyImportAccumulator(int totalKeys, Progressable externalProgressable) { - mTotalKeys = totalKeys; - // ignore updates from ImportExportOperation for now - mInternalProgressable = new Progressable() { - @Override - public void setProgress(String message, int current, int total) { - - } - - @Override - public void setProgress(int resourceId, int current, int total) { - - } - - @Override - public void setProgress(int current, int total) { - - } - - @Override - public void setPreventCancel() { - - } - }; - } - - private synchronized void singleKeyRingImportCompleted(ImportKeyResult result) { - // increase imported key count and accumulate log and bad, new etc. key counts from result - mKeyImportAccumulator.accumulateKeyImport(result); - - setProgress(mKeyImportAccumulator.getImportedKeys(), mKeyImportAccumulator.getTotalKeys()); - - if (mKeyImportAccumulator.isImportFinished()) { - ContactSyncAdapterService.requestSync(); - - sendMessageToHandler(ServiceProgressHandler.MessageStatus.OKAY, - mKeyImportAccumulator.getConsolidatedImportKeyResult()); - - stopSelf();//we're done here - } - } - - public Progressable getImportProgressable() { - return mInternalProgressable; - } - - public int getTotalKeys() { - return mTotalKeys; - } - - public int getImportedKeys() { - return mImportedKeys; - } - - public synchronized void accumulateKeyImport(ImportKeyResult result) { - mImportedKeys++; - mImportLog.addAll(result.getLog().toList());//accumulates log - mBadKeys += result.mBadKeys; - mNewKeys += result.mNewKeys; - mUpdatedKeys += result.mUpdatedKeys; - mSecret += result.mSecret; - - long[] masterKeyIds = result.getImportedMasterKeyIds(); - for (long masterKeyId : masterKeyIds) { - mImportedMasterKeyIds.add(masterKeyId); - } - - // if any key import has been cancelled, set result type to cancelled - // resultType is added to in getConsolidatedKayImport to account for remaining factors - mResultType |= result.getResult() & ImportKeyResult.RESULT_CANCELLED; - } - - /** - * returns accumulated result of all imports so far - */ - public ImportKeyResult getConsolidatedImportKeyResult() { - - // adding required information to mResultType - // special case,no keys requested for import - if (mBadKeys == 0 && mNewKeys == 0 && mUpdatedKeys == 0) { - mResultType = ImportKeyResult.RESULT_FAIL_NOTHING; - } else { - if (mNewKeys > 0) { - mResultType |= ImportKeyResult.RESULT_OK_NEWKEYS; - } - if (mUpdatedKeys > 0) { - mResultType |= ImportKeyResult.RESULT_OK_UPDATED; - } - if (mBadKeys > 0) { - mResultType |= ImportKeyResult.RESULT_WITH_ERRORS; - if (mNewKeys == 0 && mUpdatedKeys == 0) { - mResultType |= ImportKeyResult.RESULT_ERROR; - } - } - if (mImportLog.containsWarnings()) { - mResultType |= ImportKeyResult.RESULT_WARNINGS; - } - } - - long masterKeyIds[] = new long[mImportedMasterKeyIds.size()]; - for (int i = 0; i < masterKeyIds.length; i++) { - masterKeyIds[i] = mImportedMasterKeyIds.get(i); - } - - return new ImportKeyResult(mResultType, mImportLog, mNewKeys, mUpdatedKeys, mBadKeys, - mSecret, masterKeyIds); - } - - public boolean isImportFinished() { - return mTotalKeys == mImportedKeys; - } - } -} +} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ServiceProgressHandler.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ServiceProgressHandler.java index 989b0c4bd..d294e5057 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ServiceProgressHandler.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ServiceProgressHandler.java @@ -64,6 +64,8 @@ public class ServiceProgressHandler extends Handler { public static final String KEYBASE_PRESENCE_URL = "keybase_presence_url"; public static final String KEYBASE_PRESENCE_LABEL = "keybase_presence_label"; + public static final String TAG_PROGRESS_DIALOG = "progressDialog"; + FragmentActivity mActivity; public ServiceProgressHandler(FragmentActivity activity) { @@ -88,7 +90,7 @@ public class ServiceProgressHandler extends Handler { Handler handler = new Handler(); handler.post(new Runnable() { public void run() { - frag.show(manager, "progressDialog"); + frag.show(manager, TAG_PROGRESS_DIALOG); } }); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 07ab88b02..b05cc6f50 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -17,12 +17,10 @@ package org.sufficientlysecure.keychain.ui; -import android.app.ProgressDialog; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.os.Message; -import android.os.Messenger; import android.support.v4.app.Fragment; import android.view.View; import android.view.View.OnClickListener; @@ -35,9 +33,10 @@ import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; -import org.sufficientlysecure.keychain.service.KeychainService; +import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.ui.base.BaseNfcActivity; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.Log; @@ -47,7 +46,8 @@ import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize import java.io.IOException; import java.util.ArrayList; -public class ImportKeysActivity extends BaseNfcActivity { +public class ImportKeysActivity extends BaseNfcActivity + implements CryptoOperationHelper.Callback { public static final String ACTION_IMPORT_KEY = OpenKeychainIntents.IMPORT_KEY; public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER = OpenKeychainIntents.IMPORT_KEY_FROM_KEYSERVER; @@ -82,6 +82,12 @@ public class ImportKeysActivity extends BaseNfcActivity { private Fragment mTopFragment; private View mImportButton; + // for CryptoOperationHelper.Callback + private String mKeyserver; + private ArrayList mKeyList; + + private CryptoOperationHelper mOperationHelper; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -388,23 +394,9 @@ public class ImportKeysActivity extends BaseNfcActivity { return; } - ServiceProgressHandler serviceHandler = new ServiceProgressHandler(this) { - @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - ImportKeysActivity.this.handleMessage(message); - } - }; - - // Send all information needed to service to import key in other thread - Intent intent = new Intent(this, KeychainService.class); - - intent.setAction(KeychainService.ACTION_IMPORT_KEYRING); - - // fill values for this action - Bundle data = new Bundle(); + mOperationHelper = new CryptoOperationHelper( + this, this, R.string.progress_importing + ); ImportKeysListFragment.LoaderState ls = mListFragment.getLoaderState(); if (ls instanceof ImportKeysListFragment.BytesLoaderState) { @@ -423,30 +415,18 @@ public class ImportKeysActivity extends BaseNfcActivity { new ParcelableFileCache<>(this, "key_import.pcl"); cache.writeCache(selectedEntries); - intent.putExtra(KeychainService.EXTRA_DATA, data); - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(serviceHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); + mKeyList = null; + mKeyserver = null; + mOperationHelper.cryptoOperation(); - // show progress dialog - serviceHandler.showProgressDialog( - getString(R.string.progress_importing), - ProgressDialog.STYLE_HORIZONTAL, - true - ); - - // start service with intent - startService(intent); } catch (IOException e) { Log.e(Constants.TAG, "Problem writing cache file", e); Notify.create(this, "Problem writing cache file!", Notify.Style.ERROR) .show((ViewGroup) findViewById(R.id.import_snackbar)); } } else if (ls instanceof ImportKeysListFragment.CloudLoaderState) { - ImportKeysListFragment.CloudLoaderState sls = (ImportKeysListFragment.CloudLoaderState) ls; - - data.putString(KeychainService.IMPORT_KEY_SERVER, sls.mCloudPrefs.keyserver); + ImportKeysListFragment.CloudLoaderState sls = + (ImportKeysListFragment.CloudLoaderState) ls; // get selected key entries ArrayList keys = new ArrayList<>(); @@ -459,22 +439,11 @@ public class ImportKeysActivity extends BaseNfcActivity { ); } } - data.putParcelableArrayList(KeychainService.IMPORT_KEY_LIST, keys); - - intent.putExtra(KeychainService.EXTRA_DATA, data); - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(serviceHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); + mKeyList = keys; + mKeyserver = sls.mCloudPrefs.keyserver; + mOperationHelper.cryptoOperation(); - // show progress dialog - serviceHandler.showProgressDialog( - getString(R.string.progress_importing), - ProgressDialog.STYLE_HORIZONTAL, true - ); - - // start service with intent - startService(intent); } } @@ -485,4 +454,52 @@ public class ImportKeysActivity extends BaseNfcActivity { // either way, finish afterwards finish(); } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (mOperationHelper == null || + !mOperationHelper.handleActivityResult(requestCode, resultCode, data)) { + super.onActivityResult(requestCode, resultCode, data); + } + } + + public void handleResult (ImportKeyResult result) { + if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT.equals(getIntent().getAction()) + || ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN.equals(getIntent().getAction())) { + Intent intent = new Intent(); + intent.putExtra(ImportKeyResult.EXTRA_RESULT, result); + ImportKeysActivity.this.setResult(RESULT_OK, intent); + ImportKeysActivity.this.finish(); + return; + } + if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_TO_SERVICE.equals(getIntent().getAction())) { + ImportKeysActivity.this.setResult(RESULT_OK, mPendingIntentData); + ImportKeysActivity.this.finish(); + return; + } + + result.createNotify(ImportKeysActivity.this) + .show((ViewGroup) findViewById(R.id.import_snackbar)); + } + // methods from CryptoOperationHelper.Callback + + @Override + public ImportKeyringParcel createOperationInput() { + return new ImportKeyringParcel(mKeyList, mKeyserver); + } + + @Override + public void onCryptoOperationSuccess(ImportKeyResult result) { + handleResult(result); + } + + @Override + public void onCryptoOperationCancelled() { + // do nothing + } + + @Override + public void onCryptoOperationError(ImportKeyResult result) { + handleResult(result); + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java index 764602735..c00ebd915 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java @@ -18,185 +18,66 @@ package org.sufficientlysecure.keychain.ui.base; -import android.app.Activity; -import android.app.ProgressDialog; import android.content.Intent; -import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; import android.os.Parcelable; import android.support.v4.app.Fragment; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.operations.results.InputPendingResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; -import org.sufficientlysecure.keychain.service.KeychainNewService; -import org.sufficientlysecure.keychain.service.KeychainService; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; -import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; -import org.sufficientlysecure.keychain.ui.NfcOperationActivity; -import org.sufficientlysecure.keychain.ui.PassphraseDialogActivity; -import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; /** * All fragments executing crypto operations need to extend this class. */ -public abstract class CryptoOperationFragment +public abstract class CryptoOperationFragment extends Fragment { - public static final int REQUEST_CODE_PASSPHRASE = 0x00008001; - public static final int REQUEST_CODE_NFC = 0x00008002; + private CryptoOperationHelper mOperationHelper; - private void initiateInputActivity(RequiredInputParcel requiredInput) { + public CryptoOperationFragment() { + // this is implemented here instead of by the fragment so that the corresponding methods in + // CryptoOperationFragment may continue using the "protected" modifier. + CryptoOperationHelper.Callback callback = new CryptoOperationHelper.Callback() { - switch (requiredInput.mType) { - case NFC_KEYTOCARD: - case NFC_DECRYPT: - case NFC_SIGN: { - Intent intent = new Intent(getActivity(), NfcOperationActivity.class); - intent.putExtra(NfcOperationActivity.EXTRA_REQUIRED_INPUT, requiredInput); - startActivityForResult(intent, REQUEST_CODE_NFC); - return; + @Override + public T createOperationInput() { + return CryptoOperationFragment.this.createOperationInput(); } - case PASSPHRASE: - case PASSPHRASE_SYMMETRIC: { - Intent intent = new Intent(getActivity(), PassphraseDialogActivity.class); - intent.putExtra(PassphraseDialogActivity.EXTRA_REQUIRED_INPUT, requiredInput); - startActivityForResult(intent, REQUEST_CODE_PASSPHRASE); - return; + @Override + public void onCryptoOperationSuccess(S result) { + CryptoOperationFragment.this.onCryptoOperationSuccess(result); } - } - - throw new RuntimeException("Unhandled pending result!"); - } - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (resultCode == Activity.RESULT_CANCELED) { - onCryptoOperationCancelled(); - return; - } - - switch (requestCode) { - case REQUEST_CODE_PASSPHRASE: { - if (resultCode == Activity.RESULT_OK && data != null) { - CryptoInputParcel cryptoInput = - data.getParcelableExtra(PassphraseDialogActivity.RESULT_CRYPTO_INPUT); - cryptoOperation(cryptoInput); - return; - } - break; + @Override + public void onCryptoOperationCancelled() { + CryptoOperationFragment.this.onCryptoOperationCancelled(); } - case REQUEST_CODE_NFC: { - if (resultCode == Activity.RESULT_OK && data != null) { - CryptoInputParcel cryptoInput = - data.getParcelableExtra(NfcOperationActivity.RESULT_DATA); - cryptoOperation(cryptoInput); - return; - } - break; + @Override + public void onCryptoOperationError(S result) { + CryptoOperationFragment.this.onCryptoOperationError(result); } + }; - default: { - super.onActivityResult(requestCode, resultCode, data); - } - } + mOperationHelper = new CryptoOperationHelper<>(this, callback); } - protected void dismissProgress() { - - ProgressDialogFragment progressDialogFragment = - (ProgressDialogFragment) getFragmentManager().findFragmentByTag("progressDialog"); - - if (progressDialogFragment == null) { - return; - } - - progressDialogFragment.dismissAllowingStateLoss(); - + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + mOperationHelper.handleActivityResult(requestCode, resultCode, data); } protected abstract T createOperationInput(); - protected void cryptoOperation(CryptoInputParcel cryptoInput) { - cryptoOperation(cryptoInput, true); - } - protected void cryptoOperation() { cryptoOperation(new CryptoInputParcel()); } - protected void cryptoOperation(CryptoInputParcel cryptoInput, boolean showProgress) { - - T operationInput = createOperationInput(); - if (operationInput == null) { - return; - } - - // Send all information needed to service to edit key in other thread - Intent intent = new Intent(getActivity(), KeychainNewService.class); - - intent.putExtra(KeychainNewService.EXTRA_OPERATION_INPUT, operationInput); - intent.putExtra(KeychainNewService.EXTRA_CRYPTO_INPUT, cryptoInput); - - ServiceProgressHandler saveHandler = new ServiceProgressHandler(getActivity()) { - @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - - // get returned data bundle - Bundle returnData = message.getData(); - if (returnData == null) { - return; - } - - final OperationResult result = - returnData.getParcelable(OperationResult.EXTRA_RESULT); - - onHandleResult(result); - } - } - - @Override - protected void onSetProgress(String msg, int progress, int max) { - // allow handling of progress in fragment, or delegate upwards - if ( ! onCryptoSetProgress(msg, progress, max)) { - super.onSetProgress(msg, progress, max); - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); - - if (showProgress) { - saveHandler.showProgressDialog( - getString(R.string.progress_building_key), - ProgressDialog.STYLE_HORIZONTAL, false); - } - - getActivity().startService(intent); - - } - - protected void onCryptoOperationResult(S result) { - if (result.success()) { - onCryptoOperationSuccess(result); - } else { - onCryptoOperationError(result); - } + protected void cryptoOperation(CryptoInputParcel cryptoInput) { + mOperationHelper.cryptoOperation(cryptoInput); } - abstract protected void onCryptoOperationSuccess(S result); - protected void onCryptoOperationError(S result) { result.createNotify(getActivity()).show(); } @@ -204,31 +85,9 @@ public abstract class CryptoOperationFragment + * Copyright (C) 2015 Vincent Breitmoser + * Copyright (C) 2015 Adithya Abraham Philip + * + * 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 . + */ + +package org.sufficientlysecure.keychain.ui.base; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Intent; +import android.os.Bundle; +import android.os.Message; +import android.os.Messenger; +import android.os.Parcelable; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; + +import android.support.v4.app.FragmentManager; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.operations.results.InputPendingResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult; +import org.sufficientlysecure.keychain.service.KeychainNewService; +import org.sufficientlysecure.keychain.service.KeychainService; +import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; +import org.sufficientlysecure.keychain.ui.NfcOperationActivity; +import org.sufficientlysecure.keychain.ui.PassphraseDialogActivity; +import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; +import org.sufficientlysecure.keychain.util.Log; + +/** + * Designed to be integrated into activities or fragments used for CryptoOperations. + * Encapsulates the execution of a crypto operation and handling of input pending cases.s + * + * @param The type of input parcel sent to the operation + * @param The type of result returned by the operation + */ +public class CryptoOperationHelper { + + public interface Callback { + T createOperationInput(); + void onCryptoOperationSuccess(S result); + void onCryptoOperationCancelled(); + void onCryptoOperationError(S result); + } + + public static final int REQUEST_CODE_PASSPHRASE = 0x00008001; + public static final int REQUEST_CODE_NFC = 0x00008002; + + // keeps track of request code used to start an activity from this CryptoOperationHelper. + // this is necessary when multiple CryptoOperationHelpers are used in the same fragment/activity + // otherwise all CryptoOperationHandlers may respond to the same onActivityResult + private int mRequestedCode = -1; + + private int mProgressMessageString; + + private FragmentActivity mActivity; + private Fragment mFragment; + private Callback mCallback; + + private boolean mUseFragment; // short hand for mActivity == null + + /** + * If OperationHelper is being integrated into an activity + * + * @param activity + */ + public CryptoOperationHelper(FragmentActivity activity, Callback callback, int progressMessageString) { + mActivity = activity; + mUseFragment = false; + mCallback = callback; + mProgressMessageString = progressMessageString; + } + + /** + * if OperationHelper is being integrated into a fragment + * + * @param fragment + */ + public CryptoOperationHelper(Fragment fragment, Callback callback, int progressMessageString) { + mFragment = fragment; + mUseFragment = true; + mProgressMessageString = progressMessageString; + mCallback = callback; + } + + /** + * if OperationHelper is being integrated into a fragment with default message for the progress dialog + * + * @param fragment + */ + public CryptoOperationHelper(Fragment fragment, Callback callback) { + mFragment = fragment; + mUseFragment = true; + mProgressMessageString = R.string.progress_building_key; + mCallback = callback; + } + + private void initiateInputActivity(RequiredInputParcel requiredInput) { + + Activity activity = mUseFragment ? mFragment.getActivity() : mActivity; + + Log.d("PHILIP", "Initating input " + requiredInput.mType); + switch (requiredInput.mType) { + case NFC_KEYTOCARD: + case NFC_DECRYPT: + case NFC_SIGN: { + Intent intent = new Intent(activity, NfcOperationActivity.class); + intent.putExtra(NfcOperationActivity.EXTRA_REQUIRED_INPUT, requiredInput); + mRequestedCode = REQUEST_CODE_NFC; + if (mUseFragment) { + mFragment.startActivityForResult(intent, mRequestedCode); + } else { + mActivity.startActivityForResult(intent, mRequestedCode); + } + return; + } + + case PASSPHRASE: + case PASSPHRASE_SYMMETRIC: { + Intent intent = new Intent(activity, PassphraseDialogActivity.class); + intent.putExtra(PassphraseDialogActivity.EXTRA_REQUIRED_INPUT, requiredInput); + mRequestedCode = REQUEST_CODE_PASSPHRASE; + if (mUseFragment) { + mFragment.startActivityForResult(intent, mRequestedCode); + } else { + mActivity.startActivityForResult(intent, mRequestedCode); + } + return; + } + } + + throw new RuntimeException("Unhandled pending result!"); + } + + /** + * Attempts the result of an activity started by this helper. Returns true if requestCode is recognized, + * false otherwise. + * + * @param requestCode + * @param resultCode + * @param data + * @return true if requestCode was recognized, false otherwise + */ + public boolean handleActivityResult(int requestCode, int resultCode, Intent data) { + Log.d("PHILIP", "received activity result in OperationHelper"); + + if (mRequestedCode != requestCode) { + // this wasn't meant for us to handle + return false; + } else { + mRequestedCode = -1; + } + if (resultCode == Activity.RESULT_CANCELED) { + mCallback.onCryptoOperationCancelled(); + return true; + } + + switch (requestCode) { + case REQUEST_CODE_PASSPHRASE: { + if (resultCode == Activity.RESULT_OK && data != null) { + CryptoInputParcel cryptoInput = + data.getParcelableExtra(PassphraseDialogActivity.RESULT_CRYPTO_INPUT); + cryptoOperation(cryptoInput); + return true; + } + break; + } + + case REQUEST_CODE_NFC: { + if (resultCode == Activity.RESULT_OK && data != null) { + CryptoInputParcel cryptoInput = + data.getParcelableExtra(NfcOperationActivity.RESULT_DATA); + cryptoOperation(cryptoInput); + return true; + } + break; + } + + default: { + return false; + } + } + return true; + } + + protected void dismissProgress() { + FragmentManager fragmentManager = + mUseFragment ? mFragment.getFragmentManager() : + mActivity.getSupportFragmentManager(); + + ProgressDialogFragment progressDialogFragment = + (ProgressDialogFragment) fragmentManager.findFragmentByTag( + ServiceProgressHandler.TAG_PROGRESS_DIALOG); + + if (progressDialogFragment == null) { + return; + } + + progressDialogFragment.dismissAllowingStateLoss(); + + } + + public void cryptoOperation(CryptoInputParcel cryptoInput) { + + FragmentActivity activity = mUseFragment ? mFragment.getActivity() : mActivity; + + T operationInput = mCallback.createOperationInput(); + if (operationInput == null) { + return; + } + + // Send all information needed to service to edit key in other thread + Intent intent = new Intent(activity, KeychainNewService.class); + + intent.putExtra(KeychainNewService.EXTRA_OPERATION_INPUT, operationInput); + intent.putExtra(KeychainNewService.EXTRA_CRYPTO_INPUT, cryptoInput); + + ServiceProgressHandler saveHandler = new ServiceProgressHandler(activity) { + @Override + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + + if (message.arg1 == MessageStatus.OKAY.ordinal()) { + + // get returned data bundle + Bundle returnData = message.getData(); + if (returnData == null) { + return; + } + + final OperationResult result = + returnData.getParcelable(OperationResult.EXTRA_RESULT); + + onHandleResult(result); + } + } + }; + + saveHandler.showProgressDialog( + activity.getString(mProgressMessageString), + ProgressDialog.STYLE_HORIZONTAL, false); + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); + + activity.startService(intent); + + } + + public void cryptoOperation() { + cryptoOperation(new CryptoInputParcel()); + } + + protected void onCryptoOperationResult(S result) { + Log.d("PHILIP", "cryptoResult " + result.success()); + if (result.success()) { + mCallback.onCryptoOperationSuccess(result); + } else { + mCallback.onCryptoOperationError(result); + } + } + + public void onHandleResult(OperationResult result) { + Log.d("PHILIP", "Handling result in OperationHelper"); + + if (result instanceof InputPendingResult) { + Log.d("PHILIP", "is pending result"); + InputPendingResult pendingResult = (InputPendingResult) result; + if (pendingResult.isPending()) { + + Log.d("PHILIP", "Is pending"); + RequiredInputParcel requiredInput = pendingResult.getRequiredInputParcel(); + initiateInputActivity(requiredInput); + return; + } + } + + dismissProgress(); + + try { + // noinspection unchecked, because type erasure :( + onCryptoOperationResult((S) result); + } catch (ClassCastException e) { + throw new AssertionError("bad return class (" + + result.getClass().getSimpleName() + "), this is a programming error!"); + } + + } +} \ No newline at end of file -- cgit v1.2.3 From e9639bd822c149ede53aa68524b0fef72894f409 Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Tue, 23 Jun 2015 18:42:00 +0530 Subject: introduced OpHelper for import in DecryptFragment --- .../keychain/ui/DecryptFragment.java | 84 +++++++++++----------- 1 file changed, 44 insertions(+), 40 deletions(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java index c8ae867b2..ae5c86451 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java @@ -17,6 +17,7 @@ package org.sufficientlysecure.keychain.ui; +import java.lang.reflect.Array; import java.util.ArrayList; import android.app.Activity; @@ -27,6 +28,7 @@ import android.os.Bundle; import android.os.Message; import android.os.Messenger; import android.support.v4.app.Fragment; +import android.os.Parcelable; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; @@ -51,8 +53,10 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State; import org.sufficientlysecure.keychain.ui.util.Notify; @@ -78,6 +82,8 @@ public abstract class DecryptFragment extends Fragment implements LoaderManager. private DecryptVerifyResult mDecryptVerifyResult; private ViewAnimator mOverlayAnimator; + private CryptoOperationHelper mImportOpHelper; + @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); @@ -135,43 +141,15 @@ public abstract class DecryptFragment extends Fragment implements LoaderManager. private void lookupUnknownKey(long unknownKeyId) { - // Message is received after importing is done in KeychainService - ServiceProgressHandler serviceHandler = new ServiceProgressHandler(getActivity()) { - @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - // get returned data bundle - Bundle returnData = message.getData(); - - if (returnData == null) { - return; - } - - final ImportKeyResult result = - returnData.getParcelable(OperationResult.EXTRA_RESULT); - - Activity activity = getActivity(); - if (result != null && activity != null) { - result.createNotify(activity).show(); - } - - getLoaderManager().restartLoader(LOADER_ID_UNIFIED, null, DecryptFragment.this); - } - } - }; - - // fill values for this action - Bundle data = new Bundle(); + final ArrayList keyList; + final String keyserver; // search config { Preferences prefs = Preferences.getPreferences(getActivity()); Preferences.CloudSearchPrefs cloudPrefs = new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver()); - data.putString(KeychainService.IMPORT_KEY_SERVER, cloudPrefs.keyserver); + keyserver = cloudPrefs.keyserver; } { @@ -180,19 +158,38 @@ public abstract class DecryptFragment extends Fragment implements LoaderManager. ArrayList selectedEntries = new ArrayList<>(); selectedEntries.add(keyEntry); - data.putParcelableArrayList(KeychainService.IMPORT_KEY_LIST, selectedEntries); + keyList = selectedEntries; } - // Send all information needed to service to query keys in other thread - Intent intent = new Intent(getActivity(), KeychainService.class); - intent.setAction(KeychainService.ACTION_IMPORT_KEYRING); - intent.putExtra(KeychainService.EXTRA_DATA, data); + CryptoOperationHelper.Callback callback + = new CryptoOperationHelper.Callback() { - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(serviceHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); + @Override + public ImportKeyringParcel createOperationInput() { + return new ImportKeyringParcel(keyList, keyserver); + } - getActivity().startService(intent); + @Override + public void onCryptoOperationSuccess(ImportKeyResult result) { + result.createNotify(getActivity()).show(); + + getLoaderManager().restartLoader(LOADER_ID_UNIFIED, null, DecryptFragment.this); + } + + @Override + public void onCryptoOperationCancelled() { + // do nothing + } + + @Override + public void onCryptoOperationError(ImportKeyResult result) { + result.createNotify(getActivity()).show(); + } + }; + + mImportOpHelper = new CryptoOperationHelper<>(this, callback, R.string.progress_importing); + + mImportOpHelper.cryptoOperation(); } private void showKey(long keyId) { @@ -457,4 +454,11 @@ public abstract class DecryptFragment extends Fragment implements LoaderManager. protected abstract void onVerifyLoaded(boolean hideErrorOverlay); + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (mImportOpHelper != null) { + mImportOpHelper.handleActivityResult(requestCode, resultCode, data); + } + super.onActivityResult(requestCode, resultCode, data); + } } -- cgit v1.2.3 From 3f073e1cf4b398cf4691a2e98b61de7be48d0aab Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Tue, 23 Jun 2015 19:51:19 +0530 Subject: migrated import to KeychainNewService --- .../ui/CreateKeyYubiKeyImportFragment.java | 61 +++++++---- .../keychain/ui/ImportKeysProxyActivity.java | 111 ++++++++----------- .../keychain/ui/KeyListFragment.java | 86 +++++++-------- .../keychain/ui/SafeSlingerActivity.java | 121 +++++++++------------ .../keychain/ui/ViewKeyActivity.java | 87 +++++++-------- 5 files changed, 218 insertions(+), 248 deletions(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java index 2ab8c5967..298efcc39 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java @@ -40,15 +40,19 @@ import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.NfcListenerFragment; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.Preferences; -public class CreateKeyYubiKeyImportFragment extends Fragment implements NfcListenerFragment { +public class CreateKeyYubiKeyImportFragment + extends CryptoOperationFragment + implements NfcListenerFragment { private static final String ARG_FINGERPRINT = "fingerprint"; public static final String ARG_AID = "aid"; @@ -64,6 +68,10 @@ public class CreateKeyYubiKeyImportFragment extends Fragment implements NfcListe private TextView vSerNo; private TextView vUserId; + // for CryptoOperationFragment key import + private String mKeyserver; + private ArrayList mKeyList; + public static Fragment createInstance(byte[] scannedFingerprints, byte[] nfcAid, String userId) { CreateKeyYubiKeyImportFragment frag = new CreateKeyYubiKeyImportFragment(); @@ -214,38 +222,20 @@ public class CreateKeyYubiKeyImportFragment extends Fragment implements NfcListe } }; - // Send all information needed to service to decrypt in other thread - Intent intent = new Intent(getActivity(), KeychainService.class); - - // fill values for this action - Bundle data = new Bundle(); - - intent.setAction(KeychainService.ACTION_IMPORT_KEYRING); - ArrayList keyList = new ArrayList<>(); keyList.add(new ParcelableKeyRing(mNfcFingerprint, null, null)); - data.putParcelableArrayList(KeychainService.IMPORT_KEY_LIST, keyList); + mKeyList = keyList; { Preferences prefs = Preferences.getPreferences(getActivity()); Preferences.CloudSearchPrefs cloudPrefs = new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver()); - data.putString(KeychainService.IMPORT_KEY_SERVER, cloudPrefs.keyserver); + mKeyserver = cloudPrefs.keyserver; } - intent.putExtra(KeychainService.EXTRA_DATA, data); + // TODO: PHILIP make the progress dialog show importing - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); - - saveHandler.showProgressDialog( - getString(R.string.progress_importing), - ProgressDialog.STYLE_HORIZONTAL, false - ); - - // start service with intent - getActivity().startService(intent); + cryptoOperation(); } @@ -264,4 +254,29 @@ public class CreateKeyYubiKeyImportFragment extends Fragment implements NfcListe refreshSearch(); } + + @Override + protected ImportKeyringParcel createOperationInput() { + return new ImportKeyringParcel(mKeyList, mKeyserver); + } + + @Override + protected void onCryptoOperationSuccess(ImportKeyResult result) { + long[] masterKeyIds = result.getImportedMasterKeyIds(); + if (masterKeyIds.length == 0) { + super.onCryptoOperationError(result); + return; + } + + Intent intent = new Intent(getActivity(), ViewKeyActivity.class); + // use the imported masterKeyId, not the one from the yubikey, because + // that one might* just have been a subkey of the imported key + intent.setData(KeyRings.buildGenericKeyRingUri(masterKeyIds[0])); + intent.putExtra(ViewKeyActivity.EXTRA_DISPLAY_RESULT, result); + intent.putExtra(ViewKeyActivity.EXTRA_NFC_AID, mNfcAid); + intent.putExtra(ViewKeyActivity.EXTRA_NFC_USER_ID, mNfcUserId); + intent.putExtra(ViewKeyActivity.EXTRA_NFC_FINGERPRINTS, mNfcFingerprints); + startActivity(intent); + getActivity().finish(); + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java index 9f3beff43..0a7bd726a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java @@ -18,7 +18,6 @@ package org.sufficientlysecure.keychain.ui; import android.annotation.TargetApi; -import android.app.ProgressDialog; import android.content.Intent; import android.content.pm.ActivityInfo; import android.net.Uri; @@ -26,8 +25,6 @@ import android.nfc.NdefMessage; import android.nfc.NfcAdapter; import android.os.Build; import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; import android.os.Parcelable; import android.support.v4.app.FragmentActivity; import android.widget.Toast; @@ -43,8 +40,8 @@ import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.SingletonResult; -import org.sufficientlysecure.keychain.service.KeychainService; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.service.ImportKeyringParcel; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.util.IntentIntegratorSupportV4; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Preferences; @@ -55,7 +52,8 @@ import java.util.Locale; /** * Proxy activity (just a transparent content view) to scan QR Codes using the Barcode Scanner app */ -public class ImportKeysProxyActivity extends FragmentActivity { +public class ImportKeysProxyActivity extends FragmentActivity + implements CryptoOperationHelper.Callback { public static final String ACTION_QR_CODE_API = OpenKeychainIntents.IMPORT_KEY_FROM_QR_CODE; // implies activity returns scanned fingerprint as extra and does not import @@ -64,6 +62,11 @@ public class ImportKeysProxyActivity extends FragmentActivity { public static final String EXTRA_FINGERPRINT = "fingerprint"; + // for CryptoOperationHelper + private String mKeyserver; + private ArrayList mKeyList; + private CryptoOperationHelper mImportOpHelper; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -106,6 +109,10 @@ public class ImportKeysProxyActivity extends FragmentActivity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (mImportOpHelper != null) { + mImportOpHelper.cryptoOperation(); + } + if (requestCode == IntentIntegratorSupportV4.REQUEST_CODE) { IntentResult scanResult = IntentIntegratorSupportV4.parseActivityResult(requestCode, resultCode, data); @@ -205,75 +212,51 @@ public class ImportKeysProxyActivity extends FragmentActivity { private void startImportService(ArrayList keyRings) { - // Message is received after importing is done in KeychainService - ServiceProgressHandler serviceHandler = new ServiceProgressHandler(this) { - @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - // get returned data bundle - Bundle returnData = message.getData(); - if (returnData == null) { - finish(); - return; - } - final ImportKeyResult result = - returnData.getParcelable(OperationResult.EXTRA_RESULT); - if (result == null) { - Log.e(Constants.TAG, "result == null"); - finish(); - return; - } - - if (!result.success()) { - // only return if no success... - Intent data = new Intent(); - data.putExtras(returnData); - returnResult(data); - return; - } - - Intent certifyIntent = new Intent(ImportKeysProxyActivity.this, - CertifyKeyActivity.class); - certifyIntent.putExtra(CertifyKeyActivity.EXTRA_RESULT, result); - certifyIntent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, - result.getImportedMasterKeyIds()); - startActivityForResult(certifyIntent, 0); - } - } - }; - - // fill values for this action - Bundle data = new Bundle(); - // search config { Preferences prefs = Preferences.getPreferences(this); Preferences.CloudSearchPrefs cloudPrefs = new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver()); - data.putString(KeychainService.IMPORT_KEY_SERVER, cloudPrefs.keyserver); + mKeyserver = cloudPrefs.keyserver; } - data.putParcelableArrayList(KeychainService.IMPORT_KEY_LIST, keyRings); + mKeyList = keyRings; + + mImportOpHelper = new CryptoOperationHelper<>(this, this, R.string.progress_importing); - // Send all information needed to service to query keys in other thread - Intent intent = new Intent(this, KeychainService.class); - intent.setAction(KeychainService.ACTION_IMPORT_KEYRING); - intent.putExtra(KeychainService.EXTRA_DATA, data); + mImportOpHelper.cryptoOperation(); + } - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(serviceHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); - // show progress dialog - serviceHandler.showProgressDialog( - getString(R.string.progress_importing), - ProgressDialog.STYLE_HORIZONTAL, true); + // CryptoOperationHelper.Callback methods - // start service with intent - startService(intent); + @Override + public ImportKeyringParcel createOperationInput() { + return new ImportKeyringParcel(mKeyList, mKeyserver); + } + + @Override + public void onCryptoOperationSuccess(ImportKeyResult result) { + Intent certifyIntent = new Intent(this, CertifyKeyActivity.class); + certifyIntent.putExtra(CertifyKeyActivity.EXTRA_RESULT, result); + certifyIntent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, + result.getImportedMasterKeyIds()); + startActivityForResult(certifyIntent, 0); + } + + @Override + public void onCryptoOperationCancelled() { + + } + + @Override + public void onCryptoOperationError(ImportKeyResult result) { + Bundle returnData = new Bundle(); + returnData.putParcelable(OperationResult.EXTRA_RESULT, result); + Intent data = new Intent(); + data.putExtras(returnData); + returnResult(data); + return; } /** diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 780558b27..b52640d86 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -64,9 +64,11 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.service.PassphraseCacheService; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.adapter.KeyAdapter; @@ -90,7 +92,8 @@ import se.emilsjolander.stickylistheaders.StickyListHeadersListView; */ public class KeyListFragment extends LoaderFragment implements SearchView.OnQueryTextListener, AdapterView.OnItemClickListener, - LoaderManager.LoaderCallbacks, FabContainer { + LoaderManager.LoaderCallbacks, FabContainer, + CryptoOperationHelper.Callback { static final int REQUEST_REPEAT_PASSPHRASE = 1; static final int REQUEST_ACTION = 2; @@ -107,6 +110,11 @@ public class KeyListFragment extends LoaderFragment private FloatingActionsMenu mFab; + // for CryptoOperationHelper import + private ArrayList mKeyList; + private String mKeyserver; + private CryptoOperationHelper mImportOpHelper; + // This ids for multiple key export. private ArrayList mIdsForRepeatAskPassphrase; // This index for remembering the number of master key. @@ -580,64 +588,22 @@ public class KeyListFragment extends LoaderFragment ParcelableKeyRing keyEntry = new ParcelableKeyRing(fingerprint, null, null); keyList.add(keyEntry); } + mKeyList = keyList; } finally { cursor.close(); } - ServiceProgressHandler serviceHandler = new ServiceProgressHandler(getActivity()) { - @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - // get returned data bundle - Bundle returnData = message.getData(); - if (returnData == null) { - return; - } - final ImportKeyResult result = - returnData.getParcelable(OperationResult.EXTRA_RESULT); - if (result == null) { - Log.e(Constants.TAG, "result == null"); - return; - } - - result.createNotify(getActivity()).show(); - } - } - }; - - // Send all information needed to service to query keys in other thread - Intent intent = new Intent(getActivity(), KeychainService.class); - intent.setAction(KeychainService.ACTION_IMPORT_KEYRING); - - // fill values for this action - Bundle data = new Bundle(); - // search config { Preferences prefs = Preferences.getPreferences(getActivity()); Preferences.CloudSearchPrefs cloudPrefs = new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver()); - data.putString(KeychainService.IMPORT_KEY_SERVER, cloudPrefs.keyserver); + mKeyserver = cloudPrefs.keyserver; } - data.putParcelableArrayList(KeychainService.IMPORT_KEY_LIST, keyList); - - intent.putExtra(KeychainService.EXTRA_DATA, data); - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(serviceHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); - - // show progress dialog - serviceHandler.showProgressDialog( - getString(R.string.progress_updating), - ProgressDialog.STYLE_HORIZONTAL, true); - - // start service with intent - getActivity().startService(intent); + mImportOpHelper = new CryptoOperationHelper<>(this, + this, R.string.progress_updating); + mImportOpHelper.cryptoOperation(); } private void consolidate() { @@ -724,6 +690,9 @@ public class KeyListFragment extends LoaderFragment @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (mImportOpHelper != null) { + mImportOpHelper.handleActivityResult(requestCode, resultCode, data); + } if (requestCode == REQUEST_REPEAT_PASSPHRASE) { if (resultCode != Activity.RESULT_OK) { return; @@ -769,6 +738,27 @@ public class KeyListFragment extends LoaderFragment anim.start(); } + // CryptoOperationHelper.Callback methods + @Override + public ImportKeyringParcel createOperationInput() { + return new ImportKeyringParcel(mKeyList, mKeyserver); + } + + @Override + public void onCryptoOperationSuccess(ImportKeyResult result) { + result.createNotify(getActivity()).show(); + } + + @Override + public void onCryptoOperationCancelled() { + + } + + @Override + public void onCryptoOperationError(ImportKeyResult result) { + result.createNotify(getActivity()).show(); + } + public class KeyListAdapter extends KeyAdapter implements StickyListHeadersAdapter { private HashMap mSelection = new HashMap<>(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java index 7408135ae..97c44aabf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java @@ -38,9 +38,11 @@ import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.ui.base.BaseActivity; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ParcelableFileCache; @@ -52,7 +54,8 @@ import edu.cmu.cylab.starslinger.exchange.ExchangeActivity; import edu.cmu.cylab.starslinger.exchange.ExchangeConfig; @TargetApi(Build.VERSION_CODES.HONEYCOMB) -public class SafeSlingerActivity extends BaseActivity { +public class SafeSlingerActivity extends BaseActivity + implements CryptoOperationHelper.Callback { private static final int REQUEST_CODE_SAFE_SLINGER = 211; @@ -61,6 +64,12 @@ public class SafeSlingerActivity extends BaseActivity { private long mMasterKeyId; private int mSelectedNumber = 2; + // for CryptoOperationHelper + private ArrayList mKeyList; + private String mKeyserver; + private CryptoOperationHelper mOperationHelper; + + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -116,65 +125,17 @@ public class SafeSlingerActivity extends BaseActivity { @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (mOperationHelper != null) { + mOperationHelper.handleActivityResult(requestCode, resultCode, data); + } + if (requestCode == REQUEST_CODE_SAFE_SLINGER) { if (resultCode == ExchangeActivity.RESULT_EXCHANGE_CANCELED) { return; } - final FragmentActivity activity = SafeSlingerActivity.this; - - // Message is received after importing is done in KeychainService - ServiceProgressHandler saveHandler = new ServiceProgressHandler(activity) { - @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - // get returned data bundle - Bundle returnData = message.getData(); - if (returnData == null) { - return; - } - final ImportKeyResult result = - returnData.getParcelable(OperationResult.EXTRA_RESULT); - if (result == null) { - Log.e(Constants.TAG, "result == null"); - return; - } - - if (!result.success()) { -// result.createNotify(activity).show(); - // only return if no success... - Intent data = new Intent(); - data.putExtras(returnData); - setResult(RESULT_OK, data); - finish(); - return; - } - -// if (mExchangeMasterKeyId == null) { -// return; -// } - - Intent certifyIntent = new Intent(activity, CertifyKeyActivity.class); - certifyIntent.putExtra(CertifyKeyActivity.EXTRA_RESULT, result); - certifyIntent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, result.getImportedMasterKeyIds()); - certifyIntent.putExtra(CertifyKeyActivity.EXTRA_CERTIFY_KEY_ID, mMasterKeyId); - startActivityForResult(certifyIntent, 0); - -// mExchangeMasterKeyId = null; - } - } - }; - Log.d(Constants.TAG, "importKeys started"); - // Send all information needed to service to import key in other thread - Intent intent = new Intent(activity, KeychainService.class); - - intent.setAction(KeychainService.ACTION_IMPORT_KEYRING); - // instead of giving the entries by Intent extra, cache them into a // file to prevent Java Binder problems on heavy imports // read FileImportCache for more info. @@ -185,28 +146,18 @@ public class SafeSlingerActivity extends BaseActivity { // We parcel this iteratively into a file - anything we can // display here, we should be able to import. ParcelableFileCache cache = - new ParcelableFileCache<>(activity, "key_import.pcl"); + new ParcelableFileCache<>(this, "key_import.pcl"); cache.writeCache(it.size(), it.iterator()); - // fill values for this action - Bundle bundle = new Bundle(); - intent.putExtra(KeychainService.EXTRA_DATA, bundle); - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); + mOperationHelper = + new CryptoOperationHelper(this, this, R.string.progress_importing); - // show progress dialog - saveHandler.showProgressDialog( - getString(R.string.progress_importing), - ProgressDialog.STYLE_HORIZONTAL, true - ); - - // start service with intent - activity.startService(intent); + mKeyList = null; + mKeyserver = null; + mOperationHelper.cryptoOperation(); } catch (IOException e) { Log.e(Constants.TAG, "Problem writing cache file", e); - Notify.create(activity, "Problem writing cache file!", Notify.Style.ERROR).show(); + Notify.create(this, "Problem writing cache file!", Notify.Style.ERROR).show(); } } else { // give everything else down to KeyListActivity! @@ -233,4 +184,34 @@ public class SafeSlingerActivity extends BaseActivity { return list; } + // CryptoOperationHelper.Callback functions + + @Override + public ImportKeyringParcel createOperationInput() { + return new ImportKeyringParcel(mKeyList, mKeyserver); + } + + @Override + public void onCryptoOperationSuccess(ImportKeyResult result) { + Intent certifyIntent = new Intent(this, CertifyKeyActivity.class); + certifyIntent.putExtra(CertifyKeyActivity.EXTRA_RESULT, result); + certifyIntent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, result.getImportedMasterKeyIds()); + certifyIntent.putExtra(CertifyKeyActivity.EXTRA_CERTIFY_KEY_ID, mMasterKeyId); + startActivityForResult(certifyIntent, 0); + } + + @Override + public void onCryptoOperationCancelled() { + + } + + @Override + public void onCryptoOperationError(ImportKeyResult result) { + Bundle returnData = new Bundle(); + returnData.putParcelable(OperationResult.EXTRA_RESULT, result); + Intent data = new Intent(); + data.putExtras(returnData); + setResult(RESULT_OK, data); + finish(); + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 5f6a32e5a..62ee89207 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -65,11 +65,13 @@ import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus; import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.ui.base.BaseNfcActivity; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import org.sufficientlysecure.keychain.ui.util.FormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; @@ -85,11 +87,13 @@ import org.sufficientlysecure.keychain.util.NfcHelper; import org.sufficientlysecure.keychain.util.Preferences; import java.io.IOException; +import java.lang.reflect.Array; import java.util.ArrayList; import java.util.HashMap; public class ViewKeyActivity extends BaseNfcActivity implements - LoaderManager.LoaderCallbacks { + LoaderManager.LoaderCallbacks, + CryptoOperationHelper.Callback { public static final String EXTRA_NFC_USER_ID = "nfc_user_id"; public static final String EXTRA_NFC_AID = "nfc_aid"; @@ -105,6 +109,11 @@ public class ViewKeyActivity extends BaseNfcActivity implements protected Uri mDataUri; + // For CryptoOperationHelper.Callback + private String mKeyserver; + private ArrayList mKeyList; + private CryptoOperationHelper mOperationHelper; + private TextView mName; private TextView mStatusText; private ImageView mStatusImage; @@ -396,7 +405,7 @@ public class ViewKeyActivity extends BaseNfcActivity implements private void certifyImmediate() { Intent intent = new Intent(this, CertifyKeyActivity.class); - intent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[] {mMasterKeyId}); + intent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{mMasterKeyId}); startCertifyIntent(intent); } @@ -486,6 +495,10 @@ public class ViewKeyActivity extends BaseNfcActivity implements @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (mOperationHelper != null) { + mOperationHelper.handleActivityResult(requestCode, resultCode, data); + } + if (requestCode == REQUEST_QR_FINGERPRINT && resultCode == Activity.RESULT_OK) { // If there is an EXTRA_RESULT, that's an error. Just show it. @@ -651,56 +664,20 @@ public class ViewKeyActivity extends BaseNfcActivity implements ParcelableKeyRing keyEntry = new ParcelableKeyRing(fingerprint, null, null); ArrayList entries = new ArrayList<>(); entries.add(keyEntry); - - // Message is received after importing is done in KeychainService - ServiceProgressHandler serviceHandler = new ServiceProgressHandler(this) { - @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - // get returned data bundle - Bundle returnData = message.getData(); - - mIsRefreshing = false; - - if (returnData == null) { - finish(); - return; - } - final ImportKeyResult result = - returnData.getParcelable(OperationResult.EXTRA_RESULT); - result.createNotify(ViewKeyActivity.this).show(); - } - } - }; - - // fill values for this action - Bundle data = new Bundle(); + mKeyList = entries; // search config { Preferences prefs = Preferences.getPreferences(this); Preferences.CloudSearchPrefs cloudPrefs = new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver()); - data.putString(KeychainService.IMPORT_KEY_SERVER, cloudPrefs.keyserver); + mKeyserver = cloudPrefs.keyserver; } - data.putParcelableArrayList(KeychainService.IMPORT_KEY_LIST, entries); - - // Send all information needed to service to query keys in other thread - Intent intent = new Intent(this, KeychainService.class); - intent.setAction(KeychainService.ACTION_IMPORT_KEYRING); - intent.putExtra(KeychainService.EXTRA_DATA, data); - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(serviceHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); - - // start service with intent - startService(intent); + mOperationHelper = new CryptoOperationHelper<>( + this, this, R.string.progress_importing); + mOperationHelper.cryptoOperation(); } private void editKey(Uri dataUri) { @@ -986,4 +963,28 @@ public class ViewKeyActivity extends BaseNfcActivity implements public void onLoaderReset(Loader loader) { } + + // CryptoOperationHelper.Callback functions + + @Override + public ImportKeyringParcel createOperationInput() { + return new ImportKeyringParcel(mKeyList, mKeyserver); + } + + @Override + public void onCryptoOperationSuccess(ImportKeyResult result) { + mIsRefreshing = false; + result.createNotify(this).show(); + } + + @Override + public void onCryptoOperationCancelled() { + mIsRefreshing = false; + } + + @Override + public void onCryptoOperationError(ImportKeyResult result) { + mIsRefreshing = false; + result.createNotify(this).show(); + } } \ No newline at end of file -- cgit v1.2.3 From 93dc11edcf3e4310fcf0c0dbdd295992d4ebd55d Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Tue, 23 Jun 2015 20:15:38 +0530 Subject: made EmailKeyHelper work with CryptoOperationHelper --- .../keychain/util/EmailKeyHelper.java | 53 ++++++++++++---------- 1 file changed, 29 insertions(+), 24 deletions(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/EmailKeyHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/EmailKeyHelper.java index bbc08a2aa..835a97dd8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/EmailKeyHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/EmailKeyHelper.java @@ -26,8 +26,13 @@ import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; import org.sufficientlysecure.keychain.keyimport.Keyserver; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; +import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; +import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.service.KeychainService; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; +import java.lang.reflect.Array; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -35,24 +40,35 @@ import java.util.Locale; import java.util.Set; public class EmailKeyHelper { + // to import keys, simply use CryptoOperationHelper with this callback + public abstract class ImportContactKeysCallback + implements CryptoOperationHelper.Callback { - public static void importContacts(Context context, Messenger messenger) { - importAll(context, messenger, ContactHelper.getContactMails(context)); - } + private ArrayList mKeyList; + private String mKeyserver; - public static void importAll(Context context, Messenger messenger, List mails) { - // Collect all candidates as ImportKeysListEntry (set for deduplication) - Set entries = new HashSet<>(); - for (String mail : mails) { - entries.addAll(getEmailKeys(context, mail)); + public ImportContactKeysCallback(Context context, String keyserver) { + this(context, ContactHelper.getContactMails(context), keyserver); } - // Put them in a list and import - ArrayList keys = new ArrayList<>(entries.size()); - for (ImportKeysListEntry entry : entries) { - keys.add(new ParcelableKeyRing(entry.getFingerprintHex(), entry.getKeyIdHex(), null)); + public ImportContactKeysCallback(Context context, List mails, String keyserver) { + Set entries = new HashSet<>(); + for (String mail : mails) { + entries.addAll(getEmailKeys(context, mail)); + } + + // Put them in a list and import + ArrayList keys = new ArrayList<>(entries.size()); + for (ImportKeysListEntry entry : entries) { + keys.add(new ParcelableKeyRing(entry.getFingerprintHex(), entry.getKeyIdHex(), null)); + } + mKeyList = keys; + mKeyserver = keyserver; + } + @Override + public ImportKeyringParcel createOperationInput() { + return new ImportKeyringParcel(mKeyList, mKeyserver); } - importKeys(context, messenger, keys); } public static Set getEmailKeys(Context context, String mail) { @@ -78,17 +94,6 @@ public class EmailKeyHelper { return keys; } - private static void importKeys(Context context, Messenger messenger, ArrayList keys) { - Intent importIntent = new Intent(context, KeychainService.class); - importIntent.setAction(KeychainService.ACTION_IMPORT_KEYRING); - Bundle importData = new Bundle(); - importData.putParcelableArrayList(KeychainService.IMPORT_KEY_LIST, keys); - importIntent.putExtra(KeychainService.EXTRA_DATA, importData); - importIntent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); - - context.startService(importIntent); - } - public static List getEmailKeys(String mail, Keyserver keyServer) { Set keys = new HashSet<>(); try { -- cgit v1.2.3 From 6008353df8f8d17795fadb5a34fc86ad5a8f2de9 Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Tue, 23 Jun 2015 20:20:13 +0530 Subject: allow progress message to be set later --- .../ui/CreateKeyYubiKeyImportFragment.java | 45 ++-------------------- .../keychain/ui/base/CryptoOperationFragment.java | 5 +++ .../keychain/ui/base/CryptoOperationHelper.java | 14 ++++--- 3 files changed, 17 insertions(+), 47 deletions(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java index 298efcc39..ff0ebf7d3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java @@ -183,45 +183,6 @@ public class CreateKeyYubiKeyImportFragment public void importKey() { - // Message is received after decrypting is done in KeychainService - ServiceProgressHandler saveHandler = new ServiceProgressHandler(getActivity()) { - @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - // get returned data bundle - Bundle returnData = message.getData(); - - ImportKeyResult result = - returnData.getParcelable(DecryptVerifyResult.EXTRA_RESULT); - - long[] masterKeyIds = result.getImportedMasterKeyIds(); - - // TODO handle masterKeyIds.length != 1...? sorta outlandish scenario - - if (!result.success() || masterKeyIds.length == 0) { - result.createNotify(getActivity()).show(); - return; - } - - Intent intent = new Intent(getActivity(), ViewKeyActivity.class); - // use the imported masterKeyId, not the one from the yubikey, because - // that one might* just have been a subkey of the imported key - intent.setData(KeyRings.buildGenericKeyRingUri(masterKeyIds[0])); - intent.putExtra(ViewKeyActivity.EXTRA_DISPLAY_RESULT, result); - intent.putExtra(ViewKeyActivity.EXTRA_NFC_AID, mNfcAid); - intent.putExtra(ViewKeyActivity.EXTRA_NFC_USER_ID, mNfcUserId); - intent.putExtra(ViewKeyActivity.EXTRA_NFC_FINGERPRINTS, mNfcFingerprints); - startActivity(intent); - getActivity().finish(); - - } - - } - }; - ArrayList keyList = new ArrayList<>(); keyList.add(new ParcelableKeyRing(mNfcFingerprint, null, null)); mKeyList = keyList; @@ -233,9 +194,9 @@ public class CreateKeyYubiKeyImportFragment mKeyserver = cloudPrefs.keyserver; } - // TODO: PHILIP make the progress dialog show importing + super.setProgressMessageResource(R.string.progress_importing); - cryptoOperation(); + super.cryptoOperation(); } @@ -267,7 +228,7 @@ public class CreateKeyYubiKeyImportFragment super.onCryptoOperationError(result); return; } - + Intent intent = new Intent(getActivity(), ViewKeyActivity.class); // use the imported masterKeyId, not the one from the yubikey, because // that one might* just have been a subkey of the imported key diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java index c00ebd915..53ab33dc5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java @@ -63,6 +63,11 @@ public abstract class CryptoOperationFragment(this, callback); } + public void setProgressMessageResource(int id) { + mOperationHelper.setProgressMessageResource(id); + } + + @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { mOperationHelper.handleActivityResult(requestCode, resultCode, data); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java index ffbda330e..43106820f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java @@ -67,7 +67,7 @@ public class CryptoOperationHelper callback, int progressMessageString) { mFragment = fragment; mUseFragment = true; - mProgressMessageString = progressMessageString; + mProgressMessageResource = progressMessageString; mCallback = callback; } @@ -107,10 +107,14 @@ public class CryptoOperationHelper callback) { mFragment = fragment; mUseFragment = true; - mProgressMessageString = R.string.progress_building_key; + mProgressMessageResource = R.string.progress_building_key; mCallback = callback; } + public void setProgressMessageResource(int id) { + mProgressMessageResource = id; + } + private void initiateInputActivity(RequiredInputParcel requiredInput) { Activity activity = mUseFragment ? mFragment.getActivity() : mActivity; @@ -254,7 +258,7 @@ public class CryptoOperationHelper Date: Tue, 23 Jun 2015 23:03:59 +0530 Subject: added export and upload to KeychainNewService --- .../keychain/operations/ImportExportOperation.java | 46 +++++++++-- .../keychain/service/ExportKeyringParcel.java | 80 +++++++++++++++++++ .../keychain/service/ImportExportParcel.java | 19 +++++ .../keychain/service/ImportKeyringParcel.java | 2 +- .../keychain/service/KeychainNewService.java | 3 +- .../keychain/service/KeychainService.java | 89 ---------------------- .../keychain/ui/CreateKeyFinalFragment.java | 86 +++++++++++---------- .../keychain/ui/UploadKeyActivity.java | 88 +++++++++++---------- .../keychain/util/ExportHelper.java | 75 ++++++++---------- 9 files changed, 263 insertions(+), 225 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ExportKeyringParcel.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportExportParcel.java (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java index c7f0ef423..3b9390866 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java @@ -47,9 +47,10 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.ContactSyncAdapterService; +import org.sufficientlysecure.keychain.service.ExportKeyringParcel; +import org.sufficientlysecure.keychain.service.ImportExportParcel; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; -import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.FileHelper; import org.sufficientlysecure.keychain.util.Log; @@ -101,7 +102,7 @@ import java.util.concurrent.atomic.AtomicBoolean; * TODO rework uploadKeyRingToServer * */ -public class ImportExportOperation extends BaseOperation { +public class ImportExportOperation extends BaseOperation { public ImportExportOperation(Context context, ProviderHelper providerHelper, Progressable progressable) { super(context, providerHelper, progressable); @@ -629,9 +630,44 @@ public class ImportExportOperation extends BaseOperation { } @Override - public ImportKeyResult execute(ImportKeyringParcel input, CryptoInputParcel cryptoInput) { - - return importKeys(input.mKeyList, input.mKeyserver); + public OperationResult execute(ImportExportParcel input, CryptoInputParcel cryptoInput) { + if (input instanceof ExportKeyringParcel) { + ExportKeyringParcel exportInput = (ExportKeyringParcel) input; + switch (exportInput.mExportType) { + case UPLOAD_KEYSERVER: { + HkpKeyserver hkpKeyserver = new HkpKeyserver(exportInput.mKeyserver); + try { + CanonicalizedPublicKeyRing keyring + = mProviderHelper.getCanonicalizedPublicKeyRing( + exportInput.mCanonicalizedPublicKeyringUri); + uploadKeyRingToServer(hkpKeyserver, keyring); + // TODO: replace with proper log + return new ExportResult(ExportResult.RESULT_OK, new OperationLog()); + } catch (Exception e) { + // TODO: Implement better exception handling, replace with log + } + break; + } + case EXPORT_FILE: { + return exportToFile(exportInput.mMasterKeyIds, exportInput.mExportSecret, + exportInput.mOutputFile); + } + case EXPORT_URI: { + return exportToUri(exportInput.mMasterKeyIds, exportInput.mExportSecret, + exportInput.mOutputUri); + } + default: { + return null; + } + } + } + else if (input instanceof ImportKeyringParcel) { + ImportKeyringParcel importInput = (ImportKeyringParcel) input; + return importKeys(importInput.mKeyList, importInput.mKeyserver); + } else { + throw new RuntimeException("Invalid input parcel at ImportExportOperation"); + } + return null; } public ImportKeyResult importKeys(ArrayList keyList, String keyServer) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ExportKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ExportKeyringParcel.java new file mode 100644 index 000000000..8e9fa9466 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ExportKeyringParcel.java @@ -0,0 +1,80 @@ +package org.sufficientlysecure.keychain.service; + +import android.net.Uri; +import android.os.Parcel; +import android.os.Parcelable; + +public class ExportKeyringParcel extends ImportExportParcel implements Parcelable { + public String mKeyserver; + public Uri mCanonicalizedPublicKeyringUri; + + public boolean mExportSecret; + public long mMasterKeyIds[]; + public String mOutputFile; + public Uri mOutputUri; + public ExportType mExportType; + + public enum ExportType { + UPLOAD_KEYSERVER, + EXPORT_FILE, + EXPORT_URI + } + + public ExportKeyringParcel(String keyserver, Uri keyringUri) { + mExportType = ExportType.UPLOAD_KEYSERVER; + mKeyserver = keyserver; + mCanonicalizedPublicKeyringUri = keyringUri; + } + + public ExportKeyringParcel(long[] masterKeyIds, boolean exportSecret, String outputFile) { + mExportType = ExportType.EXPORT_FILE; + mMasterKeyIds = masterKeyIds; + mExportSecret = exportSecret; + mOutputFile = outputFile; + } + + public ExportKeyringParcel(long[] masterKeyIds, boolean exportSecret, Uri outputUri) { + mExportType = ExportType.EXPORT_URI; + mMasterKeyIds = masterKeyIds; + mExportSecret = exportSecret; + mOutputUri = outputUri; + } + + protected ExportKeyringParcel(Parcel in) { + mKeyserver = in.readString(); + mCanonicalizedPublicKeyringUri = (Uri) in.readValue(Uri.class.getClassLoader()); + mExportSecret = in.readByte() != 0x00; + mOutputFile = in.readString(); + mOutputUri = (Uri) in.readValue(Uri.class.getClassLoader()); + mExportType = (ExportType) in.readValue(ExportType.class.getClassLoader()); + mMasterKeyIds = in.createLongArray(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(mKeyserver); + dest.writeValue(mCanonicalizedPublicKeyringUri); + dest.writeByte((byte) (mExportSecret ? 0x01 : 0x00)); + dest.writeString(mOutputFile); + dest.writeValue(mOutputUri); + dest.writeValue(mExportType); + dest.writeLongArray(mMasterKeyIds); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public ExportKeyringParcel createFromParcel(Parcel in) { + return new ExportKeyringParcel(in); + } + + @Override + public ExportKeyringParcel[] newArray(int size) { + return new ExportKeyringParcel[size]; + } + }; +} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportExportParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportExportParcel.java new file mode 100644 index 000000000..286741317 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportExportParcel.java @@ -0,0 +1,19 @@ +package org.sufficientlysecure.keychain.service; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Empty class, simply serves as a base class for ImportKeyringParcel and ExportKeyringParcel + */ +public class ImportExportParcel implements Parcelable { + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + + } +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportKeyringParcel.java index a41dd71cb..0b7149c75 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportKeyringParcel.java @@ -24,7 +24,7 @@ import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import java.util.ArrayList; -public class ImportKeyringParcel implements Parcelable { +public class ImportKeyringParcel extends ImportExportParcel { // if null, keys are expected to be read from a cache file in ImportExportOperations public ArrayList mKeyList; public String mKeyserver; // must be set if keys are to be imported from a keyserver diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java index 822c2b12e..adf5b7585 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java @@ -103,7 +103,8 @@ public class KeychainNewService extends Service implements Progressable { } else if (inputParcel instanceof CertifyAction) { op = new CertifyOperation(outerThis, new ProviderHelper(outerThis), outerThis, mActionCanceled); - } else if (inputParcel instanceof ImportKeyringParcel){ + } else if (inputParcel instanceof ImportKeyringParcel + || inputParcel instanceof ExportKeyringParcel){ op = new ImportExportOperation(outerThis, new ProviderHelper(outerThis), outerThis, mActionCanceled); } else { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java index bcd5d837f..eec29b123 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java @@ -91,11 +91,6 @@ public class KeychainService extends Service implements Progressable { public static final String ACTION_PROMOTE_KEYRING = Constants.INTENT_PREFIX + "PROMOTE_KEYRING"; - public static final String ACTION_IMPORT_KEYRING = Constants.INTENT_PREFIX + "IMPORT_KEYRING"; - public static final String ACTION_EXPORT_KEYRING = Constants.INTENT_PREFIX + "EXPORT_KEYRING"; - - public static final String ACTION_UPLOAD_KEYRING = Constants.INTENT_PREFIX + "UPLOAD_KEYRING"; - public static final String ACTION_DELETE = Constants.INTENT_PREFIX + "DELETE"; public static final String ACTION_CONSOLIDATE = Constants.INTENT_PREFIX + "CONSOLIDATE"; @@ -117,20 +112,6 @@ public class KeychainService extends Service implements Progressable { 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_SERVER = "import_key_server"; - - // export key - public static final String EXPORT_FILENAME = "export_filename"; - public static final String EXPORT_URI = "export_uri"; - public static final String EXPORT_SECRET = "export_secret"; - public static final String EXPORT_ALL = "export_all"; - public static final String EXPORT_KEY_RING_MASTER_KEY_ID = "export_key_ring_id"; - - // upload key - public static final String UPLOAD_KEY_SERVER = "upload_key_server"; - // promote key public static final String PROMOTE_MASTER_KEY_ID = "promote_master_key_id"; public static final String PROMOTE_CARD_AID = "promote_card_aid"; @@ -354,76 +335,6 @@ public class KeychainService extends Service implements Progressable { break; } - case ACTION_EXPORT_KEYRING: { - - // Input - boolean exportSecret = data.getBoolean(EXPORT_SECRET, false); - String outputFile = data.getString(EXPORT_FILENAME); - Uri outputUri = data.getParcelable(EXPORT_URI); - - boolean exportAll = data.getBoolean(EXPORT_ALL); - long[] masterKeyIds = exportAll ? null : data.getLongArray(EXPORT_KEY_RING_MASTER_KEY_ID); - - // Operation - ImportExportOperation importExportOperation = new ImportExportOperation( - KeychainService.this, providerHelper, KeychainService.this); - ExportResult result; - if (outputFile != null) { - result = importExportOperation.exportToFile(masterKeyIds, exportSecret, outputFile); - } else { - result = importExportOperation.exportToUri(masterKeyIds, exportSecret, outputUri); - } - - // Result - sendMessageToHandler(MessageStatus.OKAY, result); - - break; - } - case ACTION_IMPORT_KEYRING: { - - // Input - String keyServer = data.getString(IMPORT_KEY_SERVER); - ArrayList keyList = data.getParcelableArrayList(IMPORT_KEY_LIST); - - ImportExportOperation importExportOperation = new ImportExportOperation( - KeychainService.this, - providerHelper, KeychainService.this, mActionCanceled); - - ImportKeyringParcel inputParcel = new ImportKeyringParcel(keyList, keyServer); - CryptoInputParcel cryptoInputParcel = new CryptoInputParcel(); - - ImportKeyResult result = importExportOperation.execute(inputParcel, cryptoInputParcel); - - sendMessageToHandler(MessageStatus.OKAY, result); - - break; - } - case ACTION_UPLOAD_KEYRING: { - try { - - // Input - String keyServer = data.getString(UPLOAD_KEY_SERVER); - // and dataUri! - - // Operation - HkpKeyserver server = new HkpKeyserver(keyServer); - - CanonicalizedPublicKeyRing keyring = providerHelper.getCanonicalizedPublicKeyRing(dataUri); - ImportExportOperation importExportOperation = new ImportExportOperation( - KeychainService.this, providerHelper, KeychainService.this); - - try { - importExportOperation.uploadKeyRingToServer(server, keyring); - } catch (Keyserver.AddKeyException e) { - throw new PgpGeneralException("Unable to export key to selected server"); - } - - sendMessageToHandler(MessageStatus.OKAY); - } catch (Exception e) { - sendErrorToHandler(e); - } - break; - } } stopSelf(); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java index ebbd01afe..7a580c541 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -35,15 +35,18 @@ import org.spongycastle.bcpg.sig.KeyFlags; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.EditKeyResult; +import org.sufficientlysecure.keychain.operations.results.ExportResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.service.ExportKeyringParcel; import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Preferences; @@ -63,6 +66,8 @@ public class CreateKeyFinalFragment extends Fragment { SaveKeyringParcel mSaveKeyringParcel; + private CryptoOperationHelper mOperationHelper; + public static CreateKeyFinalFragment newInstance() { CreateKeyFinalFragment frag = new CreateKeyFinalFragment(); @@ -134,6 +139,9 @@ public class CreateKeyFinalFragment extends Fragment { @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (mOperationHelper != null) { + mOperationHelper.handleActivityResult(requestCode, resultCode, data); + } switch (requestCode) { case REQUEST_EDIT_KEY: { if (resultCode == Activity.RESULT_OK) { @@ -249,58 +257,58 @@ public class CreateKeyFinalFragment extends Fragment { // TODO move into EditKeyOperation private void uploadKey(final EditKeyResult saveKeyResult) { - // Send all information needed to service to upload key in other thread - final Intent intent = new Intent(getActivity(), KeychainService.class); - - intent.setAction(KeychainService.ACTION_UPLOAD_KEYRING); // set data uri as path to keyring - Uri blobUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri( + final Uri blobUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri( saveKeyResult.mMasterKeyId); - intent.setData(blobUri); - - // fill values for this action - Bundle data = new Bundle(); - // upload to favorite keyserver - String keyserver = Preferences.getPreferences(getActivity()).getPreferredKeyserver(); - data.putString(KeychainService.UPLOAD_KEY_SERVER, keyserver); + final String keyserver = Preferences.getPreferences(getActivity()).getPreferredKeyserver(); - intent.putExtra(KeychainService.EXTRA_DATA, data); + CryptoOperationHelper.Callback callback + = new CryptoOperationHelper.Callback() { - ServiceProgressHandler saveHandler = new ServiceProgressHandler(getActivity()) { @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); + public ExportKeyringParcel createOperationInput() { + return new ExportKeyringParcel(keyserver, blobUri); + } - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - // TODO: upload operation needs a result! - // TODO: then combine these results - //if (result.getResult() == OperationResultParcel.RESULT_OK) { - //Notify.create(getActivity(), R.string.key_send_success, - //Notify.Style.OK).show(); - - Intent data = new Intent(); - data.putExtra(OperationResult.EXTRA_RESULT, saveKeyResult); - getActivity().setResult(Activity.RESULT_OK, data); - getActivity().finish(); - } + @Override + public void onCryptoOperationSuccess(ExportResult result) { + // TODO: upload operation needs a result! + // TODO: then combine these results (saveKeyResult and update op result) + //if (result.getResult() == OperationResultParcel.RESULT_OK) { + //Notify.create(getActivity(), R.string.key_send_success, + //Notify.Style.OK).show(); + + Intent data = new Intent(); + data.putExtra(OperationResult.EXTRA_RESULT, saveKeyResult); + getActivity().setResult(Activity.RESULT_OK, data); + getActivity().finish(); } - }; - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); + @Override + public void onCryptoOperationCancelled() { - // show progress dialog - saveHandler.showProgressDialog( - getString(R.string.progress_uploading), - ProgressDialog.STYLE_HORIZONTAL, false); + } - // start service with intent - getActivity().startService(intent); + @Override + public void onCryptoOperationError(ExportResult result) { + + // TODO: upload operation needs a result! + // TODO: then combine these results (saveKeyResult and update op result) + //if (result.getResult() == OperationResultParcel.RESULT_OK) { + //Notify.create(getActivity(), R.string.key_send_success, + //Notify.Style.OK).show(); + + Intent data = new Intent(); + data.putExtra(OperationResult.EXTRA_RESULT, saveKeyResult); + getActivity().setResult(Activity.RESULT_OK, data); + getActivity().finish(); + } + }; + mOperationHelper = new CryptoOperationHelper<>(this, callback, R.string.progress_uploading); + mOperationHelper.cryptoOperation(); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java index e4dff6083..554aa43a8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java @@ -17,12 +17,9 @@ package org.sufficientlysecure.keychain.ui; -import android.app.ProgressDialog; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; import android.support.v4.app.NavUtils; import android.view.MenuItem; import android.view.View; @@ -33,23 +30,31 @@ import android.widget.Toast; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.operations.results.ExportResult; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.service.ExportKeyringParcel; import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.ui.base.BaseActivity; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Preferences; /** * Sends the selected public key to a keyserver */ -public class UploadKeyActivity extends BaseActivity { +public class UploadKeyActivity extends BaseActivity + implements CryptoOperationHelper.Callback { private View mUploadButton; private Spinner mKeyServerSpinner; private Uri mDataUri; + // CryptoOperationHelper.Callback vars + private String mKeyserver; + private Uri mUnifiedKeyringUri; + private CryptoOperationHelper mUploadOpHelper; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -89,51 +94,23 @@ public class UploadKeyActivity extends BaseActivity { setContentView(R.layout.upload_key_activity); } - private void uploadKey() { - // Send all information needed to service to upload key in other thread - Intent intent = new Intent(this, KeychainService.class); - - intent.setAction(KeychainService.ACTION_UPLOAD_KEYRING); + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (mUploadOpHelper != null) { + mUploadOpHelper.handleActivityResult(requestCode, resultCode, data); + } + super.onActivityResult(requestCode, resultCode, data); + } - // set data uri as path to keyring + private void uploadKey() { Uri blobUri = KeyRings.buildUnifiedKeyRingUri(mDataUri); - intent.setData(blobUri); - - // fill values for this action - Bundle data = new Bundle(); + mUnifiedKeyringUri = blobUri; String server = (String) mKeyServerSpinner.getSelectedItem(); - data.putString(KeychainService.UPLOAD_KEY_SERVER, server); - - intent.putExtra(KeychainService.EXTRA_DATA, data); - - // Message is received after uploading is done in KeychainService - ServiceProgressHandler saveHandler = new ServiceProgressHandler(this) { - @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - - Toast.makeText(UploadKeyActivity.this, R.string.msg_crt_upload_success, - Toast.LENGTH_SHORT).show(); - finish(); - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); + mKeyserver = server; - // show progress dialog - saveHandler.showProgressDialog( - getString(R.string.progress_uploading), - ProgressDialog.STYLE_HORIZONTAL, false); - - // start service with intent - startService(intent); + mUploadOpHelper = new CryptoOperationHelper(this, this, R.string.progress_uploading); + mUploadOpHelper.cryptoOperation(); } @Override @@ -148,4 +125,25 @@ public class UploadKeyActivity extends BaseActivity { } return super.onOptionsItemSelected(item); } + + @Override + public ExportKeyringParcel createOperationInput() { + return new ExportKeyringParcel(mKeyserver, mUnifiedKeyringUri); + } + + @Override + public void onCryptoOperationSuccess(ExportResult result) { + Toast.makeText(UploadKeyActivity.this, R.string.msg_crt_upload_success, + Toast.LENGTH_SHORT).show(); + } + + @Override + public void onCryptoOperationCancelled() { + + } + + @Override + public void onCryptoOperationError(ExportResult result) { + // TODO: Implement proper log for key upload then show error + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ExportHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ExportHelper.java index 2fd09dc79..358b261bf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ExportHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ExportHelper.java @@ -27,16 +27,23 @@ import android.support.v4.app.FragmentActivity; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.ExportResult; +import org.sufficientlysecure.keychain.service.ExportKeyringParcel; import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import java.io.File; -public class ExportHelper { +public class ExportHelper + implements CryptoOperationHelper.Callback { protected File mExportFile; FragmentActivity mActivity; + private CryptoOperationHelper mExportOpHelper; + private boolean mExportSecret; + private long[] mMasterKeyIds; + public ExportHelper(FragmentActivity activity) { super(); this.mActivity = activity; @@ -71,60 +78,38 @@ public class ExportHelper { }, mActivity.getSupportFragmentManager() ,title, message, exportFile, checkMsg); } + // TODO: If ExportHelper requires pending data (see CryptoOPerationHelper), activities using + // TODO: this class should be able to call mExportOpHelper.handleActivity + /** * Export keys */ public void exportKeys(long[] masterKeyIds, boolean exportSecret) { Log.d(Constants.TAG, "exportKeys started"); + mExportSecret = exportSecret; + mMasterKeyIds = masterKeyIds; // if masterKeyIds is null it means export all - // Send all information needed to service to export key in other thread - final Intent intent = new Intent(mActivity, KeychainService.class); - - intent.setAction(KeychainService.ACTION_EXPORT_KEYRING); - - // fill values for this action - Bundle data = new Bundle(); - - data.putString(KeychainService.EXPORT_FILENAME, mExportFile.getAbsolutePath()); - data.putBoolean(KeychainService.EXPORT_SECRET, exportSecret); - - if (masterKeyIds == null) { - data.putBoolean(KeychainService.EXPORT_ALL, true); - } else { - data.putLongArray(KeychainService.EXPORT_KEY_RING_MASTER_KEY_ID, masterKeyIds); - } - - intent.putExtra(KeychainService.EXTRA_DATA, data); - - // Message is received after exporting is done in KeychainService - ServiceProgressHandler exportHandler = new ServiceProgressHandler(mActivity) { - @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - // get returned data bundle - Bundle data = message.getData(); + mExportOpHelper = new CryptoOperationHelper(mActivity, this, R.string.progress_exporting); + mExportOpHelper.cryptoOperation(); + } - ExportResult result = data.getParcelable(ExportResult.EXTRA_RESULT); - result.createNotify(mActivity).show(); - } - } - }; + @Override + public ExportKeyringParcel createOperationInput() { + return new ExportKeyringParcel(mMasterKeyIds, mExportSecret, mExportFile.getAbsolutePath()); + } - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(exportHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); + @Override + public void onCryptoOperationSuccess(ExportResult result) { + result.createNotify(mActivity).show(); + } - // show progress dialog - exportHandler.showProgressDialog( - mActivity.getString(R.string.progress_exporting), - ProgressDialog.STYLE_HORIZONTAL, false - ); + @Override + public void onCryptoOperationCancelled() { - // start service with intent - mActivity.startService(intent); } + @Override + public void onCryptoOperationError(ExportResult result) { + result.createNotify(mActivity).show(); + } } -- cgit v1.2.3 From af6a37f02b0fd51bc895e1b9aa5fea2fc0c209be Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Tue, 23 Jun 2015 23:51:31 +0530 Subject: migrated key creation to KeychainNewService --- .../keychain/service/KeychainService.java | 21 ---- .../keychain/ui/CreateKeyFinalFragment.java | 109 ++++++++------------- .../keychain/ui/base/CryptoOperationFragment.java | 14 ++- 3 files changed, 52 insertions(+), 92 deletions(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java index eec29b123..83e435c96 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java @@ -103,11 +103,6 @@ public class KeychainService extends Service implements Progressable { public static final String KEYBASE_REQUIRED_FINGERPRINT = "keybase_required_fingerprint"; public static final String KEYBASE_PROOF = "keybase_proof"; - // save keyring - public static final String EDIT_KEYRING_PARCEL = "save_parcel"; - public static final String EDIT_KEYRING_PASSPHRASE = "passphrase"; - public static final String EXTRA_CRYPTO_INPUT = "crypto_input"; - // delete keyring(s) public static final String DELETE_KEY_LIST = "delete_list"; public static final String DELETE_IS_SECRET = "delete_is_secret"; @@ -301,22 +296,6 @@ public class KeychainService extends Service implements Progressable { break; } - case ACTION_EDIT_KEYRING: { - - // Input - SaveKeyringParcel saveParcel = data.getParcelable(EDIT_KEYRING_PARCEL); - CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT); - - // Operation - EditKeyOperation op = new EditKeyOperation(KeychainService.this, providerHelper, - KeychainService.this, mActionCanceled); - OperationResult result = op.execute(saveParcel, cryptoInput); - - // Result - sendMessageToHandler(MessageStatus.OKAY, result); - - break; - } case ACTION_PROMOTE_KEYRING: { // Input diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java index 7a580c541..1a5c3cd96 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -24,7 +24,6 @@ import android.net.Uri; import android.os.Bundle; import android.os.Message; import android.os.Messenger; -import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -46,13 +45,15 @@ import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Preferences; import java.util.Iterator; -public class CreateKeyFinalFragment extends Fragment { +public class CreateKeyFinalFragment + extends CryptoOperationFragment { public static final int REQUEST_EDIT_KEY = 0x00008007; @@ -66,7 +67,7 @@ public class CreateKeyFinalFragment extends Fragment { SaveKeyringParcel mSaveKeyringParcel; - private CryptoOperationHelper mOperationHelper; + private CryptoOperationHelper mUploadOpHelper; public static CreateKeyFinalFragment newInstance() { CreateKeyFinalFragment frag = new CreateKeyFinalFragment(); @@ -139,8 +140,8 @@ public class CreateKeyFinalFragment extends Fragment { @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (mOperationHelper != null) { - mOperationHelper.handleActivityResult(requestCode, resultCode, data); + if (mUploadOpHelper != null) { + mUploadOpHelper.handleActivityResult(requestCode, resultCode, data); } switch (requestCode) { case REQUEST_EDIT_KEY: { @@ -156,6 +157,30 @@ public class CreateKeyFinalFragment extends Fragment { } } + @Override + protected SaveKeyringParcel createOperationInput() { + return mSaveKeyringParcel; + } + + @Override + protected void onCryptoOperationSuccess(EditKeyResult result) { + if (result.mMasterKeyId != null && mUploadCheckbox.isChecked()) { + // result will be displayed after upload + uploadKey(result); + } else { + Intent data = new Intent(); + data.putExtra(OperationResult.EXTRA_RESULT, result); + getActivity().setResult(Activity.RESULT_OK, data); + getActivity().finish(); + } + } + + @Override + protected void onCryptoOperationResult(EditKeyResult result) { + // do something else? + super.onCryptoOperationResult(result); + } + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); @@ -202,57 +227,8 @@ public class CreateKeyFinalFragment extends Fragment { private void createKey() { - Intent intent = new Intent(getActivity(), KeychainService.class); - intent.setAction(KeychainService.ACTION_EDIT_KEYRING); - - ServiceProgressHandler saveHandler = new ServiceProgressHandler(getActivity()) { - @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - // get returned data bundle - Bundle returnData = message.getData(); - if (returnData == null) { - return; - } - final EditKeyResult result = - returnData.getParcelable(OperationResult.EXTRA_RESULT); - if (result == null) { - Log.e(Constants.TAG, "result == null"); - return; - } - - if (result.mMasterKeyId != null && mUploadCheckbox.isChecked()) { - // result will be displayed after upload - uploadKey(result); - } else { - Intent data = new Intent(); - data.putExtra(OperationResult.EXTRA_RESULT, result); - getActivity().setResult(Activity.RESULT_OK, data); - getActivity().finish(); - } - } - } - }; - - // fill values for this action - Bundle data = new Bundle(); - - // get selected key entries - data.putParcelable(KeychainService.EDIT_KEYRING_PARCEL, mSaveKeyringParcel); - - intent.putExtra(KeychainService.EXTRA_DATA, data); - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); - - saveHandler.showProgressDialog(getString(R.string.progress_building_key), - ProgressDialog.STYLE_HORIZONTAL, false); - - getActivity().startService(intent); + super.setProgressMessageResource(R.string.progress_building_key); + super.cryptoOperation(); } // TODO move into EditKeyOperation @@ -274,16 +250,7 @@ public class CreateKeyFinalFragment extends Fragment { @Override public void onCryptoOperationSuccess(ExportResult result) { - // TODO: upload operation needs a result! - // TODO: then combine these results (saveKeyResult and update op result) - //if (result.getResult() == OperationResultParcel.RESULT_OK) { - //Notify.create(getActivity(), R.string.key_send_success, - //Notify.Style.OK).show(); - - Intent data = new Intent(); - data.putExtra(OperationResult.EXTRA_RESULT, saveKeyResult); - getActivity().setResult(Activity.RESULT_OK, data); - getActivity().finish(); + handleResult(result); } @Override @@ -293,8 +260,11 @@ public class CreateKeyFinalFragment extends Fragment { @Override public void onCryptoOperationError(ExportResult result) { + handleResult(result); + } - // TODO: upload operation needs a result! + public void handleResult(ExportResult result) { + // TODO: upload operation needs a result! "result" is not currenlty used // TODO: then combine these results (saveKeyResult and update op result) //if (result.getResult() == OperationResultParcel.RESULT_OK) { //Notify.create(getActivity(), R.string.key_send_success, @@ -307,8 +277,9 @@ public class CreateKeyFinalFragment extends Fragment { } }; - mOperationHelper = new CryptoOperationHelper<>(this, callback, R.string.progress_uploading); - mOperationHelper.cryptoOperation(); + + mUploadOpHelper = new CryptoOperationHelper<>(this, callback, R.string.progress_uploading); + mUploadOpHelper.cryptoOperation(); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java index 53ab33dc5..3c837206d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java @@ -84,15 +84,25 @@ public abstract class CryptoOperationFragment Date: Wed, 24 Jun 2015 01:15:11 +0530 Subject: migrated delete op to KeychainNewService --- .../keychain/operations/DeleteOperation.java | 12 ++- .../keychain/service/KeychainNewService.java | 8 +- .../keychain/service/KeychainService.java | 23 ----- .../service/input/DeleteKeyringParcel.java | 44 +++++++++ .../keychain/ui/base/CryptoOperationHelper.java | 7 +- .../ui/dialog/DeleteKeyDialogFragment.java | 107 +++++++++++++-------- 6 files changed, 131 insertions(+), 70 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/DeleteKeyringParcel.java (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/DeleteOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/DeleteOperation.java index 5ef04ab05..06f7ee752 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/DeleteOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/DeleteOperation.java @@ -27,7 +27,10 @@ import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.ContactSyncAdapterService; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.service.input.DeleteKeyringParcel; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; +import org.sufficientlysecure.keychain.util.Log; /** An operation which implements a high level keyring delete operation. * @@ -37,13 +40,18 @@ import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; * a list. * */ -public class DeleteOperation extends BaseOperation { +public class DeleteOperation extends BaseOperation { public DeleteOperation(Context context, ProviderHelper providerHelper, Progressable progressable) { super(context, providerHelper, progressable); } - public DeleteResult execute(long[] masterKeyIds, boolean isSecret) { + @Override + public DeleteResult execute(DeleteKeyringParcel deleteKeyringParcel, + CryptoInputParcel cryptoInputParcel) { + + long[] masterKeyIds = deleteKeyringParcel.mMasterKeyIds; + boolean isSecret = deleteKeyringParcel.mIsSecret; OperationLog log = new OperationLog(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java index adf5b7585..3e76f38e4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java @@ -41,6 +41,7 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction; import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.service.input.DeleteKeyringParcel; import org.sufficientlysecure.keychain.util.Log; /** @@ -103,6 +104,9 @@ public class KeychainNewService extends Service implements Progressable { } else if (inputParcel instanceof CertifyAction) { op = new CertifyOperation(outerThis, new ProviderHelper(outerThis), outerThis, mActionCanceled); + } else if (inputParcel instanceof DeleteKeyringParcel){ + Log.e("PHILIP", "delete in KeychainNewService"); + op = new DeleteOperation(outerThis, new ProviderHelper(outerThis), outerThis); } else if (inputParcel instanceof ImportKeyringParcel || inputParcel instanceof ExportKeyringParcel){ op = new ImportExportOperation(outerThis, new ProviderHelper(outerThis), @@ -110,10 +114,10 @@ public class KeychainNewService extends Service implements Progressable { } else { return; } - + Log.e("PHILIP", "exec in KeychainNewService"); @SuppressWarnings("unchecked") // this is unchecked, we make sure it's the correct op above! OperationResult result = op.execute(inputParcel, cryptoInput); - + Log.e("PHILIP", "result in KeychainNewService" + result); sendMessageToHandler(MessageStatus.OKAY, result); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java index 83e435c96..13cb4ff6b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java @@ -87,12 +87,8 @@ public class KeychainService extends Service implements Progressable { public static final String ACTION_VERIFY_KEYBASE_PROOF = Constants.INTENT_PREFIX + "VERIFY_KEYBASE_PROOF"; - public static final String ACTION_EDIT_KEYRING = Constants.INTENT_PREFIX + "EDIT_KEYRING"; - public static final String ACTION_PROMOTE_KEYRING = Constants.INTENT_PREFIX + "PROMOTE_KEYRING"; - public static final String ACTION_DELETE = Constants.INTENT_PREFIX + "DELETE"; - public static final String ACTION_CONSOLIDATE = Constants.INTENT_PREFIX + "CONSOLIDATE"; public static final String ACTION_CANCEL = Constants.INTENT_PREFIX + "CANCEL"; @@ -103,10 +99,6 @@ public class KeychainService extends Service implements Progressable { public static final String KEYBASE_REQUIRED_FINGERPRINT = "keybase_required_fingerprint"; public static final String KEYBASE_PROOF = "keybase_proof"; - // delete keyring(s) - public static final String DELETE_KEY_LIST = "delete_list"; - public static final String DELETE_IS_SECRET = "delete_is_secret"; - // promote key public static final String PROMOTE_MASTER_KEY_ID = "promote_master_key_id"; public static final String PROMOTE_CARD_AID = "promote_card_aid"; @@ -281,21 +273,6 @@ public class KeychainService extends Service implements Progressable { break; } - case ACTION_DELETE: { - - // Input - long[] masterKeyIds = data.getLongArray(DELETE_KEY_LIST); - boolean isSecret = data.getBoolean(DELETE_IS_SECRET); - - // Operation - DeleteOperation op = new DeleteOperation(KeychainService.this, providerHelper, KeychainService.this); - DeleteResult result = op.execute(masterKeyIds, isSecret); - - // Result - sendMessageToHandler(MessageStatus.OKAY, result); - - break; - } case ACTION_PROMOTE_KEYRING: { // Input diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/DeleteKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/DeleteKeyringParcel.java new file mode 100644 index 000000000..cb61921e1 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/DeleteKeyringParcel.java @@ -0,0 +1,44 @@ +package org.sufficientlysecure.keychain.service.input; + +import android.os.Parcel; +import android.os.Parcelable; + +public class DeleteKeyringParcel implements Parcelable { + + public long[] mMasterKeyIds; + public boolean mIsSecret; + + public DeleteKeyringParcel(long[] masterKeyIds, boolean isSecret) { + mMasterKeyIds = masterKeyIds; + mIsSecret = isSecret; + } + + protected DeleteKeyringParcel(Parcel in) { + mIsSecret = in.readByte() != 0x00; + mMasterKeyIds = in.createLongArray(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeByte((byte) (mIsSecret ? 0x01 : 0x00)); + dest.writeLongArray(mMasterKeyIds); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public DeleteKeyringParcel createFromParcel(Parcel in) { + return new DeleteKeyringParcel(in); + } + + @Override + public DeleteKeyringParcel[] newArray(int size) { + return new DeleteKeyringParcel[size]; + } + }; +} + diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java index 43106820f..a9002cf4a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java @@ -208,6 +208,11 @@ public class CryptoOperationHelper { private static final String ARG_MESSENGER = "messenger"; private static final String ARG_DELETE_MASTER_KEY_IDS = "delete_master_key_ids"; @@ -52,6 +58,13 @@ public class DeleteKeyDialogFragment extends DialogFragment { private TextView mMainMessage; private View mInflateView; + private Messenger mMessenger; + + // for CryptoOperationHelper.Callback + private long[] mMasterKeyIds; + private boolean mHasSecret; + private CryptoOperationHelper mDeleteOpHelper; + /** * Creates new instance of this delete file dialog fragment */ @@ -67,10 +80,18 @@ public class DeleteKeyDialogFragment extends DialogFragment { return frag; } + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (mDeleteOpHelper != null) { + mDeleteOpHelper.handleActivityResult(requestCode, resultCode, data); + } + super.onActivityResult(requestCode, resultCode, data); + } + @Override public Dialog onCreateDialog(Bundle savedInstanceState) { final FragmentActivity activity = getActivity(); - final Messenger messenger = getArguments().getParcelable(ARG_MESSENGER); + mMessenger = getArguments().getParcelable(ARG_MESSENGER); final long[] masterKeyIds = getArguments().getLongArray(ARG_DELETE_MASTER_KEY_IDS); @@ -129,47 +150,16 @@ public class DeleteKeyDialogFragment extends DialogFragment { @Override public void onClick(DialogInterface dialog, int which) { - // Send all information needed to service to import key in other thread - Intent intent = new Intent(getActivity(), KeychainService.class); - - intent.setAction(KeychainService.ACTION_DELETE); - - // Message is received after importing is done in KeychainService - ServiceProgressHandler saveHandler = new ServiceProgressHandler(getActivity()) { - @Override - public void handleMessage(Message message) { - super.handleMessage(message); - // handle messages by standard KeychainIntentServiceHandler first - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - try { - Message msg = Message.obtain(); - msg.copyFrom(message); - messenger.send(msg); - } catch (RemoteException e) { - Log.e(Constants.TAG, "messenger error", e); - } - } - } - }; - - // fill values for this action - Bundle data = new Bundle(); - data.putLongArray(KeychainService.DELETE_KEY_LIST, masterKeyIds); - data.putBoolean(KeychainService.DELETE_IS_SECRET, hasSecret); - intent.putExtra(KeychainService.EXTRA_DATA, data); - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); - - // show progress dialog - saveHandler.showProgressDialog(getString(R.string.progress_deleting), - ProgressDialog.STYLE_HORIZONTAL, true); - - // start service with intent - getActivity().startService(intent); + mMasterKeyIds = masterKeyIds; + mHasSecret = hasSecret; - dismiss(); + mDeleteOpHelper = new CryptoOperationHelper<> + (DeleteKeyDialogFragment.this, DeleteKeyDialogFragment.this, + R.string.progress_deleting); + mDeleteOpHelper.cryptoOperation(); + // do NOT dismiss here, it'll give + // OperationHelper a null fragmentManager + // dismiss(); } }); builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @@ -183,4 +173,37 @@ public class DeleteKeyDialogFragment extends DialogFragment { return builder.show(); } + @Override + public DeleteKeyringParcel createOperationInput() { + return new DeleteKeyringParcel(mMasterKeyIds, mHasSecret); + } + + @Override + public void onCryptoOperationSuccess(DeleteResult result) { + handleResult(result); + } + + @Override + public void onCryptoOperationCancelled() { + + } + + @Override + public void onCryptoOperationError(DeleteResult result) { + handleResult(result); + } + + public void handleResult(DeleteResult result) { + try { + Bundle data = new Bundle(); + data.putParcelable(OperationResult.EXTRA_RESULT, result); + Message msg = Message.obtain(); + msg.arg1 = ServiceProgressHandler.MessageStatus.OKAY.ordinal(); + msg.setData(data); + mMessenger.send(msg); + } catch (RemoteException e) { + Log.e(Constants.TAG, "messenger error", e); + } + dismiss(); + } } -- cgit v1.2.3 From de4b203150cfe542cdba7003bc9cc249b5d22b7f Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Wed, 24 Jun 2015 01:46:34 +0530 Subject: migrated promote op to KeychainNewService --- .../keychain/operations/PromoteKeyOperation.java | 12 ++++- .../keychain/service/KeychainNewService.java | 8 +-- .../keychain/service/KeychainService.java | 25 ---------- .../keychain/service/PromoteKeyringParcel.java | 47 ++++++++++++++++++ .../keychain/ui/ViewKeyYubiKeyFragment.java | 58 +++++++--------------- 5 files changed, 80 insertions(+), 70 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PromoteKeyringParcel.java (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java index 558756378..fe8a23d12 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java @@ -32,6 +32,8 @@ import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException; +import org.sufficientlysecure.keychain.service.PromoteKeyringParcel; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.ProgressScaler; @@ -45,14 +47,20 @@ import java.util.concurrent.atomic.AtomicBoolean; * without secret key material, using a GNU_DUMMY s2k type. * */ -public class PromoteKeyOperation extends BaseOperation { +public class PromoteKeyOperation extends BaseOperation { public PromoteKeyOperation(Context context, ProviderHelper providerHelper, Progressable progressable, AtomicBoolean cancelled) { super(context, providerHelper, progressable, cancelled); } - public PromoteKeyResult execute(long masterKeyId, byte[] cardAid, long[] subKeyIds) { + @Override + public PromoteKeyResult execute(PromoteKeyringParcel promoteKeyringParcel, + CryptoInputParcel cryptoInputParcel) { + // Input + long masterKeyId = promoteKeyringParcel.mKeyRingId; + byte[] cardAid = promoteKeyringParcel.mCardAid; + long[] subKeyIds = promoteKeyringParcel.mSubKeyIds; OperationLog log = new OperationLog(); log.add(LogType.MSG_PR, 0); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java index 3e76f38e4..1a56b7083 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java @@ -104,9 +104,11 @@ public class KeychainNewService extends Service implements Progressable { } else if (inputParcel instanceof CertifyAction) { op = new CertifyOperation(outerThis, new ProviderHelper(outerThis), outerThis, mActionCanceled); - } else if (inputParcel instanceof DeleteKeyringParcel){ - Log.e("PHILIP", "delete in KeychainNewService"); + } else if (inputParcel instanceof DeleteKeyringParcel) { op = new DeleteOperation(outerThis, new ProviderHelper(outerThis), outerThis); + } else if (inputParcel instanceof PromoteKeyringParcel){ + op = new PromoteKeyOperation(outerThis, new ProviderHelper(outerThis), + outerThis, mActionCanceled); } else if (inputParcel instanceof ImportKeyringParcel || inputParcel instanceof ExportKeyringParcel){ op = new ImportExportOperation(outerThis, new ProviderHelper(outerThis), @@ -114,10 +116,8 @@ public class KeychainNewService extends Service implements Progressable { } else { return; } - Log.e("PHILIP", "exec in KeychainNewService"); @SuppressWarnings("unchecked") // this is unchecked, we make sure it's the correct op above! OperationResult result = op.execute(inputParcel, cryptoInput); - Log.e("PHILIP", "result in KeychainNewService" + result); sendMessageToHandler(MessageStatus.OKAY, result); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java index 13cb4ff6b..c9d82951b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java @@ -87,8 +87,6 @@ public class KeychainService extends Service implements Progressable { public static final String ACTION_VERIFY_KEYBASE_PROOF = Constants.INTENT_PREFIX + "VERIFY_KEYBASE_PROOF"; - public static final String ACTION_PROMOTE_KEYRING = Constants.INTENT_PREFIX + "PROMOTE_KEYRING"; - public static final String ACTION_CONSOLIDATE = Constants.INTENT_PREFIX + "CONSOLIDATE"; public static final String ACTION_CANCEL = Constants.INTENT_PREFIX + "CANCEL"; @@ -99,11 +97,6 @@ public class KeychainService extends Service implements Progressable { public static final String KEYBASE_REQUIRED_FINGERPRINT = "keybase_required_fingerprint"; public static final String KEYBASE_PROOF = "keybase_proof"; - // promote key - public static final String PROMOTE_MASTER_KEY_ID = "promote_master_key_id"; - public static final String PROMOTE_CARD_AID = "promote_card_aid"; - public static final String PROMOTE_SUBKEY_IDS = "promote_fingerprints"; - // consolidate public static final String CONSOLIDATE_RECOVERY = "consolidate_recovery"; @@ -271,24 +264,6 @@ public class KeychainService extends Service implements Progressable { sendErrorToHandler(e); } - break; - } - case ACTION_PROMOTE_KEYRING: { - - // Input - long keyRingId = data.getLong(PROMOTE_MASTER_KEY_ID); - byte[] cardAid = data.getByteArray(PROMOTE_CARD_AID); - long[] subKeyIds = data.getLongArray(PROMOTE_SUBKEY_IDS); - - // Operation - PromoteKeyOperation op = new PromoteKeyOperation( - KeychainService.this, providerHelper, KeychainService.this, - mActionCanceled); - PromoteKeyResult result = op.execute(keyRingId, cardAid, subKeyIds); - - // Result - sendMessageToHandler(MessageStatus.OKAY, result); - break; } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PromoteKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PromoteKeyringParcel.java new file mode 100644 index 000000000..dc8c51c19 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PromoteKeyringParcel.java @@ -0,0 +1,47 @@ +package org.sufficientlysecure.keychain.service; + +import android.os.Parcel; +import android.os.Parcelable; + +public class PromoteKeyringParcel implements Parcelable { + + public long mKeyRingId; + public byte[] mCardAid; + public long[] mSubKeyIds; + + public PromoteKeyringParcel(long keyRingId, byte[] cardAid, long[] subKeyIds) { + mKeyRingId = keyRingId; + mCardAid = cardAid; + mSubKeyIds = subKeyIds; + } + + protected PromoteKeyringParcel(Parcel in) { + mKeyRingId = in.readLong(); + mCardAid = in.createByteArray(); + mSubKeyIds = in.createLongArray(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeLong(mKeyRingId); + dest.writeByteArray(mCardAid); + dest.writeLongArray(mSubKeyIds); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public PromoteKeyringParcel createFromParcel(Parcel in) { + return new PromoteKeyringParcel(in); + } + + @Override + public PromoteKeyringParcel[] newArray(int size) { + return new PromoteKeyringParcel[size]; + } + }; +} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java index ab25341d3..c2db5e018 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java @@ -44,11 +44,14 @@ import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; import org.sufficientlysecure.keychain.service.KeychainService; +import org.sufficientlysecure.keychain.service.PromoteKeyringParcel; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; -public class ViewKeyYubiKeyFragment extends Fragment +public class ViewKeyYubiKeyFragment + extends CryptoOperationFragment implements LoaderCallbacks { public static final String ARG_MASTER_KEY_ID = "master_key_id"; @@ -60,6 +63,8 @@ public class ViewKeyYubiKeyFragment extends Fragment private String mUserId; private byte[] mCardAid; private long mMasterKeyId; + private long[] mSubKeyIds; + private Button vButton; private TextView vStatus; @@ -127,50 +132,15 @@ public class ViewKeyYubiKeyFragment extends Fragment } public void promoteToSecretKey() { - - ServiceProgressHandler saveHandler = new ServiceProgressHandler(getActivity()) { - @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - // get returned data bundle - Bundle returnData = message.getData(); - - PromoteKeyResult result = - returnData.getParcelable(DecryptVerifyResult.EXTRA_RESULT); - - result.createNotify(getActivity()).show(); - } - - } - }; - - // Send all information needed to service to decrypt in other thread - Intent intent = new Intent(getActivity(), KeychainService.class); - - // fill values for this action - - intent.setAction(KeychainService.ACTION_PROMOTE_KEYRING); - - Bundle data = new Bundle(); - data.putLong(KeychainService.PROMOTE_MASTER_KEY_ID, mMasterKeyId); - data.putByteArray(KeychainService.PROMOTE_CARD_AID, mCardAid); long[] subKeyIds = new long[mFingerprints.length]; for (int i = 0; i < subKeyIds.length; i++) { subKeyIds[i] = KeyFormattingUtils.getKeyIdFromFingerprint(mFingerprints[i]); } - data.putLongArray(KeychainService.PROMOTE_SUBKEY_IDS, subKeyIds); - intent.putExtra(KeychainService.EXTRA_DATA, data); - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); - // start service with intent - getActivity().startService(intent); + // mMasterKeyId and mCardAid are already set + mSubKeyIds = subKeyIds; + cryptoOperation(); } public static final String[] PROJECTION = new String[]{ @@ -240,4 +210,14 @@ public class ViewKeyYubiKeyFragment extends Fragment public void onLoaderReset(Loader loader) { } + + @Override + protected PromoteKeyringParcel createOperationInput() { + return new PromoteKeyringParcel(mMasterKeyId, mCardAid, mSubKeyIds); + } + + @Override + protected void onCryptoOperationResult(PromoteKeyResult result) { + result.createNotify(getActivity()).show(); + } } -- cgit v1.2.3 From 6f3be84c43365b081040e8cefc571fa3db0550aa Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Wed, 24 Jun 2015 01:59:03 +0530 Subject: fixed promote key tests --- .../sufficientlysecure/keychain/operations/PromoteKeyOperation.java | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java index fe8a23d12..efe0c466a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java @@ -62,6 +62,11 @@ public class PromoteKeyOperation extends BaseOperation { byte[] cardAid = promoteKeyringParcel.mCardAid; long[] subKeyIds = promoteKeyringParcel.mSubKeyIds; + return execute(masterKeyId, cardAid, subKeyIds); + } + + public PromoteKeyResult execute(long masterKeyId, byte[] cardAid, long[] subKeyIds) { + OperationLog log = new OperationLog(); log.add(LogType.MSG_PR, 0); -- cgit v1.2.3 From b33004a2f599d34035c0b49dff75cf00a21adb7e Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Wed, 24 Jun 2015 03:51:53 +0530 Subject: migrated consolidation --- .../keychain/operations/ConsolidateOperation.java | 27 ++++++ .../keychain/service/ConsolidateInputParcel.java | 39 +++++++++ .../keychain/service/KeychainNewService.java | 3 + .../keychain/service/KeychainService.java | 20 +---- .../keychain/ui/ConsolidateDialogActivity.java | 97 ++++++++++------------ .../keychain/ui/KeyListFragment.java | 71 +++++++--------- 6 files changed, 142 insertions(+), 115 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ConsolidateOperation.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ConsolidateInputParcel.java (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ConsolidateOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ConsolidateOperation.java new file mode 100644 index 000000000..780301dd9 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ConsolidateOperation.java @@ -0,0 +1,27 @@ +package org.sufficientlysecure.keychain.operations; + +import android.content.Context; + +import org.sufficientlysecure.keychain.operations.results.ConsolidateResult; +import org.sufficientlysecure.keychain.pgp.Progressable; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.ConsolidateInputParcel; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; + +public class ConsolidateOperation extends BaseOperation { + + public ConsolidateOperation(Context context, ProviderHelper providerHelper, Progressable + progressable) { + super(context, providerHelper, progressable); + } + + @Override + public ConsolidateResult execute(ConsolidateInputParcel consolidateInputParcel, + CryptoInputParcel cryptoInputParcel) { + if (consolidateInputParcel.mConsolidateRecovery) { + return mProviderHelper.consolidateDatabaseStep2(mProgressable); + } else { + return mProviderHelper.consolidateDatabaseStep1(mProgressable); + } + } +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ConsolidateInputParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ConsolidateInputParcel.java new file mode 100644 index 000000000..d2ab18c0f --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ConsolidateInputParcel.java @@ -0,0 +1,39 @@ +package org.sufficientlysecure.keychain.service; + +import android.os.Parcel; +import android.os.Parcelable; + +public class ConsolidateInputParcel implements Parcelable { + + public boolean mConsolidateRecovery; + + public ConsolidateInputParcel(boolean consolidateRecovery) { + mConsolidateRecovery = consolidateRecovery; + } + + protected ConsolidateInputParcel(Parcel in) { + mConsolidateRecovery = in.readByte() != 0x00; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeByte((byte) (mConsolidateRecovery ? 0x01 : 0x00)); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public ConsolidateInputParcel createFromParcel(Parcel in) { + return new ConsolidateInputParcel(in); + } + + @Override + public ConsolidateInputParcel[] newArray(int size) { + return new ConsolidateInputParcel[size]; + } + }; +} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java index 1a56b7083..080f6a38f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java @@ -113,6 +113,9 @@ public class KeychainNewService extends Service implements Progressable { || inputParcel instanceof ExportKeyringParcel){ op = new ImportExportOperation(outerThis, new ProviderHelper(outerThis), outerThis, mActionCanceled); + } else if (inputParcel instanceof ConsolidateInputParcel) { + op = new ConsolidateOperation(outerThis, new ProviderHelper(outerThis), + outerThis); } else { return; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java index c9d82951b..127719ab7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java @@ -37,10 +37,7 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; import org.sufficientlysecure.keychain.keyimport.Keyserver; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; -import org.sufficientlysecure.keychain.operations.DeleteOperation; -import org.sufficientlysecure.keychain.operations.EditKeyOperation; -import org.sufficientlysecure.keychain.operations.ImportExportOperation; -import org.sufficientlysecure.keychain.operations.PromoteKeyOperation; +import org.sufficientlysecure.keychain.operations.*; import org.sufficientlysecure.keychain.operations.results.ConsolidateResult; import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; import org.sufficientlysecure.keychain.operations.results.DeleteResult; @@ -157,21 +154,6 @@ public class KeychainService extends Service implements Progressable { // executeServiceMethod action from extra bundle switch (action) { - case ACTION_CONSOLIDATE: { - - // Operation - ConsolidateResult result; - if (data.containsKey(CONSOLIDATE_RECOVERY) && data.getBoolean(CONSOLIDATE_RECOVERY)) { - result = providerHelper.consolidateDatabaseStep2(KeychainService.this); - } else { - result = providerHelper.consolidateDatabaseStep1(KeychainService.this); - } - - // Result - sendMessageToHandler(MessageStatus.OKAY, result); - - break; - } case ACTION_VERIFY_KEYBASE_PROOF: { try { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java index 6a9bb7b11..b3a447c84 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java @@ -17,25 +17,27 @@ package org.sufficientlysecure.keychain.ui; -import android.app.ProgressDialog; import android.content.Intent; import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; import android.support.v4.app.FragmentActivity; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.service.KeychainService; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.operations.results.ConsolidateResult; +import org.sufficientlysecure.keychain.service.ConsolidateInputParcel; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; /** * We can not directly create a dialog on the application context. * This activity encapsulates a DialogFragment to emulate a dialog. */ -public class ConsolidateDialogActivity extends FragmentActivity { +public class ConsolidateDialogActivity extends FragmentActivity + implements CryptoOperationHelper.Callback { public static final String EXTRA_CONSOLIDATE_RECOVERY = "consolidate_recovery"; + private CryptoOperationHelper mConsolidateOpHelper; + private boolean mRecovery; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -48,55 +50,40 @@ public class ConsolidateDialogActivity extends FragmentActivity { } private void consolidateRecovery(boolean recovery) { - // Message is received after importing is done in KeychainService - ServiceProgressHandler saveHandler = new ServiceProgressHandler(this) { - @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - /* don't care about the results (for now?) - - // get returned data bundle - Bundle returnData = message.getInputData(); - if (returnData == null) { - return; - } - final ConsolidateResult result = - returnData.getParcelable(KeychainService.RESULT_CONSOLIDATE); - if (result == null) { - return; - } - result.createNotify(ConsolidateDialogActivity.this).show(); - */ - - ConsolidateDialogActivity.this.finish(); - } - } - }; - - // Send all information needed to service to import key in other thread - Intent intent = new Intent(this, KeychainService.class); - intent.setAction(KeychainService.ACTION_CONSOLIDATE); - - // fill values for this action - Bundle data = new Bundle(); - data.putBoolean(KeychainService.CONSOLIDATE_RECOVERY, recovery); - intent.putExtra(KeychainService.EXTRA_DATA, data); - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); - - // show progress dialog - saveHandler.showProgressDialog( - getString(R.string.progress_importing), - ProgressDialog.STYLE_HORIZONTAL, false - ); - - // start service with intent - startService(intent); + + mRecovery = recovery; + + mConsolidateOpHelper = new CryptoOperationHelper<>(this, this, R.string.progress_importing); + mConsolidateOpHelper.cryptoOperation(); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (mConsolidateOpHelper != null) { + mConsolidateOpHelper.handleActivityResult(requestCode, resultCode, data); + } + } + + @Override + public ConsolidateInputParcel createOperationInput() { + return new ConsolidateInputParcel(mRecovery); } + @Override + public void onCryptoOperationSuccess(ConsolidateResult result) { + // don't care about result (for now?) + ConsolidateDialogActivity.this.finish(); + } + + @Override + public void onCryptoOperationCancelled() { + + } + + @Override + public void onCryptoOperationError(ConsolidateResult result) { + // don't care about result (for now?) + ConsolidateDialogActivity.this.finish(); + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index b52640d86..379f4c6b9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -64,10 +64,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.service.ImportKeyringParcel; -import org.sufficientlysecure.keychain.service.KeychainService; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; -import org.sufficientlysecure.keychain.service.PassphraseCacheService; +import org.sufficientlysecure.keychain.service.*; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; @@ -115,6 +112,9 @@ public class KeyListFragment extends LoaderFragment private String mKeyserver; private CryptoOperationHelper mImportOpHelper; + // for ConsolidateOperation + private CryptoOperationHelper mConsolidateOpHelper; + // This ids for multiple key export. private ArrayList mIdsForRepeatAskPassphrase; // This index for remembering the number of master key. @@ -607,51 +607,35 @@ public class KeyListFragment extends LoaderFragment } private void consolidate() { - // Message is received after importing is done in KeychainService - ServiceProgressHandler saveHandler = new ServiceProgressHandler(getActivity()) { - @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - // get returned data bundle - Bundle returnData = message.getData(); - if (returnData == null) { - return; - } - final ConsolidateResult result = - returnData.getParcelable(OperationResult.EXTRA_RESULT); - if (result == null) { - return; - } - result.createNotify(getActivity()).show(); - } - } - }; + CryptoOperationHelper.Callback callback + = new CryptoOperationHelper.Callback() { - // Send all information needed to service to import key in other thread - Intent intent = new Intent(getActivity(), KeychainService.class); + @Override + public ConsolidateInputParcel createOperationInput() { + return new ConsolidateInputParcel(false); // we want to perform a full consolidate + } - intent.setAction(KeychainService.ACTION_CONSOLIDATE); + @Override + public void onCryptoOperationSuccess(ConsolidateResult result) { + result.createNotify(getActivity()).show(); + } - // fill values for this action - Bundle data = new Bundle(); + @Override + public void onCryptoOperationCancelled() { - intent.putExtra(KeychainService.EXTRA_DATA, data); + } - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); + @Override + public void onCryptoOperationError(ConsolidateResult result) { + result.createNotify(getActivity()).show(); + } + }; - // show progress dialog - saveHandler.showProgressDialog( - getString(R.string.progress_importing), - ProgressDialog.STYLE_HORIZONTAL, false); + mConsolidateOpHelper = + new CryptoOperationHelper<>(this, callback, R.string.progress_importing); - // start service with intent - getActivity().startService(intent); + mConsolidateOpHelper.cryptoOperation(); } private void showMultiExportDialog(long[] masterKeyIds) { @@ -693,6 +677,11 @@ public class KeyListFragment extends LoaderFragment if (mImportOpHelper != null) { mImportOpHelper.handleActivityResult(requestCode, resultCode, data); } + + if (mConsolidateOpHelper != null) { + mConsolidateOpHelper.handleActivityResult(requestCode, resultCode, data); + } + if (requestCode == REQUEST_REPEAT_PASSPHRASE) { if (resultCode != Activity.RESULT_OK) { return; -- cgit v1.2.3 From 2f110344ed37e62320d2ff30ffad6c24315ff179 Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Wed, 24 Jun 2015 06:15:01 +0530 Subject: migrated Keybase verification --- .../keychain/operations/CertifyOperation.java | 9 +- .../operations/KeybaseVerificationOperation.java | 141 +++++++++++++ .../results/KeybaseVerificationResult.java | 59 ++++++ .../operations/results/OperationResult.java | 14 +- .../service/KeybaseVerificationParcel.java | 43 ++++ .../keychain/service/KeychainNewService.java | 8 +- .../keychain/service/KeychainService.java | 180 +---------------- .../keychain/ui/ViewKeyTrustFragment.java | 225 ++++++++++++--------- OpenKeychain/src/main/res/values/strings.xml | 9 + 9 files changed, 403 insertions(+), 285 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/KeybaseVerificationResult.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeybaseVerificationParcel.java (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java index 439260b74..cb76c8ba3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java @@ -58,12 +58,13 @@ import java.util.concurrent.atomic.AtomicBoolean; * @see CertifyActionsParcel * */ -public class CertifyOperation extends BaseOperation { +public class CertifyOperation extends BaseOperation { public CertifyOperation(Context context, ProviderHelper providerHelper, Progressable progressable, AtomicBoolean cancelled) { super(context, providerHelper, progressable, cancelled); } + @Override public CertifyResult execute(CertifyActionsParcel parcel, CryptoInputParcel cryptoInput) { OperationLog log = new OperationLog(); @@ -86,8 +87,10 @@ public class CertifyOperation extends BaseOperation { case PATTERN: case PASSPHRASE: if (!cryptoInput.hasPassphrase()) { - return new CertifyResult(log, RequiredInputParcel.createRequiredSignPassphrase( - certificationKey.getKeyId(), certificationKey.getKeyId(), null)); + return new CertifyResult(log, + RequiredInputParcel.createRequiredSignPassphrase( + certificationKey.getKeyId(), certificationKey.getKeyId(), null) + ); } // certification is always with the master key id, so use that one passphrase = cryptoInput.getPassphrase(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java new file mode 100644 index 000000000..683fc9fa9 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java @@ -0,0 +1,141 @@ +package org.sufficientlysecure.keychain.operations; + +import android.content.Context; +import com.textuality.keybase.lib.Proof; +import com.textuality.keybase.lib.prover.Prover; +import de.measite.minidns.Client; +import de.measite.minidns.DNSMessage; +import de.measite.minidns.Question; +import de.measite.minidns.Record; +import de.measite.minidns.record.Data; +import de.measite.minidns.record.TXT; +import org.json.JSONObject; +import org.spongycastle.openpgp.PGPUtil; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; +import org.sufficientlysecure.keychain.operations.results.KeybaseVerificationResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; +import org.sufficientlysecure.keychain.pgp.Progressable; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.KeybaseVerificationParcel; +import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.util.Log; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +public class KeybaseVerificationOperation extends BaseOperation { + + public KeybaseVerificationOperation(Context context, ProviderHelper providerHelper, + Progressable progressable) { + super(context, providerHelper, progressable); + } + + @Override + public KeybaseVerificationResult execute(KeybaseVerificationParcel keybaseInput, + CryptoInputParcel cryptoInput) { + + String requiredFingerprint = keybaseInput.mRequiredFingerprint; + + OperationResult.OperationLog log = new OperationResult.OperationLog(); + log.add(OperationResult.LogType.MSG_KEYBASE_VERIFICATION, 0, requiredFingerprint); + + try { + String keybaseProof = keybaseInput.mKeybaseProof; + Proof proof = new Proof(new JSONObject(keybaseProof)); + mProgressable.setProgress(R.string.keybase_message_fetching_data, 0, 100); + + Prover prover = Prover.findProverFor(proof); + + if (prover == null) { + log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_NO_PROVER, 1, + proof.getPrettyName()); + return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log); + } + + if (!prover.fetchProofData()) { + log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_FETCH_PROOF, 1); + return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log); + } + + if (!prover.checkFingerprint(requiredFingerprint)) { + log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_FINGERPRINT_MISMATCH, 1); + return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log); + } + + String domain = prover.dnsTxtCheckRequired(); + if (domain != null) { + DNSMessage dnsQuery = new Client().query(new Question(domain, Record.TYPE.TXT)); + if (dnsQuery == null) { + log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_DNS_FAIL, 1); + log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_SPECIFIC, 2, + getFlattenedProverLog(prover)); + return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log); + } + Record[] records = dnsQuery.getAnswers(); + List> extents = new ArrayList>(); + for (Record r : records) { + Data d = r.getPayload(); + if (d instanceof TXT) { + extents.add(((TXT) d).getExtents()); + } + } + if (!prover.checkDnsTxt(extents)) { + log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_SPECIFIC, 1, + getFlattenedProverLog(prover)); + return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log); + } + } + + byte[] messageBytes = prover.getPgpMessage().getBytes(); + if (prover.rawMessageCheckRequired()) { + InputStream messageByteStream = PGPUtil.getDecoderStream(new + ByteArrayInputStream + (messageBytes)); + if (!prover.checkRawMessageBytes(messageByteStream)) { + log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_SPECIFIC, 1, + getFlattenedProverLog(prover)); + return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log); + } + } + + PgpDecryptVerify op = new PgpDecryptVerify(mContext, mProviderHelper, mProgressable); + + PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(messageBytes) + .setSignedLiteralData(true) + .setRequiredSignerFingerprint(requiredFingerprint); + + DecryptVerifyResult decryptVerifyResult = op.execute(input, new CryptoInputParcel()); + + if (!decryptVerifyResult.success()) { + log.add(decryptVerifyResult, 1); + return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log); + } + + if (!prover.validate(new String(decryptVerifyResult.getOutputBytes()))) { + log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_PAYLOAD_MISMATCH, 1); + return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log); + } + + return new KeybaseVerificationResult(OperationResult.RESULT_OK, log, prover); + } catch (Exception e) { + // just adds the passed parameter, in this case e.getMessage() + log.add(OperationResult.LogType.MSG_KEYBASE_ERROR_SPECIFIC, 1, e.getMessage()); + return new KeybaseVerificationResult(OperationResult.RESULT_ERROR, log); + } + } + + private String getFlattenedProverLog(Prover prover) { + String log = ""; + for (String line : prover.getLog()) { + log += line + "\n"; + } + return log; + } +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/KeybaseVerificationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/KeybaseVerificationResult.java new file mode 100644 index 000000000..f4312ae47 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/KeybaseVerificationResult.java @@ -0,0 +1,59 @@ +package org.sufficientlysecure.keychain.operations.results; + +import android.os.Parcel; +import android.os.Parcelable; +import com.textuality.keybase.lib.KeybaseException; +import com.textuality.keybase.lib.prover.Prover; + +public class KeybaseVerificationResult extends OperationResult implements Parcelable { + public final String mProofUrl; + public final String mPresenceUrl; + public final String mPresenceLabel; + + public KeybaseVerificationResult(int result, OperationLog log) { + super(result, log); + mProofUrl = null; + mPresenceLabel = null; + mPresenceUrl = null; + } + + public KeybaseVerificationResult(int result, OperationLog log, Prover prover) + throws KeybaseException { + super(result, log); + mProofUrl = prover.getProofUrl(); + mPresenceUrl = prover.getPresenceUrl(); + mPresenceLabel = prover.getPresenceLabel(); + } + + protected KeybaseVerificationResult(Parcel in) { + super(in); + mProofUrl = in.readString(); + mPresenceUrl = in.readString(); + mPresenceLabel = in.readString(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeString(mProofUrl); + dest.writeString(mPresenceUrl); + dest.writeString(mPresenceLabel); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public KeybaseVerificationResult createFromParcel(Parcel in) { + return new KeybaseVerificationResult(in); + } + + @Override + public KeybaseVerificationResult[] newArray(int size) { + return new KeybaseVerificationResult[size]; + } + }; +} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java index c9e427462..f0561bef2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java @@ -750,7 +750,19 @@ public abstract class OperationResult implements Parcelable { MSG_DEL_OK (LogLevel.OK, R.plurals.msg_del_ok), MSG_DEL_FAIL (LogLevel.WARN, R.plurals.msg_del_fail), - //export log + // keybase verification + MSG_KEYBASE_VERIFICATION(LogLevel.START, R.string.msg_keybase_verification), + + MSG_KEYBASE_ERROR_NO_PROVER(LogLevel.ERROR, R.string.msg_keybase_error_no_prover), + MSG_KEYBASE_ERROR_FETCH_PROOF(LogLevel.ERROR, R.string.msg_keybase_error_fetching_evidence), + MSG_KEYBASE_ERROR_FINGERPRINT_MISMATCH(LogLevel.ERROR, + R.string.msg_keybase_error_key_mismatch), + MSG_KEYBASE_ERROR_DNS_FAIL(LogLevel.ERROR, R.string.msg_keybase_error_dns_fail), + MSG_KEYBASE_ERROR_SPECIFIC(LogLevel.ERROR, R.string.msg_keybase_error_specific), + MSG_KEYBASE_ERROR_PAYLOAD_MISMATCH(LogLevel.ERROR, + R.string.msg_keybase_error_msg_payload_mismatch), + + // export log MSG_EXPORT_LOG(LogLevel.START,R.string.msg_export_log_start), MSG_EXPORT_LOG_EXPORT_ERROR_NO_FILE(LogLevel.ERROR,R.string.msg_export_log_error_no_file), MSG_EXPORT_LOG_EXPORT_ERROR_FOPEN(LogLevel.ERROR,R.string.msg_export_log_error_fopen), diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeybaseVerificationParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeybaseVerificationParcel.java new file mode 100644 index 000000000..866eb84a9 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeybaseVerificationParcel.java @@ -0,0 +1,43 @@ +package org.sufficientlysecure.keychain.service; + +import android.os.Parcel; +import android.os.Parcelable; + +public class KeybaseVerificationParcel implements Parcelable { + + public String mKeybaseProof; + public String mRequiredFingerprint; + + public KeybaseVerificationParcel(String keybaseProof, String requiredFingerprint) { + mKeybaseProof = keybaseProof; + mRequiredFingerprint = requiredFingerprint; + } + + protected KeybaseVerificationParcel(Parcel in) { + mKeybaseProof = in.readString(); + mRequiredFingerprint = in.readString(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(mKeybaseProof); + dest.writeString(mRequiredFingerprint); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public KeybaseVerificationParcel createFromParcel(Parcel in) { + return new KeybaseVerificationParcel(in); + } + + @Override + public KeybaseVerificationParcel[] newArray(int size) { + return new KeybaseVerificationParcel[size]; + } + }; +} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java index 080f6a38f..9998e46a2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java @@ -106,19 +106,23 @@ public class KeychainNewService extends Service implements Progressable { mActionCanceled); } else if (inputParcel instanceof DeleteKeyringParcel) { op = new DeleteOperation(outerThis, new ProviderHelper(outerThis), outerThis); - } else if (inputParcel instanceof PromoteKeyringParcel){ + } else if (inputParcel instanceof PromoteKeyringParcel) { op = new PromoteKeyOperation(outerThis, new ProviderHelper(outerThis), outerThis, mActionCanceled); } else if (inputParcel instanceof ImportKeyringParcel - || inputParcel instanceof ExportKeyringParcel){ + || inputParcel instanceof ExportKeyringParcel) { op = new ImportExportOperation(outerThis, new ProviderHelper(outerThis), outerThis, mActionCanceled); } else if (inputParcel instanceof ConsolidateInputParcel) { op = new ConsolidateOperation(outerThis, new ProviderHelper(outerThis), outerThis); + } else if (inputParcel instanceof KeybaseVerificationParcel) { + op = new KeybaseVerificationOperation(outerThis, new ProviderHelper(outerThis), + outerThis); } else { return; } + @SuppressWarnings("unchecked") // this is unchecked, we make sure it's the correct op above! OperationResult result = op.execute(inputParcel, cryptoInput); sendMessageToHandler(MessageStatus.OKAY, result); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java index 127719ab7..e532982ce 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java @@ -38,14 +38,8 @@ import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; import org.sufficientlysecure.keychain.keyimport.Keyserver; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.*; -import org.sufficientlysecure.keychain.operations.results.ConsolidateResult; -import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; -import org.sufficientlysecure.keychain.operations.results.DeleteResult; -import org.sufficientlysecure.keychain.operations.results.ExportResult; -import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; -import org.sufficientlysecure.keychain.operations.results.OperationResult; +import org.sufficientlysecure.keychain.operations.results.*; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; -import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; @@ -61,14 +55,6 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; - -import de.measite.minidns.Client; -import de.measite.minidns.DNSMessage; -import de.measite.minidns.Question; -import de.measite.minidns.Record; -import de.measite.minidns.record.Data; -import de.measite.minidns.record.TXT; /** * This Service contains all important long lasting operations for OpenKeychain. It receives Intents with @@ -80,28 +66,8 @@ public class KeychainService extends Service implements Progressable { public static final String EXTRA_MESSENGER = "messenger"; public static final String EXTRA_DATA = "data"; - /* possible actions */ - - public static final String ACTION_VERIFY_KEYBASE_PROOF = Constants.INTENT_PREFIX + "VERIFY_KEYBASE_PROOF"; - - public static final String ACTION_CONSOLIDATE = Constants.INTENT_PREFIX + "CONSOLIDATE"; - - public static final String ACTION_CANCEL = Constants.INTENT_PREFIX + "CANCEL"; - - /* keys for data bundle */ - - // keybase proof - public static final String KEYBASE_REQUIRED_FINGERPRINT = "keybase_required_fingerprint"; - public static final String KEYBASE_PROOF = "keybase_proof"; - - // consolidate - public static final String CONSOLIDATE_RECOVERY = "consolidate_recovery"; - Messenger mMessenger; - // this attribute can possibly merged with the one above? not sure... - private AtomicBoolean mActionCanceled = new AtomicBoolean(false); - @Override public IBinder onBind(Intent intent) { return null; @@ -112,150 +78,6 @@ public class KeychainService extends Service implements Progressable { */ @Override public int onStartCommand(final Intent intent, int flags, int startId) { - - if (ACTION_CANCEL.equals(intent.getAction())) { - mActionCanceled.set(true); - return START_NOT_STICKY; - } - - Runnable actionRunnable = new Runnable() { - @Override - public void run() { - // We have not been cancelled! (yet) - mActionCanceled.set(false); - - Bundle extras = intent.getExtras(); - if (extras == null) { - Log.e(Constants.TAG, "Extras bundle is null!"); - return; - } - - if (!(extras.containsKey(EXTRA_MESSENGER) || extras.containsKey(EXTRA_DATA) || (intent - .getAction() == null))) { - Log.e(Constants.TAG, - "Extra bundle must contain a messenger, a data bundle, and an action!"); - return; - } - - Uri dataUri = intent.getData(); - - mMessenger = (Messenger) extras.get(EXTRA_MESSENGER); - Bundle data = extras.getBundle(EXTRA_DATA); - if (data == null) { - Log.e(Constants.TAG, "data extra is null!"); - return; - } - - Log.logDebugBundle(data, "EXTRA_DATA"); - - ProviderHelper providerHelper = new ProviderHelper(KeychainService.this); - - String action = intent.getAction(); - - // executeServiceMethod action from extra bundle - switch (action) { - case ACTION_VERIFY_KEYBASE_PROOF: { - - try { - Proof proof = new Proof(new JSONObject(data.getString(KEYBASE_PROOF))); - setProgress(R.string.keybase_message_fetching_data, 0, 100); - - Prover prover = Prover.findProverFor(proof); - - if (prover == null) { - sendProofError(getString(R.string.keybase_no_prover_found) + ": " + proof - .getPrettyName()); - return; - } - - if (!prover.fetchProofData()) { - sendProofError(prover.getLog(), getString(R.string.keybase_problem_fetching_evidence)); - return; - } - String requiredFingerprint = data.getString(KEYBASE_REQUIRED_FINGERPRINT); - if (!prover.checkFingerprint(requiredFingerprint)) { - sendProofError(getString(R.string.keybase_key_mismatch)); - return; - } - - String domain = prover.dnsTxtCheckRequired(); - if (domain != null) { - DNSMessage dnsQuery = new Client().query(new Question(domain, Record.TYPE.TXT)); - if (dnsQuery == null) { - sendProofError(prover.getLog(), getString(R.string.keybase_dns_query_failure)); - return; - } - Record[] records = dnsQuery.getAnswers(); - List> extents = new ArrayList>(); - for (Record r : records) { - Data d = r.getPayload(); - if (d instanceof TXT) { - extents.add(((TXT) d).getExtents()); - } - } - if (!prover.checkDnsTxt(extents)) { - sendProofError(prover.getLog(), null); - return; - } - } - - byte[] messageBytes = prover.getPgpMessage().getBytes(); - if (prover.rawMessageCheckRequired()) { - InputStream messageByteStream = PGPUtil.getDecoderStream(new ByteArrayInputStream - (messageBytes)); - if (!prover.checkRawMessageBytes(messageByteStream)) { - sendProofError(prover.getLog(), null); - return; - } - } - - PgpDecryptVerify op = new PgpDecryptVerify(KeychainService.this, providerHelper, - KeychainService.this); - - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(messageBytes) - .setSignedLiteralData(true) - .setRequiredSignerFingerprint(requiredFingerprint); - - DecryptVerifyResult decryptVerifyResult = op.execute(input, new CryptoInputParcel()); - - if (!decryptVerifyResult.success()) { - OperationLog log = decryptVerifyResult.getLog(); - OperationResult.LogEntryParcel lastEntry = null; - for (OperationResult.LogEntryParcel entry : log) { - lastEntry = entry; - } - sendProofError(getString(lastEntry.mType.getMsgId())); - return; - } - - if (!prover.validate(new String(decryptVerifyResult.getOutputBytes()))) { - sendProofError(getString(R.string.keybase_message_payload_mismatch)); - return; - } - - Bundle resultData = new Bundle(); - resultData.putString(ServiceProgressHandler.DATA_MESSAGE, "OK"); - - // these help the handler construct a useful human-readable message - resultData.putString(ServiceProgressHandler.KEYBASE_PROOF_URL, prover.getProofUrl()); - resultData.putString(ServiceProgressHandler.KEYBASE_PRESENCE_URL, prover.getPresenceUrl()); - resultData.putString(ServiceProgressHandler.KEYBASE_PRESENCE_LABEL, prover - .getPresenceLabel()); - sendMessageToHandler(MessageStatus.OKAY, resultData); - } catch (Exception e) { - sendErrorToHandler(e); - } - - break; - } - } - stopSelf(); - } - }; - - Thread actionThread = new Thread(actionRunnable); - actionThread.start(); - return START_NOT_STICKY; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java index c33485adc..b196f06e2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java @@ -48,9 +48,12 @@ import com.textuality.keybase.lib.User; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.operations.results.KeybaseVerificationResult; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.service.KeybaseVerificationParcel; import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.Log; @@ -59,7 +62,8 @@ import java.util.Hashtable; import java.util.List; public class ViewKeyTrustFragment extends LoaderFragment implements - LoaderManager.LoaderCallbacks { + LoaderManager.LoaderCallbacks, + CryptoOperationHelper.Callback { public static final String ARG_DATA_URI = "uri"; @@ -76,6 +80,14 @@ public class ViewKeyTrustFragment extends LoaderFragment implements // for retrieving the key we’re working on private Uri mDataUri; + private Proof mProof; + + // for CryptoOperationHelper,Callback + private String mKeybaseProof; + private String mKeybaseFingerprint; + private CryptoOperationHelper + mKeybaseOpHelper; + @Override public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) { View root = super.onCreateView(inflater, superContainer, savedInstanceState); @@ -349,112 +361,125 @@ public class ViewKeyTrustFragment extends LoaderFragment implements } private void verify(final Proof proof, final String fingerprint) { - Intent intent = new Intent(getActivity(), KeychainService.class); - Bundle data = new Bundle(); - intent.setAction(KeychainService.ACTION_VERIFY_KEYBASE_PROOF); - data.putString(KeychainService.KEYBASE_PROOF, proof.toString()); - data.putString(KeychainService.KEYBASE_REQUIRED_FINGERPRINT, fingerprint); - intent.putExtra(KeychainService.EXTRA_DATA, data); + mProof = proof; + mKeybaseProof = proof.toString(); + mKeybaseFingerprint = fingerprint; mProofVerifyDetail.setVisibility(View.GONE); - // Create a new Messenger for the communication back after proof work is done - ServiceProgressHandler handler = new ServiceProgressHandler(getActivity()) { - @Override - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == MessageStatus.OKAY.ordinal()) { - Bundle returnData = message.getData(); - String msg = returnData.getString(ServiceProgressHandler.DATA_MESSAGE); - SpannableStringBuilder ssb = new SpannableStringBuilder(); - - if ((msg != null) && msg.equals("OK")) { - - //yay - String proofUrl = returnData.getString(ServiceProgressHandler.KEYBASE_PROOF_URL); - String presenceUrl = returnData.getString(ServiceProgressHandler.KEYBASE_PRESENCE_URL); - String presenceLabel = returnData.getString(ServiceProgressHandler.KEYBASE_PRESENCE_LABEL); - - String proofLabel; - switch (proof.getType()) { - case Proof.PROOF_TYPE_TWITTER: - proofLabel = getString(R.string.keybase_twitter_proof); - break; - case Proof.PROOF_TYPE_DNS: - proofLabel = getString(R.string.keybase_dns_proof); - break; - case Proof.PROOF_TYPE_WEB_SITE: - proofLabel = getString(R.string.keybase_web_site_proof); - break; - case Proof.PROOF_TYPE_GITHUB: - proofLabel = getString(R.string.keybase_github_proof); - break; - case Proof.PROOF_TYPE_REDDIT: - proofLabel = getString(R.string.keybase_reddit_proof); - break; - default: - proofLabel = getString(R.string.keybase_a_post); - break; - } + mKeybaseOpHelper = new CryptoOperationHelper<>(this, this, + R.string.progress_verifying_signature); + mKeybaseOpHelper.cryptoOperation(); + } - ssb.append(getString(R.string.keybase_proof_succeeded)); - StyleSpan bold = new StyleSpan(Typeface.BOLD); - ssb.setSpan(bold, 0, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - ssb.append("\n\n"); - int length = ssb.length(); - ssb.append(proofLabel); - if (proofUrl != null) { - URLSpan postLink = new URLSpan(proofUrl); - ssb.setSpan(postLink, length, length + proofLabel.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - } - if (Proof.PROOF_TYPE_DNS == proof.getType()) { - ssb.append(" ").append(getString(R.string.keybase_for_the_domain)).append(" "); - } else { - ssb.append(" ").append(getString(R.string.keybase_fetched_from)).append(" "); - } - length = ssb.length(); - URLSpan presenceLink = new URLSpan(presenceUrl); - ssb.append(presenceLabel); - ssb.setSpan(presenceLink, length, length + presenceLabel.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - if (Proof.PROOF_TYPE_REDDIT == proof.getType()) { - ssb.append(", "). - append(getString(R.string.keybase_reddit_attribution)). - append(" “").append(proof.getHandle()).append("”, "); - } - ssb.append(" ").append(getString(R.string.keybase_contained_signature)); - } else { - // verification failed! - msg = returnData.getString(ServiceProgressHandler.DATA_ERROR); - ssb.append(getString(R.string.keybase_proof_failure)); - if (msg == null) { - msg = getString(R.string.keybase_unknown_proof_failure); - } - StyleSpan bold = new StyleSpan(Typeface.BOLD); - ssb.setSpan(bold, 0, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - ssb.append("\n\n").append(msg); - } - mProofVerifyHeader.setVisibility(View.VISIBLE); - mProofVerifyDetail.setVisibility(View.VISIBLE); - mProofVerifyDetail.setMovementMethod(LinkMovementMethod.getInstance()); - mProofVerifyDetail.setText(ssb); - } - } - }; + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (mKeybaseOpHelper != null) { + mKeybaseOpHelper.handleActivityResult(requestCode, resultCode, data); + } + } - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(handler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); + // CryptoOperationHelper.Callback methods + @Override + public KeybaseVerificationParcel createOperationInput() { + return new KeybaseVerificationParcel(mKeybaseProof, mKeybaseFingerprint); + } - // show progress dialog - handler.showProgressDialog( - getString(R.string.progress_verifying_signature), - ProgressDialog.STYLE_HORIZONTAL, false - ); + @Override + public void onCryptoOperationSuccess(KeybaseVerificationResult result) { + + result.createNotify(getActivity()).show(); + + String proofUrl = result.mProofUrl; + String presenceUrl = result.mPresenceUrl; + String presenceLabel = result.mPresenceLabel; + + Proof proof = mProof; // TODO: should ideally be contained in result + + String proofLabel; + switch (proof.getType()) { + case Proof.PROOF_TYPE_TWITTER: + proofLabel = getString(R.string.keybase_twitter_proof); + break; + case Proof.PROOF_TYPE_DNS: + proofLabel = getString(R.string.keybase_dns_proof); + break; + case Proof.PROOF_TYPE_WEB_SITE: + proofLabel = getString(R.string.keybase_web_site_proof); + break; + case Proof.PROOF_TYPE_GITHUB: + proofLabel = getString(R.string.keybase_github_proof); + break; + case Proof.PROOF_TYPE_REDDIT: + proofLabel = getString(R.string.keybase_reddit_proof); + break; + default: + proofLabel = getString(R.string.keybase_a_post); + break; + } + + SpannableStringBuilder ssb = new SpannableStringBuilder(); + + ssb.append(getString(R.string.keybase_proof_succeeded)); + StyleSpan bold = new StyleSpan(Typeface.BOLD); + ssb.setSpan(bold, 0, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + ssb.append("\n\n"); + int length = ssb.length(); + ssb.append(proofLabel); + if (proofUrl != null) { + URLSpan postLink = new URLSpan(proofUrl); + ssb.setSpan(postLink, length, length + proofLabel.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + if (Proof.PROOF_TYPE_DNS == proof.getType()) { + ssb.append(" ").append(getString(R.string.keybase_for_the_domain)).append(" "); + } else { + ssb.append(" ").append(getString(R.string.keybase_fetched_from)).append(" "); + } + length = ssb.length(); + URLSpan presenceLink = new URLSpan(presenceUrl); + ssb.append(presenceLabel); + ssb.setSpan(presenceLink, length, length + presenceLabel.length(), Spanned + .SPAN_EXCLUSIVE_EXCLUSIVE); + if (Proof.PROOF_TYPE_REDDIT == proof.getType()) { + ssb.append(", "). + append(getString(R.string.keybase_reddit_attribution)). + append(" “").append(proof.getHandle()).append("”, "); + } + ssb.append(" ").append(getString(R.string.keybase_contained_signature)); + + displaySpannableResult(ssb); + } + + @Override + public void onCryptoOperationCancelled() { + + } + + @Override + public void onCryptoOperationError(KeybaseVerificationResult result) { + + result.createNotify(getActivity()).show(); + + SpannableStringBuilder ssb = new SpannableStringBuilder(); + + ssb.append(getString(R.string.keybase_proof_failure)); + String msg = getString(result.getLog().getLast().mType.mMsgId); + if (msg == null) { + msg = getString(R.string.keybase_unknown_proof_failure); + } + StyleSpan bold = new StyleSpan(Typeface.BOLD); + ssb.setSpan(bold, 0, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + ssb.append("\n\n").append(msg); + + displaySpannableResult(ssb); + } - // start service with intent - getActivity().startService(intent); + private void displaySpannableResult(SpannableStringBuilder ssb) { + mProofVerifyHeader.setVisibility(View.VISIBLE); + mProofVerifyDetail.setVisibility(View.VISIBLE); + mProofVerifyDetail.setMovementMethod(LinkMovementMethod.getInstance()); + mProofVerifyDetail.setText(ssb); } } diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 3c8c7a22b..28bdd78fb 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -1213,6 +1213,15 @@ "An error occurred when searching for keys." + + "Attempting keybase verification for %s" + "No proof checker found for %s" + "Problem with fetching proof" + "Key fingerprint doesn’t match that in proof post" + "DNS TXT Record retrieval failed" + "%s" + "Decrypted proof post does not match expected value" + "Exporting log" "Error opening file" -- cgit v1.2.3 From 0012db1f6d5e7a80ea22b6f4577d70d13ec6fc96 Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Wed, 24 Jun 2015 06:30:47 +0530 Subject: deleted KeychainService --- OpenKeychain/src/main/AndroidManifest.xml | 3 - .../keychain/service/KeychainNewService.java | 7 + .../keychain/service/KeychainService.java | 184 ------------------ .../keychain/ui/CertifyKeyFragment.java | 7 - .../keychain/ui/CreateKeyFinalFragment.java | 7 - .../ui/CreateKeyYubiKeyImportFragment.java | 6 - .../keychain/ui/DecryptFilesFragment.java | 216 +++++++++++++++++++++ .../keychain/ui/DecryptFragment.java | 5 +- .../keychain/ui/EditKeyFragment.java | 14 +- .../keychain/ui/SafeSlingerActivity.java | 6 - .../keychain/ui/UploadKeyActivity.java | 1 - .../keychain/ui/ViewKeyActivity.java | 5 +- .../keychain/ui/ViewKeyTrustFragment.java | 5 - .../keychain/ui/ViewKeyYubiKeyFragment.java | 7 - .../keychain/ui/base/CryptoOperationHelper.java | 3 +- .../ui/dialog/DeleteKeyDialogFragment.java | 3 - .../keychain/ui/dialog/ProgressDialogFragment.java | 6 +- .../keychain/util/EmailKeyHelper.java | 6 - .../keychain/util/ExportHelper.java | 7 - 19 files changed, 236 insertions(+), 262 deletions(-) delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index d5db3c2da..8e416f387 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -713,9 +713,6 @@ - - * Copyright (C) 2014 Vincent Breitmoser - * - * 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 . - */ - -package org.sufficientlysecure.keychain.service; - -import android.app.Service; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.os.IBinder; -import android.os.Message; -import android.os.Messenger; -import android.os.RemoteException; - -import com.textuality.keybase.lib.Proof; -import com.textuality.keybase.lib.prover.Prover; - -import org.json.JSONObject; -import org.spongycastle.openpgp.PGPUtil; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; -import org.sufficientlysecure.keychain.keyimport.Keyserver; -import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; -import org.sufficientlysecure.keychain.operations.*; -import org.sufficientlysecure.keychain.operations.results.*; -import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; -import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; -import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; -import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; -import org.sufficientlysecure.keychain.pgp.Progressable; -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException; -import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus; -import org.sufficientlysecure.keychain.util.Log; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - -/** - * This Service contains all important long lasting operations for OpenKeychain. It receives Intents with - * data from the activities or other apps, executes them, and stops itself after doing them. - */ -public class KeychainService extends Service implements Progressable { - - /* extras that can be given by intent */ - public static final String EXTRA_MESSENGER = "messenger"; - public static final String EXTRA_DATA = "data"; - - Messenger mMessenger; - - @Override - public IBinder onBind(Intent intent) { - return null; - } - - /** - * This is run on the main thread, we need to spawn a runnable which runs on another thread for the actual operation - */ - @Override - public int onStartCommand(final Intent intent, int flags, int startId) { - return START_NOT_STICKY; - } - - private void sendProofError(List log, String label) { - String msg = null; - label = (label == null) ? "" : label + ": "; - for (String m : log) { - Log.e(Constants.TAG, label + m); - msg = m; - } - sendProofError(label + msg); - } - - private void sendProofError(String msg) { - Bundle bundle = new Bundle(); - bundle.putString(ServiceProgressHandler.DATA_ERROR, msg); - sendMessageToHandler(MessageStatus.OKAY, bundle); - } - - private void sendErrorToHandler(Exception e) { - // TODO: Implement a better exception handling here - // contextualize the exception, if necessary - String message; - if (e instanceof PgpGeneralMsgIdException) { - e = ((PgpGeneralMsgIdException) e).getContextualized(KeychainService.this); - message = e.getMessage(); - } else { - message = e.getMessage(); - } - Log.d(Constants.TAG, "KeychainService Exception: ", e); - - Bundle data = new Bundle(); - data.putString(ServiceProgressHandler.DATA_ERROR, message); - sendMessageToHandler(MessageStatus.EXCEPTION, null, data); - } - - private void sendMessageToHandler(MessageStatus status, Integer arg2, Bundle data) { - - Message msg = Message.obtain(); - assert msg != null; - msg.arg1 = status.ordinal(); - if (arg2 != null) { - msg.arg2 = arg2; - } - if (data != null) { - msg.setData(data); - } - - try { - mMessenger.send(msg); - } catch (RemoteException e) { - Log.w(Constants.TAG, "Exception sending message, Is handler present?", e); - } catch (NullPointerException e) { - Log.w(Constants.TAG, "Messenger is null!", e); - } - } - - private void sendMessageToHandler(MessageStatus status, OperationResult data) { - Bundle bundle = new Bundle(); - bundle.putParcelable(OperationResult.EXTRA_RESULT, data); - sendMessageToHandler(status, null, bundle); - } - - private void sendMessageToHandler(MessageStatus status, Bundle data) { - sendMessageToHandler(status, null, data); - } - - private void sendMessageToHandler(MessageStatus status) { - sendMessageToHandler(status, null, null); - } - - /** - * Set progress of ProgressDialog by sending message to handler on UI thread - */ - @Override - public void setProgress(String message, int progress, int max) { - Log.d(Constants.TAG, "Send message by setProgress with progress=" + progress + ", max=" - + max); - - Bundle data = new Bundle(); - if (message != null) { - data.putString(ServiceProgressHandler.DATA_MESSAGE, message); - } - data.putInt(ServiceProgressHandler.DATA_PROGRESS, progress); - data.putInt(ServiceProgressHandler.DATA_PROGRESS_MAX, max); - - sendMessageToHandler(MessageStatus.UPDATE_PROGRESS, null, data); - } - - @Override - public void setProgress(int resourceId, int progress, int max) { - setProgress(getString(resourceId), progress, max); - } - - @Override - public void setProgress(int progress, int max) { - setProgress(null, progress, max); - } - - @Override - public void setPreventCancel() { - sendMessageToHandler(MessageStatus.PREVENT_CANCEL); - } -} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java index e39a3a0bf..c92ee10df 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java @@ -19,15 +19,12 @@ package org.sufficientlysecure.keychain.ui; import android.app.Activity; -import android.app.ProgressDialog; import android.content.Intent; import android.database.Cursor; import android.database.MatrixCursor; import android.graphics.PorterDuff; import android.net.Uri; import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; import android.os.Parcel; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; @@ -52,15 +49,11 @@ import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.CertifyActionsParcel; import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction; -import org.sufficientlysecure.keychain.service.KeychainService; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; -import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.ui.adapter.MultiUserIdsAdapter; import org.sufficientlysecure.keychain.ui.base.CachingCryptoOperationFragment; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.widget.CertifyKeySpinner; import org.sufficientlysecure.keychain.util.Log; -import org.sufficientlysecure.keychain.util.Preferences; import java.util.ArrayList; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java index 1a5c3cd96..1cf4b5a56 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -18,12 +18,9 @@ package org.sufficientlysecure.keychain.ui; import android.app.Activity; -import android.app.ProgressDialog; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -31,7 +28,6 @@ import android.widget.CheckBox; import android.widget.TextView; import org.spongycastle.bcpg.sig.KeyFlags; -import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.EditKeyResult; import org.sufficientlysecure.keychain.operations.results.ExportResult; @@ -39,15 +35,12 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.service.ExportKeyringParcel; -import org.sufficientlysecure.keychain.service.KeychainService; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; -import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Preferences; import java.util.Iterator; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java index ff0ebf7d3..f9ddd9e73 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java @@ -22,11 +22,8 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import android.app.Activity; -import android.app.ProgressDialog; import android.content.Intent; import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; @@ -37,12 +34,9 @@ import android.widget.TextView; import org.spongycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; -import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; -import org.sufficientlysecure.keychain.service.KeychainService; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.NfcListenerFragment; import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java new file mode 100644 index 000000000..fcad560ad --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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 . + */ + +package org.sufficientlysecure.keychain.ui; + +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.TextView; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; +import org.sufficientlysecure.keychain.ui.util.Notify; +import org.sufficientlysecure.keychain.util.FileHelper; + +import java.io.File; + +public class DecryptFilesFragment extends DecryptFragment { + public static final String ARG_URI = "uri"; + public static final String ARG_OPEN_DIRECTLY = "open_directly"; + + private static final int REQUEST_CODE_INPUT = 0x00007003; + private static final int REQUEST_CODE_OUTPUT = 0x00007007; + + // view + private TextView mFilename; + private CheckBox mDeleteAfter; + private View mDecryptButton; + + // model + private Uri mInputUri = null; + private Uri mOutputUri = null; + + /** + * Creates new instance of this fragment + */ + public static DecryptFilesFragment newInstance(Uri uri, boolean openDirectly) { + DecryptFilesFragment frag = new DecryptFilesFragment(); + + Bundle args = new Bundle(); + args.putParcelable(ARG_URI, uri); + args.putBoolean(ARG_OPEN_DIRECTLY, openDirectly); + + frag.setArguments(args); + + return frag; + } + + /** + * Inflate the layout for this fragment + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.decrypt_files_fragment, container, false); + + mFilename = (TextView) view.findViewById(R.id.decrypt_files_filename); + mDeleteAfter = (CheckBox) view.findViewById(R.id.decrypt_files_delete_after_decryption); + mDecryptButton = view.findViewById(R.id.decrypt_files_action_decrypt); + view.findViewById(R.id.decrypt_files_browse).setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + FileHelper.openDocument(DecryptFilesFragment.this, "*/*", REQUEST_CODE_INPUT); + } else { + FileHelper.openFile(DecryptFilesFragment.this, mInputUri, "*/*", + REQUEST_CODE_INPUT); + } + } + }); + mDecryptButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + decryptAction(); + } + }); + + return view; + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + + outState.putParcelable(ARG_URI, mInputUri); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + Bundle state = savedInstanceState != null ? savedInstanceState : getArguments(); + setInputUri(state.getParcelable(ARG_URI)); + + // should only come from args + if (state.getBoolean(ARG_OPEN_DIRECTLY, false)) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + FileHelper.openDocument(DecryptFilesFragment.this, "*/*", REQUEST_CODE_INPUT); + } else { + FileHelper.openFile(DecryptFilesFragment.this, mInputUri, "*/*", REQUEST_CODE_INPUT); + } + } + } + + private void setInputUri(Uri inputUri) { + if (inputUri == null) { + mInputUri = null; + mFilename.setText(""); + return; + } + + mInputUri = inputUri; + mFilename.setText(FileHelper.getFilename(getActivity(), mInputUri)); + } + + private void decryptAction() { + if (mInputUri == null) { + Notify.create(getActivity(), R.string.no_file_selected, Notify.Style.ERROR).show(); + return; + } + + cryptoOperation(); + } + + private String removeEncryptedAppend(String name) { + if (name.endsWith(Constants.FILE_EXTENSION_ASC) + || name.endsWith(Constants.FILE_EXTENSION_PGP_MAIN) + || name.endsWith(Constants.FILE_EXTENSION_PGP_ALTERNATE)) { + return name.substring(0, name.length() - 4); + } + return name; + } + + private void askForOutputFilename(String originalFilename) { + if (TextUtils.isEmpty(originalFilename)) { + originalFilename = removeEncryptedAppend(FileHelper.getFilename(getActivity(), mInputUri)); + } + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { + File file = new File(mInputUri.getPath()); + File parentDir = file.exists() ? file.getParentFile() : Constants.Path.APP_DIR; + File targetFile = new File(parentDir, originalFilename); + FileHelper.saveFile(this, getString(R.string.title_decrypt_to_file), + getString(R.string.specify_file_to_decrypt_to), targetFile, REQUEST_CODE_OUTPUT); + } else { + FileHelper.saveDocument(this, "*/*", originalFilename, REQUEST_CODE_OUTPUT); + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case REQUEST_CODE_INPUT: { + if (resultCode == Activity.RESULT_OK && data != null) { + setInputUri(data.getData()); + } + return; + } + + case REQUEST_CODE_OUTPUT: { + // This happens after output file was selected, so start our operation + if (resultCode == Activity.RESULT_OK && data != null) { + mOutputUri = data.getData(); + cryptoOperation(); + } + return; + } + + default: { + super.onActivityResult(requestCode, resultCode, data); + } + } + } + + @Override + protected void onVerifyLoaded(boolean hideErrorOverlay) { + + } + + @Override + protected PgpDecryptVerifyInputParcel createOperationInput() { + return new PgpDecryptVerifyInputParcel(mInputUri, mOutputUri).setAllowSymmetricDecryption(true); + } + + @Override + protected void onCryptoOperationSuccess(DecryptVerifyResult result) { + + // display signature result in activity + loadVerifyResult(result); + + // TODO delete after decrypt not implemented! + + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java index ae5c86451..9cfe1651c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java @@ -17,7 +17,6 @@ package org.sufficientlysecure.keychain.ui; -import java.lang.reflect.Array; import java.util.ArrayList; import android.app.Activity; @@ -47,15 +46,13 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; -import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; -import org.sufficientlysecure.keychain.service.KeychainService; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.ui.base.CachingCryptoOperationFragment; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index 48aa3016d..2cd916544 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -18,7 +18,6 @@ package org.sufficientlysecure.keychain.ui; import android.app.Activity; -import android.app.ProgressDialog; import android.content.Intent; import android.database.Cursor; import android.net.Uri; @@ -26,7 +25,6 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Messenger; -import android.os.Parcelable; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; @@ -40,9 +38,6 @@ import android.widget.ListView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; -import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; -import org.sufficientlysecure.keychain.operations.results.EditKeyResult; -import org.sufficientlysecure.keychain.operations.results.InputPendingResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.SingletonResult; @@ -54,8 +49,6 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException; -import org.sufficientlysecure.keychain.service.KeychainService; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange; @@ -65,7 +58,12 @@ import org.sufficientlysecure.keychain.ui.adapter.SubkeysAddedAdapter; import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter; import org.sufficientlysecure.keychain.ui.adapter.UserIdsAddedAdapter; import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; -import org.sufficientlysecure.keychain.ui.dialog.*; +import org.sufficientlysecure.keychain.ui.dialog.AddSubkeyDialogFragment; +import org.sufficientlysecure.keychain.ui.dialog.AddUserIdDialogFragment; +import org.sufficientlysecure.keychain.ui.dialog.EditSubkeyDialogFragment; +import org.sufficientlysecure.keychain.ui.dialog.EditSubkeyExpiryDialogFragment; +import org.sufficientlysecure.keychain.ui.dialog.EditUserIdDialogFragment; +import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Passphrase; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java index 97c44aabf..240dbe7ad 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java @@ -18,15 +18,11 @@ package org.sufficientlysecure.keychain.ui; import android.annotation.TargetApi; -import android.app.ProgressDialog; import android.content.Intent; import android.graphics.PorterDuff; import android.net.Uri; import android.os.Build; import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; -import android.support.v4.app.FragmentActivity; import android.view.View; import android.widget.ImageView; import android.widget.NumberPicker; @@ -39,9 +35,7 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; -import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.ui.base.BaseActivity; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.Log; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java index 554aa43a8..a4215c67d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java @@ -34,7 +34,6 @@ import org.sufficientlysecure.keychain.operations.results.ExportResult; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.service.ExportKeyringParcel; -import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.ui.base.BaseActivity; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.util.Log; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 62ee89207..5360058f7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -66,7 +66,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; -import org.sufficientlysecure.keychain.service.KeychainService; +import org.sufficientlysecure.keychain.service.KeychainNewService; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus; import org.sufficientlysecure.keychain.service.PassphraseCacheService; @@ -87,7 +87,6 @@ import org.sufficientlysecure.keychain.util.NfcHelper; import org.sufficientlysecure.keychain.util.Preferences; import java.io.IOException; -import java.lang.reflect.Array; import java.util.ArrayList; import java.util.HashMap; @@ -428,7 +427,7 @@ public class ViewKeyActivity extends BaseNfcActivity implements }; // Create a new Messenger for the communication back Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); + intent.putExtra(KeychainNewService.EXTRA_MESSENGER, messenger); startActivityForResult(intent, 0); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java index b196f06e2..03f8ca447 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java @@ -17,15 +17,12 @@ package org.sufficientlysecure.keychain.ui; -import android.app.ProgressDialog; import android.content.Intent; import android.database.Cursor; import android.graphics.Typeface; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; @@ -51,8 +48,6 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.KeybaseVerificationResult; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.service.KeybaseVerificationParcel; -import org.sufficientlysecure.keychain.service.KeychainService; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.Log; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java index c2db5e018..10ce679f6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java @@ -21,12 +21,8 @@ package org.sufficientlysecure.keychain.ui; import java.nio.ByteBuffer; import java.util.Arrays; -import android.content.Intent; import android.database.Cursor; import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; -import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; @@ -39,13 +35,10 @@ import android.widget.TextView; import org.spongycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; -import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.service.PromoteKeyringParcel; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java index a9002cf4a..38f313d23 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java @@ -34,7 +34,6 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.InputPendingResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.service.KeychainNewService; -import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; @@ -268,7 +267,7 @@ public class CryptoOperationHelper Date: Wed, 24 Jun 2015 07:06:54 +0530 Subject: fixed Certify op --- .../org/sufficientlysecure/keychain/service/KeychainNewService.java | 4 ++-- .../keychain/ui/base/CachingCryptoOperationFragment.java | 3 ++- .../sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java | 1 - 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java index ee1431276..5aa72fda2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java @@ -75,7 +75,7 @@ public class KeychainNewService extends Service implements Progressable { @Override public int onStartCommand(final Intent intent, int flags, int startId) { - if (intent.getAction().equals(ACTION_CANCEL)) { + if (intent.getAction() != null && intent.getAction().equals(ACTION_CANCEL)) { mActionCanceled.set(true); return START_NOT_STICKY; } @@ -108,7 +108,7 @@ public class KeychainNewService extends Service implements Progressable { } else if (inputParcel instanceof SaveKeyringParcel) { op = new EditKeyOperation(outerThis, new ProviderHelper(outerThis), outerThis, mActionCanceled); - } else if (inputParcel instanceof CertifyAction) { + } else if (inputParcel instanceof CertifyActionsParcel) { op = new CertifyOperation(outerThis, new ProviderHelper(outerThis), outerThis, mActionCanceled); } else if (inputParcel instanceof DeleteKeyringParcel) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java index 87c6ee3ca..b451689b1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java @@ -31,11 +31,12 @@ public abstract class CachingCryptoOperationFragment Date: Wed, 24 Jun 2015 07:27:33 +0530 Subject: removed debug logs, added licenses --- .../keychain/operations/ConsolidateOperation.java | 19 +++++++ .../operations/KeybaseVerificationOperation.java | 23 ++++++-- .../results/KeybaseVerificationResult.java | 19 +++++++ .../keychain/service/ConsolidateInputParcel.java | 19 +++++++ .../keychain/service/DeleteKeyringParcel.java | 63 ++++++++++++++++++++++ .../keychain/service/ExportKeyringParcel.java | 19 +++++++ .../keychain/service/ImportExportParcel.java | 19 +++++++ .../service/KeybaseVerificationParcel.java | 19 +++++++ .../keychain/service/KeychainNewService.java | 17 +++--- .../keychain/service/PromoteKeyringParcel.java | 19 +++++++ .../service/input/DeleteKeyringParcel.java | 44 --------------- .../keychain/ui/KeyListFragment.java | 5 +- .../ui/base/CachingCryptoOperationFragment.java | 2 +- .../keychain/ui/base/CryptoOperationHelper.java | 9 ++-- 14 files changed, 234 insertions(+), 62 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/DeleteKeyringParcel.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/DeleteKeyringParcel.java (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ConsolidateOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ConsolidateOperation.java index 780301dd9..bda574e0a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ConsolidateOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ConsolidateOperation.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2015 Dominik Schürmann + * Copyright (C) 2015 Vincent Breitmoser + * Copyright (C) 2015 Adithya Abraham Philip + * + * 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 . + */ + package org.sufficientlysecure.keychain.operations; import android.content.Context; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java index 683fc9fa9..57b99951d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java @@ -1,6 +1,26 @@ +/* + * Copyright (C) 2015 Dominik Schürmann + * Copyright (C) 2015 Vincent Breitmoser + * Copyright (C) 2015 Adithya Abraham Philip + * + * 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 . + */ + package org.sufficientlysecure.keychain.operations; import android.content.Context; + import com.textuality.keybase.lib.Proof; import com.textuality.keybase.lib.prover.Prover; import de.measite.minidns.Client; @@ -11,7 +31,6 @@ import de.measite.minidns.record.Data; import de.measite.minidns.record.TXT; import org.json.JSONObject; import org.spongycastle.openpgp.PGPUtil; -import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; import org.sufficientlysecure.keychain.operations.results.KeybaseVerificationResult; @@ -21,9 +40,7 @@ import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeybaseVerificationParcel; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; -import org.sufficientlysecure.keychain.util.Log; import java.io.ByteArrayInputStream; import java.io.InputStream; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/KeybaseVerificationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/KeybaseVerificationResult.java index f4312ae47..420cbbf01 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/KeybaseVerificationResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/KeybaseVerificationResult.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2015 Dominik Schürmann + * Copyright (C) 2015 Vincent Breitmoser + * Copyright (C) 2015 Adithya Abraham Philip + * + * 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 . + */ + package org.sufficientlysecure.keychain.operations.results; import android.os.Parcel; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ConsolidateInputParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ConsolidateInputParcel.java index d2ab18c0f..15d109814 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ConsolidateInputParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ConsolidateInputParcel.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2015 Dominik Schürmann + * Copyright (C) 2015 Vincent Breitmoser + * Copyright (C) 2015 Adithya Abraham Philip + * + * 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 . + */ + package org.sufficientlysecure.keychain.service; import android.os.Parcel; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/DeleteKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/DeleteKeyringParcel.java new file mode 100644 index 000000000..b412a6e2b --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/DeleteKeyringParcel.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2015 Dominik Schürmann + * Copyright (C) 2015 Vincent Breitmoser + * Copyright (C) 2015 Adithya Abraham Philip + * + * 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 . + */ + +package org.sufficientlysecure.keychain.service; + +import android.os.Parcel; +import android.os.Parcelable; + +public class DeleteKeyringParcel implements Parcelable { + + public long[] mMasterKeyIds; + public boolean mIsSecret; + + public DeleteKeyringParcel(long[] masterKeyIds, boolean isSecret) { + mMasterKeyIds = masterKeyIds; + mIsSecret = isSecret; + } + + protected DeleteKeyringParcel(Parcel in) { + mIsSecret = in.readByte() != 0x00; + mMasterKeyIds = in.createLongArray(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeByte((byte) (mIsSecret ? 0x01 : 0x00)); + dest.writeLongArray(mMasterKeyIds); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public DeleteKeyringParcel createFromParcel(Parcel in) { + return new DeleteKeyringParcel(in); + } + + @Override + public DeleteKeyringParcel[] newArray(int size) { + return new DeleteKeyringParcel[size]; + } + }; +} + diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ExportKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ExportKeyringParcel.java index 8e9fa9466..236f7f0e3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ExportKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ExportKeyringParcel.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2015 Dominik Schürmann + * Copyright (C) 2015 Vincent Breitmoser + * Copyright (C) 2015 Adithya Abraham Philip + * + * 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 . + */ + package org.sufficientlysecure.keychain.service; import android.net.Uri; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportExportParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportExportParcel.java index 286741317..2e14cc6b6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportExportParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportExportParcel.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2015 Dominik Schürmann + * Copyright (C) 2015 Vincent Breitmoser + * Copyright (C) 2015 Adithya Abraham Philip + * + * 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 . + */ + package org.sufficientlysecure.keychain.service; import android.os.Parcel; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeybaseVerificationParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeybaseVerificationParcel.java index 866eb84a9..1872191af 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeybaseVerificationParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeybaseVerificationParcel.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2015 Dominik Schürmann + * Copyright (C) 2015 Vincent Breitmoser + * Copyright (C) 2015 Adithya Abraham Philip + * + * 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 . + */ + package org.sufficientlysecure.keychain.service; import android.os.Parcel; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java index 5aa72fda2..2bf31e471 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java @@ -18,9 +18,6 @@ package org.sufficientlysecure.keychain.service; - -import java.util.concurrent.atomic.AtomicBoolean; - import android.app.Service; import android.content.Intent; import android.os.Bundle; @@ -31,19 +28,27 @@ import android.os.Parcelable; import android.os.RemoteException; import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.operations.*; +import org.sufficientlysecure.keychain.operations.BaseOperation; +import org.sufficientlysecure.keychain.operations.CertifyOperation; +import org.sufficientlysecure.keychain.operations.ConsolidateOperation; +import org.sufficientlysecure.keychain.operations.DeleteOperation; +import org.sufficientlysecure.keychain.operations.EditKeyOperation; +import org.sufficientlysecure.keychain.operations.ImportExportOperation; +import org.sufficientlysecure.keychain.operations.KeybaseVerificationOperation; +import org.sufficientlysecure.keychain.operations.PromoteKeyOperation; +import org.sufficientlysecure.keychain.operations.SignEncryptOperation; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction; import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; -import org.sufficientlysecure.keychain.service.input.DeleteKeyringParcel; import org.sufficientlysecure.keychain.util.Log; +import java.util.concurrent.atomic.AtomicBoolean; + /** * This Service contains all important long lasting operations for OpenKeychain. It receives Intents with * data from the activities or other apps, executes them, and stops itself after doing them. diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PromoteKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PromoteKeyringParcel.java index dc8c51c19..d268c3694 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PromoteKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PromoteKeyringParcel.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2015 Dominik Schürmann + * Copyright (C) 2015 Vincent Breitmoser + * Copyright (C) 2015 Adithya Abraham Philip + * + * 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 . + */ + package org.sufficientlysecure.keychain.service; import android.os.Parcel; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/DeleteKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/DeleteKeyringParcel.java deleted file mode 100644 index cb61921e1..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/DeleteKeyringParcel.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.sufficientlysecure.keychain.service.input; - -import android.os.Parcel; -import android.os.Parcelable; - -public class DeleteKeyringParcel implements Parcelable { - - public long[] mMasterKeyIds; - public boolean mIsSecret; - - public DeleteKeyringParcel(long[] masterKeyIds, boolean isSecret) { - mMasterKeyIds = masterKeyIds; - mIsSecret = isSecret; - } - - protected DeleteKeyringParcel(Parcel in) { - mIsSecret = in.readByte() != 0x00; - mMasterKeyIds = in.createLongArray(); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeByte((byte) (mIsSecret ? 0x01 : 0x00)); - dest.writeLongArray(mMasterKeyIds); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - @Override - public DeleteKeyringParcel createFromParcel(Parcel in) { - return new DeleteKeyringParcel(in); - } - - @Override - public DeleteKeyringParcel[] newArray(int size) { - return new DeleteKeyringParcel[size]; - } - }; -} - diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 379f4c6b9..d80e3db39 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -21,7 +21,6 @@ package org.sufficientlysecure.keychain.ui; import android.animation.ObjectAnimator; import android.annotation.TargetApi; import android.app.Activity; -import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.database.Cursor; @@ -64,7 +63,9 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.service.*; +import org.sufficientlysecure.keychain.service.ConsolidateInputParcel; +import org.sufficientlysecure.keychain.service.ImportKeyringParcel; +import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java index b451689b1..0f9601153 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java @@ -31,7 +31,7 @@ public abstract class CachingCryptoOperationFragment Date: Wed, 24 Jun 2015 07:37:50 +0530 Subject: renamed KeychainNewService to KeychainService --- OpenKeychain/src/main/AndroidManifest.xml | 2 +- .../keychain/service/KeychainNewService.java | 215 --------------------- .../keychain/service/KeychainService.java | 215 +++++++++++++++++++++ .../keychain/ui/ViewKeyActivity.java | 4 +- .../keychain/ui/base/CryptoOperationHelper.java | 10 +- .../keychain/ui/dialog/ProgressDialogFragment.java | 6 +- 6 files changed, 226 insertions(+), 226 deletions(-) delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index 8e416f387..5c7b36874 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -711,7 +711,7 @@ android:exported="false" android:process=":remote_api" /> - * Copyright (C) 2014 Vincent Breitmoser - * - * 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 . - */ - -package org.sufficientlysecure.keychain.service; - -import android.app.Service; -import android.content.Intent; -import android.os.Bundle; -import android.os.IBinder; -import android.os.Message; -import android.os.Messenger; -import android.os.Parcelable; -import android.os.RemoteException; - -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.operations.BaseOperation; -import org.sufficientlysecure.keychain.operations.CertifyOperation; -import org.sufficientlysecure.keychain.operations.ConsolidateOperation; -import org.sufficientlysecure.keychain.operations.DeleteOperation; -import org.sufficientlysecure.keychain.operations.EditKeyOperation; -import org.sufficientlysecure.keychain.operations.ImportExportOperation; -import org.sufficientlysecure.keychain.operations.KeybaseVerificationOperation; -import org.sufficientlysecure.keychain.operations.PromoteKeyOperation; -import org.sufficientlysecure.keychain.operations.SignEncryptOperation; -import org.sufficientlysecure.keychain.operations.results.OperationResult; -import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; -import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; -import org.sufficientlysecure.keychain.pgp.Progressable; -import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; -import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus; -import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; -import org.sufficientlysecure.keychain.util.Log; - -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * This Service contains all important long lasting operations for OpenKeychain. It receives Intents with - * data from the activities or other apps, executes them, and stops itself after doing them. - */ -public class KeychainNewService extends Service implements Progressable { - - // messenger for communication (hack) - public static final String EXTRA_MESSENGER = "messenger"; - - // extras for operation - public static final String EXTRA_OPERATION_INPUT = "op_input"; - public static final String EXTRA_CRYPTO_INPUT = "crypto_input"; - - public static final String ACTION_CANCEL = "action_cancel"; - - // this attribute can possibly merged with the one above? not sure... - private AtomicBoolean mActionCanceled = new AtomicBoolean(false); - - ThreadLocal mMessenger = new ThreadLocal<>(); - - @Override - public IBinder onBind(Intent intent) { - return null; - } - - /** - * This is run on the main thread, we need to spawn a runnable which runs on another thread for the actual operation - */ - @Override - public int onStartCommand(final Intent intent, int flags, int startId) { - - if (intent.getAction() != null && intent.getAction().equals(ACTION_CANCEL)) { - mActionCanceled.set(true); - return START_NOT_STICKY; - } - - Runnable actionRunnable = new Runnable() { - @Override - public void run() { - // We have not been cancelled! (yet) - mActionCanceled.set(false); - - Bundle extras = intent.getExtras(); - - // Set messenger for communication (for this particular thread) - mMessenger.set(extras.getParcelable(EXTRA_MESSENGER)); - - // Input - Parcelable inputParcel = extras.getParcelable(EXTRA_OPERATION_INPUT); - CryptoInputParcel cryptoInput = extras.getParcelable(EXTRA_CRYPTO_INPUT); - - // Operation - BaseOperation op; - - // just for brevity - KeychainNewService outerThis = KeychainNewService.this; - if (inputParcel instanceof SignEncryptParcel) { - op = new SignEncryptOperation(outerThis, new ProviderHelper(outerThis), - outerThis, mActionCanceled); - } else if (inputParcel instanceof PgpDecryptVerifyInputParcel) { - op = new PgpDecryptVerify(outerThis, new ProviderHelper(outerThis), outerThis); - } else if (inputParcel instanceof SaveKeyringParcel) { - op = new EditKeyOperation(outerThis, new ProviderHelper(outerThis), outerThis, - mActionCanceled); - } else if (inputParcel instanceof CertifyActionsParcel) { - op = new CertifyOperation(outerThis, new ProviderHelper(outerThis), outerThis, - mActionCanceled); - } else if (inputParcel instanceof DeleteKeyringParcel) { - op = new DeleteOperation(outerThis, new ProviderHelper(outerThis), outerThis); - } else if (inputParcel instanceof PromoteKeyringParcel) { - op = new PromoteKeyOperation(outerThis, new ProviderHelper(outerThis), - outerThis, mActionCanceled); - } else if (inputParcel instanceof ImportKeyringParcel - || inputParcel instanceof ExportKeyringParcel) { - op = new ImportExportOperation(outerThis, new ProviderHelper(outerThis), - outerThis, mActionCanceled); - } else if (inputParcel instanceof ConsolidateInputParcel) { - op = new ConsolidateOperation(outerThis, new ProviderHelper(outerThis), - outerThis); - } else if (inputParcel instanceof KeybaseVerificationParcel) { - op = new KeybaseVerificationOperation(outerThis, new ProviderHelper(outerThis), - outerThis); - } else { - return; - } - - @SuppressWarnings("unchecked") // this is unchecked, we make sure it's the correct op above! - OperationResult result = op.execute(inputParcel, cryptoInput); - sendMessageToHandler(MessageStatus.OKAY, result); - - } - }; - - Thread actionThread = new Thread(actionRunnable); - actionThread.start(); - - return START_NOT_STICKY; - } - - private void sendMessageToHandler(MessageStatus status, Integer arg2, Bundle data) { - - Message msg = Message.obtain(); - assert msg != null; - msg.arg1 = status.ordinal(); - if (arg2 != null) { - msg.arg2 = arg2; - } - if (data != null) { - msg.setData(data); - } - - try { - mMessenger.get().send(msg); - } catch (RemoteException e) { - Log.w(Constants.TAG, "Exception sending message, Is handler present?", e); - } catch (NullPointerException e) { - Log.w(Constants.TAG, "Messenger is null!", e); - } - } - - private void sendMessageToHandler(MessageStatus status, OperationResult data) { - Bundle bundle = new Bundle(); - bundle.putParcelable(OperationResult.EXTRA_RESULT, data); - sendMessageToHandler(status, null, bundle); - } - - private void sendMessageToHandler(MessageStatus status) { - sendMessageToHandler(status, null, null); - } - - /** - * Set progress of ProgressDialog by sending message to handler on UI thread - */ - @Override - public void setProgress(String message, int progress, int max) { - Log.d(Constants.TAG, "Send message by setProgress with progress=" + progress + ", max=" - + max); - - Bundle data = new Bundle(); - if (message != null) { - data.putString(ServiceProgressHandler.DATA_MESSAGE, message); - } - data.putInt(ServiceProgressHandler.DATA_PROGRESS, progress); - data.putInt(ServiceProgressHandler.DATA_PROGRESS_MAX, max); - - sendMessageToHandler(MessageStatus.UPDATE_PROGRESS, null, data); - } - - @Override - public void setProgress(int resourceId, int progress, int max) { - setProgress(getString(resourceId), progress, max); - } - - @Override - public void setProgress(int progress, int max) { - setProgress(null, progress, max); - } - - @Override - public void setPreventCancel() { - sendMessageToHandler(MessageStatus.PREVENT_CANCEL); - } - -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java new file mode 100644 index 000000000..6a74520db --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2012-2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser + * + * 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 . + */ + +package org.sufficientlysecure.keychain.service; + +import android.app.Service; +import android.content.Intent; +import android.os.Bundle; +import android.os.IBinder; +import android.os.Message; +import android.os.Messenger; +import android.os.Parcelable; +import android.os.RemoteException; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.operations.BaseOperation; +import org.sufficientlysecure.keychain.operations.CertifyOperation; +import org.sufficientlysecure.keychain.operations.ConsolidateOperation; +import org.sufficientlysecure.keychain.operations.DeleteOperation; +import org.sufficientlysecure.keychain.operations.EditKeyOperation; +import org.sufficientlysecure.keychain.operations.ImportExportOperation; +import org.sufficientlysecure.keychain.operations.KeybaseVerificationOperation; +import org.sufficientlysecure.keychain.operations.PromoteKeyOperation; +import org.sufficientlysecure.keychain.operations.SignEncryptOperation; +import org.sufficientlysecure.keychain.operations.results.OperationResult; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; +import org.sufficientlysecure.keychain.pgp.Progressable; +import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.util.Log; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * This Service contains all important long lasting operations for OpenKeychain. It receives Intents with + * data from the activities or other apps, executes them, and stops itself after doing them. + */ +public class KeychainService extends Service implements Progressable { + + // messenger for communication (hack) + public static final String EXTRA_MESSENGER = "messenger"; + + // extras for operation + public static final String EXTRA_OPERATION_INPUT = "op_input"; + public static final String EXTRA_CRYPTO_INPUT = "crypto_input"; + + public static final String ACTION_CANCEL = "action_cancel"; + + // this attribute can possibly merged with the one above? not sure... + private AtomicBoolean mActionCanceled = new AtomicBoolean(false); + + ThreadLocal mMessenger = new ThreadLocal<>(); + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + /** + * This is run on the main thread, we need to spawn a runnable which runs on another thread for the actual operation + */ + @Override + public int onStartCommand(final Intent intent, int flags, int startId) { + + if (intent.getAction() != null && intent.getAction().equals(ACTION_CANCEL)) { + mActionCanceled.set(true); + return START_NOT_STICKY; + } + + Runnable actionRunnable = new Runnable() { + @Override + public void run() { + // We have not been cancelled! (yet) + mActionCanceled.set(false); + + Bundle extras = intent.getExtras(); + + // Set messenger for communication (for this particular thread) + mMessenger.set(extras.getParcelable(EXTRA_MESSENGER)); + + // Input + Parcelable inputParcel = extras.getParcelable(EXTRA_OPERATION_INPUT); + CryptoInputParcel cryptoInput = extras.getParcelable(EXTRA_CRYPTO_INPUT); + + // Operation + BaseOperation op; + + // just for brevity + KeychainService outerThis = KeychainService.this; + if (inputParcel instanceof SignEncryptParcel) { + op = new SignEncryptOperation(outerThis, new ProviderHelper(outerThis), + outerThis, mActionCanceled); + } else if (inputParcel instanceof PgpDecryptVerifyInputParcel) { + op = new PgpDecryptVerify(outerThis, new ProviderHelper(outerThis), outerThis); + } else if (inputParcel instanceof SaveKeyringParcel) { + op = new EditKeyOperation(outerThis, new ProviderHelper(outerThis), outerThis, + mActionCanceled); + } else if (inputParcel instanceof CertifyActionsParcel) { + op = new CertifyOperation(outerThis, new ProviderHelper(outerThis), outerThis, + mActionCanceled); + } else if (inputParcel instanceof DeleteKeyringParcel) { + op = new DeleteOperation(outerThis, new ProviderHelper(outerThis), outerThis); + } else if (inputParcel instanceof PromoteKeyringParcel) { + op = new PromoteKeyOperation(outerThis, new ProviderHelper(outerThis), + outerThis, mActionCanceled); + } else if (inputParcel instanceof ImportKeyringParcel + || inputParcel instanceof ExportKeyringParcel) { + op = new ImportExportOperation(outerThis, new ProviderHelper(outerThis), + outerThis, mActionCanceled); + } else if (inputParcel instanceof ConsolidateInputParcel) { + op = new ConsolidateOperation(outerThis, new ProviderHelper(outerThis), + outerThis); + } else if (inputParcel instanceof KeybaseVerificationParcel) { + op = new KeybaseVerificationOperation(outerThis, new ProviderHelper(outerThis), + outerThis); + } else { + return; + } + + @SuppressWarnings("unchecked") // this is unchecked, we make sure it's the correct op above! + OperationResult result = op.execute(inputParcel, cryptoInput); + sendMessageToHandler(MessageStatus.OKAY, result); + + } + }; + + Thread actionThread = new Thread(actionRunnable); + actionThread.start(); + + return START_NOT_STICKY; + } + + private void sendMessageToHandler(MessageStatus status, Integer arg2, Bundle data) { + + Message msg = Message.obtain(); + assert msg != null; + msg.arg1 = status.ordinal(); + if (arg2 != null) { + msg.arg2 = arg2; + } + if (data != null) { + msg.setData(data); + } + + try { + mMessenger.get().send(msg); + } catch (RemoteException e) { + Log.w(Constants.TAG, "Exception sending message, Is handler present?", e); + } catch (NullPointerException e) { + Log.w(Constants.TAG, "Messenger is null!", e); + } + } + + private void sendMessageToHandler(MessageStatus status, OperationResult data) { + Bundle bundle = new Bundle(); + bundle.putParcelable(OperationResult.EXTRA_RESULT, data); + sendMessageToHandler(status, null, bundle); + } + + private void sendMessageToHandler(MessageStatus status) { + sendMessageToHandler(status, null, null); + } + + /** + * Set progress of ProgressDialog by sending message to handler on UI thread + */ + @Override + public void setProgress(String message, int progress, int max) { + Log.d(Constants.TAG, "Send message by setProgress with progress=" + progress + ", max=" + + max); + + Bundle data = new Bundle(); + if (message != null) { + data.putString(ServiceProgressHandler.DATA_MESSAGE, message); + } + data.putInt(ServiceProgressHandler.DATA_PROGRESS, progress); + data.putInt(ServiceProgressHandler.DATA_PROGRESS_MAX, max); + + sendMessageToHandler(MessageStatus.UPDATE_PROGRESS, null, data); + } + + @Override + public void setProgress(int resourceId, int progress, int max) { + setProgress(getString(resourceId), progress, max); + } + + @Override + public void setProgress(int progress, int max) { + setProgress(null, progress, max); + } + + @Override + public void setPreventCancel() { + sendMessageToHandler(MessageStatus.PREVENT_CANCEL); + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 5360058f7..4b157590d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -66,7 +66,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; -import org.sufficientlysecure.keychain.service.KeychainNewService; +import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus; import org.sufficientlysecure.keychain.service.PassphraseCacheService; @@ -427,7 +427,7 @@ public class ViewKeyActivity extends BaseNfcActivity implements }; // Create a new Messenger for the communication back Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainNewService.EXTRA_MESSENGER, messenger); + intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger); startActivityForResult(intent, 0); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java index 856ed8bb0..a0ff4664b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationHelper.java @@ -34,7 +34,7 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.InputPendingResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; -import org.sufficientlysecure.keychain.service.KeychainNewService; +import org.sufficientlysecure.keychain.service.KeychainService; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; @@ -234,10 +234,10 @@ public class CryptoOperationHelper Date: Wed, 24 Jun 2015 08:00:39 +0530 Subject: fixed package import --- .../org/sufficientlysecure/keychain/operations/DeleteOperation.java | 3 +-- .../sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/DeleteOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/DeleteOperation.java index 06f7ee752..50b2ef69b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/DeleteOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/DeleteOperation.java @@ -27,10 +27,9 @@ import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.ContactSyncAdapterService; +import org.sufficientlysecure.keychain.service.DeleteKeyringParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; -import org.sufficientlysecure.keychain.service.input.DeleteKeyringParcel; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; -import org.sufficientlysecure.keychain.util.Log; /** An operation which implements a high level keyring delete operation. * diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java index 0797cf596..03850aa92 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java @@ -37,8 +37,8 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.DeleteKeyringParcel; import org.sufficientlysecure.keychain.service.ServiceProgressHandler; -import org.sufficientlysecure.keychain.service.input.DeleteKeyringParcel; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.util.Log; -- cgit v1.2.3 From f64e1467ad0549702ef90801fc020298a32e2566 Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Thu, 25 Jun 2015 06:43:14 +0530 Subject: split import and export ops --- .../keychain/operations/CertifyOperation.java | 8 +- .../keychain/operations/ExportOperation.java | 343 ++++++++ .../keychain/operations/ImportExportOperation.java | 873 --------------------- .../keychain/operations/ImportOperation.java | 565 +++++++++++++ .../keychain/provider/ProviderHelper.java | 6 +- .../keychain/service/ExportKeyringParcel.java | 2 +- .../keychain/service/ImportExportParcel.java | 38 - .../keychain/service/ImportKeyringParcel.java | 2 +- .../keychain/service/KeychainService.java | 13 +- .../keychain/ui/adapter/ImportKeysAdapter.java | 5 +- .../keychain/operations/ExportTest.java | 3 +- 11 files changed, 929 insertions(+), 929 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ExportOperation.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportExportParcel.java (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java index cb76c8ba3..0806e6a16 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java @@ -188,10 +188,10 @@ public class CertifyOperation extends BaseOperation { } HkpKeyserver keyServer = null; - ImportExportOperation importExportOperation = null; + ExportOperation exportOperation = null; if (parcel.keyServerUri != null) { keyServer = new HkpKeyserver(parcel.keyServerUri); - importExportOperation = new ImportExportOperation(mContext, mProviderHelper, mProgressable); + exportOperation = new ExportOperation(mContext, mProviderHelper, mProgressable); } // Write all certified keys into the database @@ -209,10 +209,10 @@ public class CertifyOperation extends BaseOperation { mProviderHelper.clearLog(); SaveKeyringResult result = mProviderHelper.savePublicKeyRing(certifiedKey); - if (importExportOperation != null) { + if (exportOperation != null) { // TODO use subresult, get rid of try/catch! try { - importExportOperation.uploadKeyRingToServer(keyServer, certifiedKey); + exportOperation.uploadKeyRingToServer(keyServer, certifiedKey); uploadOk += 1; } catch (AddKeyException e) { Log.e(Constants.TAG, "error uploading key", e); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ExportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ExportOperation.java new file mode 100644 index 000000000..01a45bc79 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ExportOperation.java @@ -0,0 +1,343 @@ +/* + * Copyright (C) 2012-2014 Dominik Schürmann + * Copyright (C) 2010-2014 Thialfihar + * + * 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 . + */ + +package org.sufficientlysecure.keychain.operations; + +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; + +import org.spongycastle.bcpg.ArmoredOutputStream; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; +import org.sufficientlysecure.keychain.keyimport.Keyserver.AddKeyException; +import org.sufficientlysecure.keychain.operations.results.ExportResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; +import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; +import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing; +import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; +import org.sufficientlysecure.keychain.pgp.Progressable; +import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.ExportKeyringParcel; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; +import org.sufficientlysecure.keychain.util.FileHelper; +import org.sufficientlysecure.keychain.util.Log; + +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * An operation class which implements high level export + * operations. + * This class receives a source and/or destination of keys as input and performs + * all steps for this export. + * + * @see org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter#getSelectedEntries() + * For the export operation, the input consists of a set of key ids and + * either the name of a file or an output uri to write to. + * TODO rework uploadKeyRingToServer + */ +public class ExportOperation extends BaseOperation { + + public ExportOperation(Context context, ProviderHelper providerHelper, Progressable + progressable) { + super(context, providerHelper, progressable); + } + + public ExportOperation(Context context, ProviderHelper providerHelper, + Progressable progressable, AtomicBoolean cancelled) { + super(context, providerHelper, progressable, cancelled); + } + + public void uploadKeyRingToServer(HkpKeyserver server, CanonicalizedPublicKeyRing keyring) + throws AddKeyException { + uploadKeyRingToServer(server, keyring.getUncachedKeyRing()); + } + + public void uploadKeyRingToServer(HkpKeyserver server, UncachedKeyRing keyring) throws + AddKeyException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ArmoredOutputStream aos = null; + try { + aos = new ArmoredOutputStream(bos); + keyring.encode(aos); + aos.close(); + + String armoredKey = bos.toString("UTF-8"); + server.add(armoredKey); + } catch (IOException e) { + Log.e(Constants.TAG, "IOException", e); + throw new AddKeyException(); + } finally { + try { + if (aos != null) { + aos.close(); + } + bos.close(); + } catch (IOException e) { + // this is just a finally thing, no matter if it doesn't work out. + } + } + } + + public ExportResult exportToFile(long[] masterKeyIds, boolean exportSecret, String outputFile) { + + OperationLog log = new OperationLog(); + if (masterKeyIds != null) { + log.add(LogType.MSG_EXPORT, 0, masterKeyIds.length); + } else { + log.add(LogType.MSG_EXPORT_ALL, 0); + } + + // do we have a file name? + if (outputFile == null) { + log.add(LogType.MSG_EXPORT_ERROR_NO_FILE, 1); + return new ExportResult(ExportResult.RESULT_ERROR, log); + } + + // check if storage is ready + if (!FileHelper.isStorageMounted(outputFile)) { + log.add(LogType.MSG_EXPORT_ERROR_STORAGE, 1); + return new ExportResult(ExportResult.RESULT_ERROR, log); + } + + try { + OutputStream outStream = new FileOutputStream(outputFile); + try { + ExportResult result = exportKeyRings(log, masterKeyIds, exportSecret, outStream); + if (result.cancelled()) { + //noinspection ResultOfMethodCallIgnored + new File(outputFile).delete(); + } + return result; + } finally { + outStream.close(); + } + } catch (IOException e) { + log.add(LogType.MSG_EXPORT_ERROR_FOPEN, 1); + return new ExportResult(ExportResult.RESULT_ERROR, log); + } + + } + + public ExportResult exportToUri(long[] masterKeyIds, boolean exportSecret, Uri outputUri) { + + OperationLog log = new OperationLog(); + if (masterKeyIds != null) { + log.add(LogType.MSG_EXPORT, 0, masterKeyIds.length); + } else { + log.add(LogType.MSG_EXPORT_ALL, 0); + } + + // do we have a file name? + if (outputUri == null) { + log.add(LogType.MSG_EXPORT_ERROR_NO_URI, 1); + return new ExportResult(ExportResult.RESULT_ERROR, log); + } + + try { + OutputStream outStream = mProviderHelper.getContentResolver().openOutputStream + (outputUri); + return exportKeyRings(log, masterKeyIds, exportSecret, outStream); + } catch (FileNotFoundException e) { + log.add(LogType.MSG_EXPORT_ERROR_URI_OPEN, 1); + return new ExportResult(ExportResult.RESULT_ERROR, log); + } + + } + + ExportResult exportKeyRings(OperationLog log, long[] masterKeyIds, boolean exportSecret, + OutputStream outStream) { + + /* TODO isn't this checked above, with the isStorageMounted call? + if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + log.add(LogType.MSG_EXPORT_ERROR_STORAGE, 1); + return new ExportResult(ExportResult.RESULT_ERROR, log); + } + */ + + if (!BufferedOutputStream.class.isInstance(outStream)) { + outStream = new BufferedOutputStream(outStream); + } + + int okSecret = 0, okPublic = 0, progress = 0; + + Cursor cursor = null; + try { + + String selection = null, ids[] = null; + + if (masterKeyIds != null) { + // generate placeholders and string selection args + ids = new String[masterKeyIds.length]; + StringBuilder placeholders = new StringBuilder("?"); + for (int i = 0; i < masterKeyIds.length; i++) { + ids[i] = Long.toString(masterKeyIds[i]); + if (i != 0) { + placeholders.append(",?"); + } + } + + // put together selection string + selection = Tables.KEY_RINGS_PUBLIC + "." + KeyRings.MASTER_KEY_ID + + " IN (" + placeholders + ")"; + } + + cursor = mProviderHelper.getContentResolver().query( + KeyRings.buildUnifiedKeyRingsUri(), new String[]{ + KeyRings.MASTER_KEY_ID, KeyRings.PUBKEY_DATA, + KeyRings.PRIVKEY_DATA, KeyRings.HAS_ANY_SECRET + }, selection, ids, Tables.KEYS + "." + KeyRings.MASTER_KEY_ID + ); + + if (cursor == null || !cursor.moveToFirst()) { + log.add(LogType.MSG_EXPORT_ERROR_DB, 1); + return new ExportResult(ExportResult.RESULT_ERROR, log, okPublic, okSecret); + } + + int numKeys = cursor.getCount(); + + updateProgress( + mContext.getResources().getQuantityString(R.plurals.progress_exporting_key, + numKeys), 0, numKeys); + + // For each public masterKey id + while (!cursor.isAfterLast()) { + + long keyId = cursor.getLong(0); + ArmoredOutputStream arOutStream = null; + + // Create an output stream + try { + arOutStream = new ArmoredOutputStream(outStream); + + log.add(LogType.MSG_EXPORT_PUBLIC, 1, KeyFormattingUtils.beautifyKeyId(keyId)); + + byte[] data = cursor.getBlob(1); + CanonicalizedKeyRing ring = + UncachedKeyRing.decodeFromData(data).canonicalize(log, 2, true); + ring.encode(arOutStream); + + okPublic += 1; + } catch (PgpGeneralException e) { + log.add(LogType.MSG_EXPORT_ERROR_KEY, 2); + updateProgress(progress++, numKeys); + continue; + } finally { + // make sure this is closed + if (arOutStream != null) { + arOutStream.close(); + } + arOutStream = null; + } + + if (exportSecret && cursor.getInt(3) > 0) { + try { + arOutStream = new ArmoredOutputStream(outStream); + + // export secret key part + log.add(LogType.MSG_EXPORT_SECRET, 2, KeyFormattingUtils.beautifyKeyId + (keyId)); + byte[] data = cursor.getBlob(2); + CanonicalizedKeyRing ring = + UncachedKeyRing.decodeFromData(data).canonicalize(log, 2, true); + ring.encode(arOutStream); + + okSecret += 1; + } catch (PgpGeneralException e) { + log.add(LogType.MSG_EXPORT_ERROR_KEY, 2); + updateProgress(progress++, numKeys); + continue; + } finally { + // make sure this is closed + if (arOutStream != null) { + arOutStream.close(); + } + } + } + + updateProgress(progress++, numKeys); + + cursor.moveToNext(); + } + + updateProgress(R.string.progress_done, numKeys, numKeys); + + } catch (IOException e) { + log.add(LogType.MSG_EXPORT_ERROR_IO, 1); + return new ExportResult(ExportResult.RESULT_ERROR, log, okPublic, okSecret); + } finally { + // Make sure the stream is closed + if (outStream != null) try { + outStream.close(); + } catch (Exception e) { + Log.e(Constants.TAG, "error closing stream", e); + } + if (cursor != null) { + cursor.close(); + } + } + + + log.add(LogType.MSG_EXPORT_SUCCESS, 1); + return new ExportResult(ExportResult.RESULT_OK, log, okPublic, okSecret); + + } + + public ExportResult execute(ExportKeyringParcel exportInput, CryptoInputParcel cryptoInput) { + switch (exportInput.mExportType) { + case UPLOAD_KEYSERVER: { + HkpKeyserver hkpKeyserver = new HkpKeyserver(exportInput.mKeyserver); + try { + CanonicalizedPublicKeyRing keyring + = mProviderHelper.getCanonicalizedPublicKeyRing( + exportInput.mCanonicalizedPublicKeyringUri); + uploadKeyRingToServer(hkpKeyserver, keyring); + // TODO: replace with proper log + return new ExportResult(ExportResult.RESULT_OK, new OperationLog()); + } catch (Exception e) { + return new ExportResult(ExportResult.RESULT_ERROR, new OperationLog()); + // TODO: Implement better exception handling, replace with log + } + } + case EXPORT_FILE: { + return exportToFile(exportInput.mMasterKeyIds, exportInput.mExportSecret, + exportInput.mOutputFile); + } + case EXPORT_URI: { + return exportToUri(exportInput.mMasterKeyIds, exportInput.mExportSecret, + exportInput.mOutputUri); + } + default: { // can't happen + return null; + } + } + } +} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java deleted file mode 100644 index 3b9390866..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java +++ /dev/null @@ -1,873 +0,0 @@ -/* - * Copyright (C) 2012-2014 Dominik Schürmann - * Copyright (C) 2010-2014 Thialfihar - * - * 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 . - */ - -package org.sufficientlysecure.keychain.operations; - -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; - -import android.os.Parcelable; -import org.spongycastle.bcpg.ArmoredOutputStream; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; -import org.sufficientlysecure.keychain.keyimport.KeybaseKeyserver; -import org.sufficientlysecure.keychain.keyimport.Keyserver; -import org.sufficientlysecure.keychain.keyimport.Keyserver.AddKeyException; -import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; -import org.sufficientlysecure.keychain.operations.results.ConsolidateResult; -import org.sufficientlysecure.keychain.operations.results.ExportResult; -import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; -import org.sufficientlysecure.keychain.operations.results.OperationResult; -import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; -import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; -import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult; -import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing; -import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; -import org.sufficientlysecure.keychain.pgp.Progressable; -import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; -import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; -import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.service.ContactSyncAdapterService; -import org.sufficientlysecure.keychain.service.ExportKeyringParcel; -import org.sufficientlysecure.keychain.service.ImportExportParcel; -import org.sufficientlysecure.keychain.service.ImportKeyringParcel; -import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; -import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; -import org.sufficientlysecure.keychain.util.FileHelper; -import org.sufficientlysecure.keychain.util.Log; -import org.sufficientlysecure.keychain.util.ParcelableFileCache; -import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; -import org.sufficientlysecure.keychain.util.ProgressScaler; - -import java.io.BufferedOutputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.net.Proxy; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorCompletionService; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -/** An operation class which implements high level import and export - * operations. - * - * This class receives a source and/or destination of keys as input and performs - * all steps for this import or export. - * - * For the import operation, the only valid source is an Iterator of - * ParcelableKeyRing, each of which must contain either a single - * keyring encoded as bytes, or a unique reference to a keyring - * on keyservers and/or keybase.io. - * It is important to note that public keys should generally be imported before - * secret keys, because some implementations (notably Symantec PGP Desktop) do - * not include self certificates for user ids in the secret keyring. The import - * method here will generally import keyrings in the order given by the - * iterator. so this should be ensured beforehand. - * @see org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter#getSelectedEntries() - * - * For the export operation, the input consists of a set of key ids and - * either the name of a file or an output uri to write to. - * - * TODO rework uploadKeyRingToServer - * - */ -public class ImportExportOperation extends BaseOperation { - - public ImportExportOperation(Context context, ProviderHelper providerHelper, Progressable progressable) { - super(context, providerHelper, progressable); - } - - public ImportExportOperation(Context context, ProviderHelper providerHelper, - Progressable progressable, AtomicBoolean cancelled) { - super(context, providerHelper, progressable, cancelled); - } - - public void uploadKeyRingToServer(HkpKeyserver server, CanonicalizedPublicKeyRing keyring) throws AddKeyException { - uploadKeyRingToServer(server, keyring.getUncachedKeyRing()); - } - - public void uploadKeyRingToServer(HkpKeyserver server, UncachedKeyRing keyring) throws AddKeyException { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ArmoredOutputStream aos = null; - try { - aos = new ArmoredOutputStream(bos); - keyring.encode(aos); - aos.close(); - - String armoredKey = bos.toString("UTF-8"); - server.add(armoredKey); - } catch (IOException e) { - Log.e(Constants.TAG, "IOException", e); - throw new AddKeyException(); - } finally { - try { - if (aos != null) { - aos.close(); - } - bos.close(); - } catch (IOException e) { - // this is just a finally thing, no matter if it doesn't work out. - } - } - } - - // Overloaded functions for using progressable supplied in constructor during import - public ImportKeyResult serialKeyRingImport(Iterator entries, int num, - String keyServerUri) { - return serialKeyRingImport(entries, num, keyServerUri, mProgressable); - } - - public ImportKeyResult serialKeyRingImport(List entries, - String keyServerUri) { - - Iterator it = entries.iterator(); - int numEntries = entries.size(); - - return serialKeyRingImport(it, numEntries, keyServerUri, mProgressable); - - } - - public ImportKeyResult serialKeyRingImport(List entries, String keyServerUri, - Progressable progressable) { - - Iterator it = entries.iterator(); - int numEntries = entries.size(); - - return serialKeyRingImport(it, numEntries, keyServerUri, progressable); - - } - - public ImportKeyResult serialKeyRingImport(ParcelableFileCache cache, - String keyServerUri) { - - // get entries from cached file - try { - IteratorWithSize it = cache.readCache(); - int numEntries = it.getSize(); - - return serialKeyRingImport(it, numEntries, keyServerUri, mProgressable); - } catch (IOException e) { - - // Special treatment here, we need a lot - OperationLog log = new OperationLog(); - log.add(LogType.MSG_IMPORT, 0, 0); - log.add(LogType.MSG_IMPORT_ERROR_IO, 0, 0); - - return new ImportKeyResult(ImportKeyResult.RESULT_ERROR, log); - } - - } - - /** - * Since the introduction of multithreaded import, we expect calling functions to handle the - * key sync i,eContactSyncAdapterService.requestSync() - * - * @param entries keys to import - * @param num number of keys to import - * @param keyServerUri contains uri of keyserver to import from, if it is an import from cloud - * @param progressable Allows multi-threaded import to supply a progressable that ignores the - * progress of a single key being imported - * @return - */ - public ImportKeyResult serialKeyRingImport(Iterator entries, int num, - String keyServerUri, Progressable progressable) { - updateProgress(R.string.progress_importing, 0, 100); - - OperationLog log = new OperationLog(); - log.add(LogType.MSG_IMPORT, 0, num); - - // If there aren't even any keys, do nothing here. - if (entries == null || !entries.hasNext()) { - return new ImportKeyResult(ImportKeyResult.RESULT_FAIL_NOTHING, log); - } - - int newKeys = 0, updatedKeys = 0, badKeys = 0, secret = 0; - ArrayList importedMasterKeyIds = new ArrayList<>(); - - boolean cancelled = false; - int position = 0; - double progSteps = 100.0 / num; - - KeybaseKeyserver keybaseServer = null; - HkpKeyserver keyServer = null; - - // iterate over all entries - while (entries.hasNext()) { - ParcelableKeyRing entry = entries.next(); - - // Has this action been cancelled? If so, don't proceed any further - if (checkCancelled()) { - cancelled = true; - break; - } - - try { - - UncachedKeyRing key = null; - - // If there is already byte data, use that - if (entry.mBytes != null) { - key = UncachedKeyRing.decodeFromData(entry.mBytes); - } - // Otherwise, we need to fetch the data from a server first - else { - - // We fetch from keyservers first, because we tend to get more certificates - // from there, so the number of certificates which are merged in later is smaller. - - // If we have a keyServerUri and a fingerprint or at least a keyId, - // download from HKP - if (keyServerUri != null - && (entry.mKeyIdHex != null || entry.mExpectedFingerprint != null)) { - // Make sure we have the keyserver instance cached - if (keyServer == null) { - log.add(LogType.MSG_IMPORT_KEYSERVER, 1, keyServerUri); - keyServer = new HkpKeyserver(keyServerUri); - } - - try { - byte[] data; - // Download by fingerprint, or keyId - whichever is available - if (entry.mExpectedFingerprint != null) { - log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER, 2, "0x" + - entry.mExpectedFingerprint.substring(24)); - data = keyServer.get("0x" + entry.mExpectedFingerprint).getBytes(); - } else { - log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER, 2, entry.mKeyIdHex); - data = keyServer.get(entry.mKeyIdHex).getBytes(); - } - key = UncachedKeyRing.decodeFromData(data); - if (key != null) { - log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_OK, 3); - } else { - log.add(LogType.MSG_IMPORT_FETCH_ERROR_DECODE, 3); - } - } catch (Keyserver.QueryFailedException e) { - Log.e(Constants.TAG, "query failed", e); - log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_ERROR, 3, e.getMessage()); - } - } - - // If we have a keybase name, try to fetch from there - if (entry.mKeybaseName != null) { - // Make sure we have this cached - if (keybaseServer == null) { - keybaseServer = new KeybaseKeyserver(); - } - - try { - log.add(LogType.MSG_IMPORT_FETCH_KEYBASE, 2, entry.mKeybaseName); - byte[] data = keybaseServer.get(entry.mKeybaseName).getBytes(); - UncachedKeyRing keybaseKey = UncachedKeyRing.decodeFromData(data); - - // If there already is a key, merge the two - if (key != null && keybaseKey != null) { - log.add(LogType.MSG_IMPORT_MERGE, 3); - keybaseKey = key.merge(keybaseKey, log, 4); - // If the merge didn't fail, use the new merged key - if (keybaseKey != null) { - key = keybaseKey; - } else { - log.add(LogType.MSG_IMPORT_MERGE_ERROR, 4); - } - } else if (keybaseKey != null) { - key = keybaseKey; - } - } catch (Keyserver.QueryFailedException e) { - // download failed, too bad. just proceed - Log.e(Constants.TAG, "query failed", e); - log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_ERROR, 3, e.getMessage()); - } - } - } - - if (key == null) { - log.add(LogType.MSG_IMPORT_FETCH_ERROR, 2); - badKeys += 1; - continue; - } - - // If we have an expected fingerprint, make sure it matches - if (entry.mExpectedFingerprint != null) { - if (!key.containsSubkey(entry.mExpectedFingerprint)) { - log.add(LogType.MSG_IMPORT_FINGERPRINT_ERROR, 2); - badKeys += 1; - continue; - } else { - log.add(LogType.MSG_IMPORT_FINGERPRINT_OK, 2); - } - } - - // Another check if we have been cancelled - if (checkCancelled()) { - cancelled = true; - break; - } - - SaveKeyringResult result; - mProviderHelper.clearLog(); - if (key.isSecret()) { - result = mProviderHelper.saveSecretKeyRing(key, - new ProgressScaler(progressable, (int)(position*progSteps), - (int)((position+1)*progSteps), 100)); - } else { - result = mProviderHelper.savePublicKeyRing(key, - new ProgressScaler(progressable, (int)(position*progSteps), - (int)((position+1)*progSteps), 100)); - } - if (!result.success()) { - badKeys += 1; - } else if (result.updated()) { - updatedKeys += 1; - importedMasterKeyIds.add(key.getMasterKeyId()); - } else { - newKeys += 1; - if (key.isSecret()) { - secret += 1; - } - importedMasterKeyIds.add(key.getMasterKeyId()); - } - - log.add(result, 2); - - } catch (IOException | PgpGeneralException e) { - Log.e(Constants.TAG, "Encountered bad key on import!", e); - ++badKeys; - } - // update progress - position++; - } - - // Special: consolidate on secret key import (cannot be cancelled!) - if (secret > 0) { - setPreventCancel(); - ConsolidateResult result = mProviderHelper.consolidateDatabaseStep1(progressable); - log.add(result, 1); - } - - // Special: make sure new data is synced into contacts - // disabling sync right now since it reduces speed while multi-threading - // so, we expect calling functions to take care of it. KeychainService handles this - // ContactSyncAdapterService.requestSync(); - - // convert to long array - long[] importedMasterKeyIdsArray = new long[importedMasterKeyIds.size()]; - for (int i = 0; i < importedMasterKeyIds.size(); ++i) { - importedMasterKeyIdsArray[i] = importedMasterKeyIds.get(i); - } - - int resultType = 0; - if (cancelled) { - log.add(LogType.MSG_OPERATION_CANCELLED, 1); - resultType |= ImportKeyResult.RESULT_CANCELLED; - } - - // special return case: no new keys at all - if (badKeys == 0 && newKeys == 0 && updatedKeys == 0) { - resultType = ImportKeyResult.RESULT_FAIL_NOTHING; - } else { - if (newKeys > 0) { - resultType |= ImportKeyResult.RESULT_OK_NEWKEYS; - } - if (updatedKeys > 0) { - resultType |= ImportKeyResult.RESULT_OK_UPDATED; - } - if (badKeys > 0) { - resultType |= ImportKeyResult.RESULT_WITH_ERRORS; - if (newKeys == 0 && updatedKeys == 0) { - resultType |= ImportKeyResult.RESULT_ERROR; - } - } - if (log.containsWarnings()) { - resultType |= ImportKeyResult.RESULT_WARNINGS; - } - } - - // Final log entry, it's easier to do this individually - if ( (newKeys > 0 || updatedKeys > 0) && badKeys > 0) { - log.add(LogType.MSG_IMPORT_PARTIAL, 1); - } else if (newKeys > 0 || updatedKeys > 0) { - log.add(LogType.MSG_IMPORT_SUCCESS, 1); - } else { - log.add(LogType.MSG_IMPORT_ERROR, 1); - } - - return new ImportKeyResult(resultType, log, newKeys, updatedKeys, badKeys, secret, - importedMasterKeyIdsArray); - } - - public ExportResult exportToFile(long[] masterKeyIds, boolean exportSecret, String outputFile) { - - OperationLog log = new OperationLog(); - if (masterKeyIds != null) { - log.add(LogType.MSG_EXPORT, 0, masterKeyIds.length); - } else { - log.add(LogType.MSG_EXPORT_ALL, 0); - } - - // do we have a file name? - if (outputFile == null) { - log.add(LogType.MSG_EXPORT_ERROR_NO_FILE, 1); - return new ExportResult(ExportResult.RESULT_ERROR, log); - } - - // check if storage is ready - if (!FileHelper.isStorageMounted(outputFile)) { - log.add(LogType.MSG_EXPORT_ERROR_STORAGE, 1); - return new ExportResult(ExportResult.RESULT_ERROR, log); - } - - try { - OutputStream outStream = new FileOutputStream(outputFile); - try { - ExportResult result = exportKeyRings(log, masterKeyIds, exportSecret, outStream); - if (result.cancelled()) { - //noinspection ResultOfMethodCallIgnored - new File(outputFile).delete(); - } - return result; - } finally { - outStream.close(); - } - } catch (IOException e) { - log.add(LogType.MSG_EXPORT_ERROR_FOPEN, 1); - return new ExportResult(ExportResult.RESULT_ERROR, log); - } - - } - - public ExportResult exportToUri(long[] masterKeyIds, boolean exportSecret, Uri outputUri) { - - OperationLog log = new OperationLog(); - if (masterKeyIds != null) { - log.add(LogType.MSG_EXPORT, 0, masterKeyIds.length); - } else { - log.add(LogType.MSG_EXPORT_ALL, 0); - } - - // do we have a file name? - if (outputUri == null) { - log.add(LogType.MSG_EXPORT_ERROR_NO_URI, 1); - return new ExportResult(ExportResult.RESULT_ERROR, log); - } - - try { - OutputStream outStream = mProviderHelper.getContentResolver().openOutputStream(outputUri); - return exportKeyRings(log, masterKeyIds, exportSecret, outStream); - } catch (FileNotFoundException e) { - log.add(LogType.MSG_EXPORT_ERROR_URI_OPEN, 1); - return new ExportResult(ExportResult.RESULT_ERROR, log); - } - - } - - ExportResult exportKeyRings(OperationLog log, long[] masterKeyIds, boolean exportSecret, - OutputStream outStream) { - - /* TODO isn't this checked above, with the isStorageMounted call? - if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - log.add(LogType.MSG_EXPORT_ERROR_STORAGE, 1); - return new ExportResult(ExportResult.RESULT_ERROR, log); - } - */ - - if ( ! BufferedOutputStream.class.isInstance(outStream)) { - outStream = new BufferedOutputStream(outStream); - } - - int okSecret = 0, okPublic = 0, progress = 0; - - Cursor cursor = null; - try { - - String selection = null, ids[] = null; - - if (masterKeyIds != null) { - // generate placeholders and string selection args - ids = new String[masterKeyIds.length]; - StringBuilder placeholders = new StringBuilder("?"); - for (int i = 0; i < masterKeyIds.length; i++) { - ids[i] = Long.toString(masterKeyIds[i]); - if (i != 0) { - placeholders.append(",?"); - } - } - - // put together selection string - selection = Tables.KEY_RINGS_PUBLIC + "." + KeyRings.MASTER_KEY_ID - + " IN (" + placeholders + ")"; - } - - cursor = mProviderHelper.getContentResolver().query( - KeyRings.buildUnifiedKeyRingsUri(), new String[]{ - KeyRings.MASTER_KEY_ID, KeyRings.PUBKEY_DATA, - KeyRings.PRIVKEY_DATA, KeyRings.HAS_ANY_SECRET - }, selection, ids, Tables.KEYS + "." + KeyRings.MASTER_KEY_ID - ); - - if (cursor == null || !cursor.moveToFirst()) { - log.add(LogType.MSG_EXPORT_ERROR_DB, 1); - return new ExportResult(ExportResult.RESULT_ERROR, log, okPublic, okSecret); - } - - int numKeys = cursor.getCount(); - - updateProgress( - mContext.getResources().getQuantityString(R.plurals.progress_exporting_key, - numKeys), 0, numKeys); - - // For each public masterKey id - while (!cursor.isAfterLast()) { - - long keyId = cursor.getLong(0); - ArmoredOutputStream arOutStream = null; - - // Create an output stream - try { - arOutStream = new ArmoredOutputStream(outStream); - - log.add(LogType.MSG_EXPORT_PUBLIC, 1, KeyFormattingUtils.beautifyKeyId(keyId)); - - byte[] data = cursor.getBlob(1); - CanonicalizedKeyRing ring = - UncachedKeyRing.decodeFromData(data).canonicalize(log, 2, true); - ring.encode(arOutStream); - - okPublic += 1; - } catch (PgpGeneralException e) { - log.add(LogType.MSG_EXPORT_ERROR_KEY, 2); - updateProgress(progress++, numKeys); - continue; - } finally { - // make sure this is closed - if (arOutStream != null) { - arOutStream.close(); - } - arOutStream = null; - } - - if (exportSecret && cursor.getInt(3) > 0) { - try { - arOutStream = new ArmoredOutputStream(outStream); - - // export secret key part - log.add(LogType.MSG_EXPORT_SECRET, 2, KeyFormattingUtils.beautifyKeyId(keyId)); - byte[] data = cursor.getBlob(2); - CanonicalizedKeyRing ring = - UncachedKeyRing.decodeFromData(data).canonicalize(log, 2, true); - ring.encode(arOutStream); - - okSecret += 1; - } catch (PgpGeneralException e) { - log.add(LogType.MSG_EXPORT_ERROR_KEY, 2); - updateProgress(progress++, numKeys); - continue; - } finally { - // make sure this is closed - if (arOutStream != null) { - arOutStream.close(); - } - } - } - - updateProgress(progress++, numKeys); - - cursor.moveToNext(); - } - - updateProgress(R.string.progress_done, numKeys, numKeys); - - } catch (IOException e) { - log.add(LogType.MSG_EXPORT_ERROR_IO, 1); - return new ExportResult(ExportResult.RESULT_ERROR, log, okPublic, okSecret); - } finally { - // Make sure the stream is closed - if (outStream != null) try { - outStream.close(); - } catch (Exception e) { - Log.e(Constants.TAG, "error closing stream", e); - } - if (cursor != null) { - cursor.close(); - } - } - - - log.add(LogType.MSG_EXPORT_SUCCESS, 1); - return new ExportResult(ExportResult.RESULT_OK, log, okPublic, okSecret); - - } - - @Override - public OperationResult execute(ImportExportParcel input, CryptoInputParcel cryptoInput) { - if (input instanceof ExportKeyringParcel) { - ExportKeyringParcel exportInput = (ExportKeyringParcel) input; - switch (exportInput.mExportType) { - case UPLOAD_KEYSERVER: { - HkpKeyserver hkpKeyserver = new HkpKeyserver(exportInput.mKeyserver); - try { - CanonicalizedPublicKeyRing keyring - = mProviderHelper.getCanonicalizedPublicKeyRing( - exportInput.mCanonicalizedPublicKeyringUri); - uploadKeyRingToServer(hkpKeyserver, keyring); - // TODO: replace with proper log - return new ExportResult(ExportResult.RESULT_OK, new OperationLog()); - } catch (Exception e) { - // TODO: Implement better exception handling, replace with log - } - break; - } - case EXPORT_FILE: { - return exportToFile(exportInput.mMasterKeyIds, exportInput.mExportSecret, - exportInput.mOutputFile); - } - case EXPORT_URI: { - return exportToUri(exportInput.mMasterKeyIds, exportInput.mExportSecret, - exportInput.mOutputUri); - } - default: { - return null; - } - } - } - else if (input instanceof ImportKeyringParcel) { - ImportKeyringParcel importInput = (ImportKeyringParcel) input; - return importKeys(importInput.mKeyList, importInput.mKeyserver); - } else { - throw new RuntimeException("Invalid input parcel at ImportExportOperation"); - } - return null; - } - - public ImportKeyResult importKeys(ArrayList keyList, String keyServer) { - - ImportKeyResult result; - - if (keyList == null) {// import from file, do serially - ParcelableFileCache cache = new ParcelableFileCache<>(mContext, - "key_import.pcl"); - - result = serialKeyRingImport(cache, keyServer); - } else { - // if there is more than one key with the same fingerprint, we do a serial import to prevent - // https://github.com/open-keychain/open-keychain/issues/1221 - HashSet keyFingerprintSet = new HashSet<>(); - for (int i = 0; i < keyList.size(); i++) { - keyFingerprintSet.add(keyList.get(i).mExpectedFingerprint); - } - if (keyFingerprintSet.size() == keyList.size()) { - // all keys have unique fingerprints - result = multiThreadedKeyImport(keyList.iterator(), keyList.size(), keyServer); - } else { - result = serialKeyRingImport(keyList, keyServer); - } - } - - ContactSyncAdapterService.requestSync(); - return result; - } - - private ImportKeyResult multiThreadedKeyImport(Iterator keyListIterator, - int totKeys, final String keyServer) { - Log.d(Constants.TAG, "Multi-threaded key import starting"); - if (keyListIterator != null) { - KeyImportAccumulator accumulator = new KeyImportAccumulator(totKeys, mProgressable); - - final Progressable ignoreProgressable = new Progressable() { - @Override - public void setProgress(String message, int current, int total) { - - } - - @Override - public void setProgress(int resourceId, int current, int total) { - - } - - @Override - public void setProgress(int current, int total) { - - } - - @Override - public void setPreventCancel() { - - } - }; - - - final int maxThreads = 200; - ExecutorService importExecutor = new ThreadPoolExecutor(0, maxThreads, - 30L, TimeUnit.SECONDS, - new SynchronousQueue()); - - ExecutorCompletionService importCompletionService = - new ExecutorCompletionService(importExecutor); - - while (keyListIterator.hasNext()) { // submit all key rings to be imported - - final ParcelableKeyRing pkRing = keyListIterator.next(); - - Callable importOperationCallable = new Callable() { - - @Override - public ImportKeyResult call() { - - ArrayList list = new ArrayList<>(); - list.add(pkRing); - - return serialKeyRingImport(list, keyServer, ignoreProgressable); - } - }; - - importCompletionService.submit(importOperationCallable); - } - - while (!accumulator.isImportFinished()) { // accumulate the results of each import - try { - accumulator.accumulateKeyImport(importCompletionService.take().get()); - } catch (InterruptedException | ExecutionException e) { - Log.e(Constants.TAG, "A key could not be imported during multi-threaded import", e); - // do nothing? - if (e instanceof ExecutionException) { - // Since serialKeyRingImport does not throw any exceptions, this is what would have happened if - // we were importing the key on this thread - throw new RuntimeException(); - } - } - } - return accumulator.getConsolidatedResult(); - } - return null; // TODO: Decide if we should just crash instead of returning null - } - - /** - * Used to accumulate the results of individual key imports - */ - private class KeyImportAccumulator { - private OperationResult.OperationLog mImportLog = new OperationResult.OperationLog(); - Progressable mProgressable; - private int mTotalKeys; - private int mImportedKeys = 0; - ArrayList mImportedMasterKeyIds = new ArrayList(); - private int mBadKeys = 0; - private int mNewKeys = 0; - private int mUpdatedKeys = 0; - private int mSecret = 0; - private int mResultType = 0; - - /** - * Accumulates keyring imports and updates the progressable whenever a new key is imported. - * Also sets the progress to 0 on instantiation. - * - * @param totalKeys total number of keys to be imported - * @param externalProgressable the external progressable to be updated every time a key is imported - */ - public KeyImportAccumulator(int totalKeys, Progressable externalProgressable) { - mTotalKeys = totalKeys; - mProgressable = externalProgressable; - mProgressable.setProgress(0, totalKeys); - } - - public int getTotalKeys() { - return mTotalKeys; - } - - public int getImportedKeys() { - return mImportedKeys; - } - - public synchronized void accumulateKeyImport(ImportKeyResult result) { - mImportedKeys++; - - mProgressable.setProgress(mImportedKeys, mTotalKeys); - - mImportLog.addAll(result.getLog().toList());//accumulates log - mBadKeys += result.mBadKeys; - mNewKeys += result.mNewKeys; - mUpdatedKeys += result.mUpdatedKeys; - mSecret += result.mSecret; - - long[] masterKeyIds = result.getImportedMasterKeyIds(); - for (long masterKeyId : masterKeyIds) { - mImportedMasterKeyIds.add(masterKeyId); - } - - // if any key import has been cancelled, set result type to cancelled - // resultType is added to in getConsolidatedKayImport to account for remaining factors - mResultType |= result.getResult() & ImportKeyResult.RESULT_CANCELLED; - } - - /** - * returns accumulated result of all imports so far - */ - public ImportKeyResult getConsolidatedResult() { - - // adding required information to mResultType - // special case,no keys requested for import - if (mBadKeys == 0 && mNewKeys == 0 && mUpdatedKeys == 0) { - mResultType = ImportKeyResult.RESULT_FAIL_NOTHING; - } else { - if (mNewKeys > 0) { - mResultType |= ImportKeyResult.RESULT_OK_NEWKEYS; - } - if (mUpdatedKeys > 0) { - mResultType |= ImportKeyResult.RESULT_OK_UPDATED; - } - if (mBadKeys > 0) { - mResultType |= ImportKeyResult.RESULT_WITH_ERRORS; - if (mNewKeys == 0 && mUpdatedKeys == 0) { - mResultType |= ImportKeyResult.RESULT_ERROR; - } - } - if (mImportLog.containsWarnings()) { - mResultType |= ImportKeyResult.RESULT_WARNINGS; - } - } - - long masterKeyIds[] = new long[mImportedMasterKeyIds.size()]; - for (int i = 0; i < masterKeyIds.length; i++) { - masterKeyIds[i] = mImportedMasterKeyIds.get(i); - } - - return new ImportKeyResult(mResultType, mImportLog, mNewKeys, mUpdatedKeys, mBadKeys, - mSecret, masterKeyIds); - } - - public boolean isImportFinished() { - return mTotalKeys == mImportedKeys; - } - } - -} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java new file mode 100644 index 000000000..ace059dac --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java @@ -0,0 +1,565 @@ +/* + * Copyright (C) 2012-2014 Dominik Schürmann + * Copyright (C) 2010-2014 Thialfihar + * + * 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 . + */ + +package org.sufficientlysecure.keychain.operations; + +import android.content.Context; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; +import org.sufficientlysecure.keychain.keyimport.KeybaseKeyserver; +import org.sufficientlysecure.keychain.keyimport.Keyserver; +import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; +import org.sufficientlysecure.keychain.operations.results.ConsolidateResult; +import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; +import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; +import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult; +import org.sufficientlysecure.keychain.pgp.Progressable; +import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.ContactSyncAdapterService; +import org.sufficientlysecure.keychain.service.ImportKeyringParcel; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.ParcelableFileCache; +import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; +import org.sufficientlysecure.keychain.util.ProgressScaler; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * An operation class which implements high level import + * operations. + * This class receives a source and/or destination of keys as input and performs + * all steps for this import. + * For the import operation, the only valid source is an Iterator of + * ParcelableKeyRing, each of which must contain either a single + * keyring encoded as bytes, or a unique reference to a keyring + * on keyservers and/or keybase.io. + * It is important to note that public keys should generally be imported before + * secret keys, because some implementations (notably Symantec PGP Desktop) do + * not include self certificates for user ids in the secret keyring. The import + * method here will generally import keyrings in the order given by the + * iterator, so this should be ensured beforehand. + * + * @see org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter#getSelectedEntries() + */ +public class ImportOperation extends BaseOperation { + + public ImportOperation(Context context, ProviderHelper providerHelper, Progressable + progressable) { + super(context, providerHelper, progressable); + } + + public ImportOperation(Context context, ProviderHelper providerHelper, + Progressable progressable, AtomicBoolean cancelled) { + super(context, providerHelper, progressable, cancelled); + } + + // Overloaded functions for using progressable supplied in constructor during import + public ImportKeyResult serialKeyRingImport(Iterator entries, int num, + String keyServerUri) { + return serialKeyRingImport(entries, num, keyServerUri, mProgressable); + } + + public ImportKeyResult serialKeyRingImport(List entries, + String keyServerUri) { + + Iterator it = entries.iterator(); + int numEntries = entries.size(); + + return serialKeyRingImport(it, numEntries, keyServerUri, mProgressable); + + } + + public ImportKeyResult serialKeyRingImport(List entries, String keyServerUri, + Progressable progressable) { + + Iterator it = entries.iterator(); + int numEntries = entries.size(); + + return serialKeyRingImport(it, numEntries, keyServerUri, progressable); + + } + + public ImportKeyResult serialKeyRingImport(ParcelableFileCache cache, + String keyServerUri) { + + // get entries from cached file + try { + IteratorWithSize it = cache.readCache(); + int numEntries = it.getSize(); + + return serialKeyRingImport(it, numEntries, keyServerUri, mProgressable); + } catch (IOException e) { + + // Special treatment here, we need a lot + OperationLog log = new OperationLog(); + log.add(LogType.MSG_IMPORT, 0, 0); + log.add(LogType.MSG_IMPORT_ERROR_IO, 0, 0); + + return new ImportKeyResult(ImportKeyResult.RESULT_ERROR, log); + } + + } + + /** + * Since the introduction of multithreaded import, we expect calling functions to handle the + * key sync i,eContactSyncAdapterService.requestSync() + * + * @param entries keys to import + * @param num number of keys to import + * @param keyServerUri contains uri of keyserver to import from, if it is an import from cloud + * @param progressable Allows multi-threaded import to supply a progressable that ignores the + * progress of a single key being imported + * @return + */ + public ImportKeyResult serialKeyRingImport(Iterator entries, int num, + String keyServerUri, Progressable progressable) { + updateProgress(R.string.progress_importing, 0, 100); + + OperationLog log = new OperationLog(); + log.add(LogType.MSG_IMPORT, 0, num); + + // If there aren't even any keys, do nothing here. + if (entries == null || !entries.hasNext()) { + return new ImportKeyResult(ImportKeyResult.RESULT_FAIL_NOTHING, log); + } + + int newKeys = 0, updatedKeys = 0, badKeys = 0, secret = 0; + ArrayList importedMasterKeyIds = new ArrayList<>(); + + boolean cancelled = false; + int position = 0; + double progSteps = 100.0 / num; + + KeybaseKeyserver keybaseServer = null; + HkpKeyserver keyServer = null; + + // iterate over all entries + while (entries.hasNext()) { + ParcelableKeyRing entry = entries.next(); + + // Has this action been cancelled? If so, don't proceed any further + if (checkCancelled()) { + cancelled = true; + break; + } + + try { + + UncachedKeyRing key = null; + + // If there is already byte data, use that + if (entry.mBytes != null) { + key = UncachedKeyRing.decodeFromData(entry.mBytes); + } + // Otherwise, we need to fetch the data from a server first + else { + + // We fetch from keyservers first, because we tend to get more certificates + // from there, so the number of certificates which are merged in later is + // smaller. + + // If we have a keyServerUri and a fingerprint or at least a keyId, + // download from HKP + if (keyServerUri != null + && (entry.mKeyIdHex != null || entry.mExpectedFingerprint != null)) { + // Make sure we have the keyserver instance cached + if (keyServer == null) { + log.add(LogType.MSG_IMPORT_KEYSERVER, 1, keyServerUri); + keyServer = new HkpKeyserver(keyServerUri); + } + + try { + byte[] data; + // Download by fingerprint, or keyId - whichever is available + if (entry.mExpectedFingerprint != null) { + log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER, 2, "0x" + + entry.mExpectedFingerprint.substring(24)); + data = keyServer.get("0x" + entry.mExpectedFingerprint).getBytes(); + } else { + log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER, 2, entry.mKeyIdHex); + data = keyServer.get(entry.mKeyIdHex).getBytes(); + } + key = UncachedKeyRing.decodeFromData(data); + if (key != null) { + log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_OK, 3); + } else { + log.add(LogType.MSG_IMPORT_FETCH_ERROR_DECODE, 3); + } + } catch (Keyserver.QueryFailedException e) { + Log.e(Constants.TAG, "query failed", e); + log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_ERROR, 3, e.getMessage()); + } + } + + // If we have a keybase name, try to fetch from there + if (entry.mKeybaseName != null) { + // Make sure we have this cached + if (keybaseServer == null) { + keybaseServer = new KeybaseKeyserver(); + } + + try { + log.add(LogType.MSG_IMPORT_FETCH_KEYBASE, 2, entry.mKeybaseName); + byte[] data = keybaseServer.get(entry.mKeybaseName).getBytes(); + UncachedKeyRing keybaseKey = UncachedKeyRing.decodeFromData(data); + + // If there already is a key, merge the two + if (key != null && keybaseKey != null) { + log.add(LogType.MSG_IMPORT_MERGE, 3); + keybaseKey = key.merge(keybaseKey, log, 4); + // If the merge didn't fail, use the new merged key + if (keybaseKey != null) { + key = keybaseKey; + } else { + log.add(LogType.MSG_IMPORT_MERGE_ERROR, 4); + } + } else if (keybaseKey != null) { + key = keybaseKey; + } + } catch (Keyserver.QueryFailedException e) { + // download failed, too bad. just proceed + Log.e(Constants.TAG, "query failed", e); + log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_ERROR, 3, e.getMessage()); + } + } + } + + if (key == null) { + log.add(LogType.MSG_IMPORT_FETCH_ERROR, 2); + badKeys += 1; + continue; + } + + // If we have an expected fingerprint, make sure it matches + if (entry.mExpectedFingerprint != null) { + if (!key.containsSubkey(entry.mExpectedFingerprint)) { + log.add(LogType.MSG_IMPORT_FINGERPRINT_ERROR, 2); + badKeys += 1; + continue; + } else { + log.add(LogType.MSG_IMPORT_FINGERPRINT_OK, 2); + } + } + + // Another check if we have been cancelled + if (checkCancelled()) { + cancelled = true; + break; + } + + SaveKeyringResult result; + mProviderHelper.clearLog(); + if (key.isSecret()) { + result = mProviderHelper.saveSecretKeyRing(key, + new ProgressScaler(progressable, (int) (position * progSteps), + (int) ((position + 1) * progSteps), 100)); + } else { + result = mProviderHelper.savePublicKeyRing(key, + new ProgressScaler(progressable, (int) (position * progSteps), + (int) ((position + 1) * progSteps), 100)); + } + if (!result.success()) { + badKeys += 1; + } else if (result.updated()) { + updatedKeys += 1; + importedMasterKeyIds.add(key.getMasterKeyId()); + } else { + newKeys += 1; + if (key.isSecret()) { + secret += 1; + } + importedMasterKeyIds.add(key.getMasterKeyId()); + } + + log.add(result, 2); + + } catch (IOException | PgpGeneralException e) { + Log.e(Constants.TAG, "Encountered bad key on import!", e); + ++badKeys; + } + // update progress + position++; + } + + // Special: consolidate on secret key import (cannot be cancelled!) + if (secret > 0) { + setPreventCancel(); + ConsolidateResult result = mProviderHelper.consolidateDatabaseStep1(progressable); + log.add(result, 1); + } + + // Special: make sure new data is synced into contacts + // disabling sync right now since it reduces speed while multi-threading + // so, we expect calling functions to take care of it. KeychainService handles this + // ContactSyncAdapterService.requestSync(); + + // convert to long array + long[] importedMasterKeyIdsArray = new long[importedMasterKeyIds.size()]; + for (int i = 0; i < importedMasterKeyIds.size(); ++i) { + importedMasterKeyIdsArray[i] = importedMasterKeyIds.get(i); + } + + int resultType = 0; + if (cancelled) { + log.add(LogType.MSG_OPERATION_CANCELLED, 1); + resultType |= ImportKeyResult.RESULT_CANCELLED; + } + + // special return case: no new keys at all + if (badKeys == 0 && newKeys == 0 && updatedKeys == 0) { + resultType = ImportKeyResult.RESULT_FAIL_NOTHING; + } else { + if (newKeys > 0) { + resultType |= ImportKeyResult.RESULT_OK_NEWKEYS; + } + if (updatedKeys > 0) { + resultType |= ImportKeyResult.RESULT_OK_UPDATED; + } + if (badKeys > 0) { + resultType |= ImportKeyResult.RESULT_WITH_ERRORS; + if (newKeys == 0 && updatedKeys == 0) { + resultType |= ImportKeyResult.RESULT_ERROR; + } + } + if (log.containsWarnings()) { + resultType |= ImportKeyResult.RESULT_WARNINGS; + } + } + + // Final log entry, it's easier to do this individually + if ((newKeys > 0 || updatedKeys > 0) && badKeys > 0) { + log.add(LogType.MSG_IMPORT_PARTIAL, 1); + } else if (newKeys > 0 || updatedKeys > 0) { + log.add(LogType.MSG_IMPORT_SUCCESS, 1); + } else { + log.add(LogType.MSG_IMPORT_ERROR, 1); + } + + return new ImportKeyResult(resultType, log, newKeys, updatedKeys, badKeys, secret, + importedMasterKeyIdsArray); + } + + @Override + public ImportKeyResult execute(ImportKeyringParcel importInput, CryptoInputParcel cryptoInput) { + return importKeys(importInput.mKeyList, importInput.mKeyserver); + } + + public ImportKeyResult importKeys(ArrayList keyList, String keyServer) { + + ImportKeyResult result; + + if (keyList == null) {// import from file, do serially + ParcelableFileCache cache = new ParcelableFileCache<>(mContext, + "key_import.pcl"); + + result = serialKeyRingImport(cache, keyServer); + } else { + // if there is more than one key with the same fingerprint, we do a serial import to + // prevent + // https://github.com/open-keychain/open-keychain/issues/1221 + HashSet keyFingerprintSet = new HashSet<>(); + for (int i = 0; i < keyList.size(); i++) { + keyFingerprintSet.add(keyList.get(i).mExpectedFingerprint); + } + if (keyFingerprintSet.size() == keyList.size()) { + // all keys have unique fingerprints + result = multiThreadedKeyImport(keyList.iterator(), keyList.size(), keyServer); + } else { + result = serialKeyRingImport(keyList, keyServer); + } + } + + ContactSyncAdapterService.requestSync(); + return result; + } + + private ImportKeyResult multiThreadedKeyImport(Iterator keyListIterator, + int totKeys, final String keyServer) { + Log.d(Constants.TAG, "Multi-threaded key import starting"); + if (keyListIterator != null) { + KeyImportAccumulator accumulator = new KeyImportAccumulator(totKeys, mProgressable); + + final ProgressScaler ignoreProgressable = new ProgressScaler(); + + final int maxThreads = 200; + ExecutorService importExecutor = new ThreadPoolExecutor(0, maxThreads, + 30L, TimeUnit.SECONDS, + new SynchronousQueue()); + + ExecutorCompletionService importCompletionService = + new ExecutorCompletionService(importExecutor); + + while (keyListIterator.hasNext()) { // submit all key rings to be imported + + final ParcelableKeyRing pkRing = keyListIterator.next(); + + Callable importOperationCallable = new Callable + () { + + @Override + public ImportKeyResult call() { + + ArrayList list = new ArrayList<>(); + list.add(pkRing); + + return serialKeyRingImport(list, keyServer, ignoreProgressable); + } + }; + + importCompletionService.submit(importOperationCallable); + } + + while (!accumulator.isImportFinished()) { // accumulate the results of each import + try { + accumulator.accumulateKeyImport(importCompletionService.take().get()); + } catch (InterruptedException | ExecutionException e) { + Log.e(Constants.TAG, "A key could not be imported during multi-threaded " + + "import", e); + // do nothing? + if (e instanceof ExecutionException) { + // Since serialKeyRingImport does not throw any exceptions, this is what + // would have happened if + // we were importing the key on this thread + throw new RuntimeException(); + } + } + } + return accumulator.getConsolidatedResult(); + } + return null; // TODO: Decide if we should just crash instead of returning null + } + + /** + * Used to accumulate the results of individual key imports + */ + private class KeyImportAccumulator { + private OperationResult.OperationLog mImportLog = new OperationResult.OperationLog(); + Progressable mProgressable; + private int mTotalKeys; + private int mImportedKeys = 0; + ArrayList mImportedMasterKeyIds = new ArrayList(); + private int mBadKeys = 0; + private int mNewKeys = 0; + private int mUpdatedKeys = 0; + private int mSecret = 0; + private int mResultType = 0; + + /** + * Accumulates keyring imports and updates the progressable whenever a new key is imported. + * Also sets the progress to 0 on instantiation. + * + * @param totalKeys total number of keys to be imported + * @param externalProgressable the external progressable to be updated every time a key + * is imported + */ + public KeyImportAccumulator(int totalKeys, Progressable externalProgressable) { + mTotalKeys = totalKeys; + mProgressable = externalProgressable; + mProgressable.setProgress(0, totalKeys); + } + + public int getTotalKeys() { + return mTotalKeys; + } + + public int getImportedKeys() { + return mImportedKeys; + } + + public synchronized void accumulateKeyImport(ImportKeyResult result) { + mImportedKeys++; + + mProgressable.setProgress(mImportedKeys, mTotalKeys); + + mImportLog.addAll(result.getLog().toList());//accumulates log + mBadKeys += result.mBadKeys; + mNewKeys += result.mNewKeys; + mUpdatedKeys += result.mUpdatedKeys; + mSecret += result.mSecret; + + long[] masterKeyIds = result.getImportedMasterKeyIds(); + for (long masterKeyId : masterKeyIds) { + mImportedMasterKeyIds.add(masterKeyId); + } + + // if any key import has been cancelled, set result type to cancelled + // resultType is added to in getConsolidatedKayImport to account for remaining factors + mResultType |= result.getResult() & ImportKeyResult.RESULT_CANCELLED; + } + + /** + * returns accumulated result of all imports so far + */ + public ImportKeyResult getConsolidatedResult() { + + // adding required information to mResultType + // special case,no keys requested for import + if (mBadKeys == 0 && mNewKeys == 0 && mUpdatedKeys == 0) { + mResultType = ImportKeyResult.RESULT_FAIL_NOTHING; + } else { + if (mNewKeys > 0) { + mResultType |= ImportKeyResult.RESULT_OK_NEWKEYS; + } + if (mUpdatedKeys > 0) { + mResultType |= ImportKeyResult.RESULT_OK_UPDATED; + } + if (mBadKeys > 0) { + mResultType |= ImportKeyResult.RESULT_WITH_ERRORS; + if (mNewKeys == 0 && mUpdatedKeys == 0) { + mResultType |= ImportKeyResult.RESULT_ERROR; + } + } + if (mImportLog.containsWarnings()) { + mResultType |= ImportKeyResult.RESULT_WARNINGS; + } + } + + long masterKeyIds[] = new long[mImportedMasterKeyIds.size()]; + for (int i = 0; i < masterKeyIds.length; i++) { + masterKeyIds[i] = mImportedMasterKeyIds.get(i); + } + + return new ImportKeyResult(mResultType, mImportLog, mNewKeys, mUpdatedKeys, mBadKeys, + mSecret, masterKeyIds); + } + + public boolean isImportFinished() { + return mTotalKeys == mImportedKeys; + } + } + +} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 5fbc7f6c7..590c58f97 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -32,7 +32,7 @@ import org.spongycastle.bcpg.CompressionAlgorithmTags; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; -import org.sufficientlysecure.keychain.operations.ImportExportOperation; +import org.sufficientlysecure.keychain.operations.ImportOperation; import org.sufficientlysecure.keychain.operations.results.ConsolidateResult; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; @@ -1248,7 +1248,7 @@ public class ProviderHelper { // 3. Re-Import secret keyrings from cache if (numSecrets > 0) { - ImportKeyResult result = new ImportExportOperation(mContext, this, + ImportKeyResult result = new ImportOperation(mContext, this, new ProgressFixedScaler(progress, 10, 25, 100, R.string.progress_con_reimport)) .serialKeyRingImport(itSecrets, numSecrets, null); log.add(result, indent); @@ -1276,7 +1276,7 @@ public class ProviderHelper { // 4. Re-Import public keyrings from cache if (numPublics > 0) { - ImportKeyResult result = new ImportExportOperation(mContext, this, + ImportKeyResult result = new ImportOperation(mContext, this, new ProgressFixedScaler(progress, 25, 99, 100, R.string.progress_con_reimport)) .serialKeyRingImport(itPublics, numPublics, null); log.add(result, indent); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ExportKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ExportKeyringParcel.java index 236f7f0e3..ef5b48df3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ExportKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ExportKeyringParcel.java @@ -23,7 +23,7 @@ import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; -public class ExportKeyringParcel extends ImportExportParcel implements Parcelable { +public class ExportKeyringParcel implements Parcelable { public String mKeyserver; public Uri mCanonicalizedPublicKeyringUri; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportExportParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportExportParcel.java deleted file mode 100644 index 2e14cc6b6..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportExportParcel.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2015 Dominik Schürmann - * Copyright (C) 2015 Vincent Breitmoser - * Copyright (C) 2015 Adithya Abraham Philip - * - * 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 . - */ - -package org.sufficientlysecure.keychain.service; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Empty class, simply serves as a base class for ImportKeyringParcel and ExportKeyringParcel - */ -public class ImportExportParcel implements Parcelable { - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportKeyringParcel.java index 0b7149c75..a41dd71cb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportKeyringParcel.java @@ -24,7 +24,7 @@ import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import java.util.ArrayList; -public class ImportKeyringParcel extends ImportExportParcel { +public class ImportKeyringParcel implements Parcelable { // if null, keys are expected to be read from a cache file in ImportExportOperations public ArrayList mKeyList; public String mKeyserver; // must be set if keys are to be imported from a keyserver diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java index 6a74520db..1cd76b462 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java @@ -33,7 +33,8 @@ import org.sufficientlysecure.keychain.operations.CertifyOperation; import org.sufficientlysecure.keychain.operations.ConsolidateOperation; import org.sufficientlysecure.keychain.operations.DeleteOperation; import org.sufficientlysecure.keychain.operations.EditKeyOperation; -import org.sufficientlysecure.keychain.operations.ImportExportOperation; +import org.sufficientlysecure.keychain.operations.ExportOperation; +import org.sufficientlysecure.keychain.operations.ImportOperation; import org.sufficientlysecure.keychain.operations.KeybaseVerificationOperation; import org.sufficientlysecure.keychain.operations.PromoteKeyOperation; import org.sufficientlysecure.keychain.operations.SignEncryptOperation; @@ -121,10 +122,12 @@ public class KeychainService extends Service implements Progressable { } else if (inputParcel instanceof PromoteKeyringParcel) { op = new PromoteKeyOperation(outerThis, new ProviderHelper(outerThis), outerThis, mActionCanceled); - } else if (inputParcel instanceof ImportKeyringParcel - || inputParcel instanceof ExportKeyringParcel) { - op = new ImportExportOperation(outerThis, new ProviderHelper(outerThis), - outerThis, mActionCanceled); + } else if (inputParcel instanceof ImportKeyringParcel) { + op = new ImportOperation(outerThis, new ProviderHelper(outerThis), outerThis, + mActionCanceled); + } else if (inputParcel instanceof ExportKeyringParcel) { + op = new ExportOperation(outerThis, new ProviderHelper(outerThis), outerThis, + mActionCanceled); } else if (inputParcel instanceof ConsolidateInputParcel) { op = new ConsolidateOperation(outerThis, new ProviderHelper(outerThis), outerThis); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index db88de676..93c6593ab 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -33,6 +33,7 @@ import android.widget.TextView; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; +import org.sufficientlysecure.keychain.operations.ImportOperation; import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.ui.util.FormattingUtils; import org.sufficientlysecure.keychain.ui.util.Highlighter; @@ -92,8 +93,8 @@ public class ImportKeysAdapter extends ArrayAdapter { } /** This method returns a list of all selected entries, with public keys sorted - * before secret keys, see ImportExportOperation for specifics. - * @see org.sufficientlysecure.keychain.operations.ImportExportOperation + * before secret keys, see ImportOperation for specifics. + * @see ImportOperation */ public ArrayList getSelectedEntries() { ArrayList result = new ArrayList<>(); diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java index fa1288e08..a659dc7da 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/ExportTest.java @@ -30,7 +30,6 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowLog; import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.jce.provider.BouncyCastleProvider; -import org.sufficientlysecure.keychain.BuildConfig; import org.sufficientlysecure.keychain.WorkaroundBuildConfig; import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult; import org.sufficientlysecure.keychain.operations.results.ExportResult; @@ -127,7 +126,7 @@ public class ExportTest { @Test public void testExportAll() throws Exception { - ImportExportOperation op = new ImportExportOperation(RuntimeEnvironment.application, + ExportOperation op = new ExportOperation(RuntimeEnvironment.application, new ProviderHelper(RuntimeEnvironment.application), null); // make sure there is a local cert (so the later checks that there are none are meaningful) -- cgit v1.2.3 From 4b2e85794f691d6b71001d2394df17c0ba5b1227 Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Sat, 27 Jun 2015 02:37:56 +0530 Subject: changed to work with multi-decrypt --- .../keychain/ui/ConsolidateDialogActivity.java | 5 + .../keychain/ui/CreateKeyFinalFragment.java | 5 + .../keychain/ui/DecryptFilesFragment.java | 216 --------------------- .../keychain/ui/DecryptFragment.java | 5 + .../keychain/ui/DecryptListFragment.java | 6 - .../keychain/ui/ImportKeysActivity.java | 5 + .../keychain/ui/ImportKeysProxyActivity.java | 5 + .../keychain/ui/KeyListFragment.java | 10 + .../keychain/ui/SafeSlingerActivity.java | 5 + .../keychain/ui/UploadKeyActivity.java | 5 + .../keychain/ui/ViewKeyActivity.java | 5 + .../keychain/ui/ViewKeyTrustFragment.java | 5 + .../keychain/ui/base/CryptoOperationFragment.java | 16 +- .../keychain/ui/base/CryptoOperationHelper.java | 24 ++- .../ui/dialog/DeleteKeyDialogFragment.java | 5 + .../keychain/util/ExportHelper.java | 5 + 16 files changed, 99 insertions(+), 228 deletions(-) delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java index b3a447c84..7a473e49f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java @@ -86,4 +86,9 @@ public class ConsolidateDialogActivity extends FragmentActivity // don't care about result (for now?) ConsolidateDialogActivity.this.finish(); } + + @Override + public boolean onCryptoSetProgress(String msg, int progress, int max) { + return false; + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java index 1cf4b5a56..a045b34f5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -268,6 +268,11 @@ public class CreateKeyFinalFragment getActivity().setResult(Activity.RESULT_OK, data); getActivity().finish(); } + + @Override + public boolean onCryptoSetProgress(String msg, int progress, int max) { + return false; + } }; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java deleted file mode 100644 index fcad560ad..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * - * 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 . - */ - -package org.sufficientlysecure.keychain.ui; - -import android.app.Activity; -import android.content.Intent; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.text.TextUtils; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CheckBox; -import android.widget.TextView; - -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; -import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; -import org.sufficientlysecure.keychain.ui.util.Notify; -import org.sufficientlysecure.keychain.util.FileHelper; - -import java.io.File; - -public class DecryptFilesFragment extends DecryptFragment { - public static final String ARG_URI = "uri"; - public static final String ARG_OPEN_DIRECTLY = "open_directly"; - - private static final int REQUEST_CODE_INPUT = 0x00007003; - private static final int REQUEST_CODE_OUTPUT = 0x00007007; - - // view - private TextView mFilename; - private CheckBox mDeleteAfter; - private View mDecryptButton; - - // model - private Uri mInputUri = null; - private Uri mOutputUri = null; - - /** - * Creates new instance of this fragment - */ - public static DecryptFilesFragment newInstance(Uri uri, boolean openDirectly) { - DecryptFilesFragment frag = new DecryptFilesFragment(); - - Bundle args = new Bundle(); - args.putParcelable(ARG_URI, uri); - args.putBoolean(ARG_OPEN_DIRECTLY, openDirectly); - - frag.setArguments(args); - - return frag; - } - - /** - * Inflate the layout for this fragment - */ - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.decrypt_files_fragment, container, false); - - mFilename = (TextView) view.findViewById(R.id.decrypt_files_filename); - mDeleteAfter = (CheckBox) view.findViewById(R.id.decrypt_files_delete_after_decryption); - mDecryptButton = view.findViewById(R.id.decrypt_files_action_decrypt); - view.findViewById(R.id.decrypt_files_browse).setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - FileHelper.openDocument(DecryptFilesFragment.this, "*/*", REQUEST_CODE_INPUT); - } else { - FileHelper.openFile(DecryptFilesFragment.this, mInputUri, "*/*", - REQUEST_CODE_INPUT); - } - } - }); - mDecryptButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - decryptAction(); - } - }); - - return view; - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - - outState.putParcelable(ARG_URI, mInputUri); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - Bundle state = savedInstanceState != null ? savedInstanceState : getArguments(); - setInputUri(state.getParcelable(ARG_URI)); - - // should only come from args - if (state.getBoolean(ARG_OPEN_DIRECTLY, false)) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - FileHelper.openDocument(DecryptFilesFragment.this, "*/*", REQUEST_CODE_INPUT); - } else { - FileHelper.openFile(DecryptFilesFragment.this, mInputUri, "*/*", REQUEST_CODE_INPUT); - } - } - } - - private void setInputUri(Uri inputUri) { - if (inputUri == null) { - mInputUri = null; - mFilename.setText(""); - return; - } - - mInputUri = inputUri; - mFilename.setText(FileHelper.getFilename(getActivity(), mInputUri)); - } - - private void decryptAction() { - if (mInputUri == null) { - Notify.create(getActivity(), R.string.no_file_selected, Notify.Style.ERROR).show(); - return; - } - - cryptoOperation(); - } - - private String removeEncryptedAppend(String name) { - if (name.endsWith(Constants.FILE_EXTENSION_ASC) - || name.endsWith(Constants.FILE_EXTENSION_PGP_MAIN) - || name.endsWith(Constants.FILE_EXTENSION_PGP_ALTERNATE)) { - return name.substring(0, name.length() - 4); - } - return name; - } - - private void askForOutputFilename(String originalFilename) { - if (TextUtils.isEmpty(originalFilename)) { - originalFilename = removeEncryptedAppend(FileHelper.getFilename(getActivity(), mInputUri)); - } - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { - File file = new File(mInputUri.getPath()); - File parentDir = file.exists() ? file.getParentFile() : Constants.Path.APP_DIR; - File targetFile = new File(parentDir, originalFilename); - FileHelper.saveFile(this, getString(R.string.title_decrypt_to_file), - getString(R.string.specify_file_to_decrypt_to), targetFile, REQUEST_CODE_OUTPUT); - } else { - FileHelper.saveDocument(this, "*/*", originalFilename, REQUEST_CODE_OUTPUT); - } - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - switch (requestCode) { - case REQUEST_CODE_INPUT: { - if (resultCode == Activity.RESULT_OK && data != null) { - setInputUri(data.getData()); - } - return; - } - - case REQUEST_CODE_OUTPUT: { - // This happens after output file was selected, so start our operation - if (resultCode == Activity.RESULT_OK && data != null) { - mOutputUri = data.getData(); - cryptoOperation(); - } - return; - } - - default: { - super.onActivityResult(requestCode, resultCode, data); - } - } - } - - @Override - protected void onVerifyLoaded(boolean hideErrorOverlay) { - - } - - @Override - protected PgpDecryptVerifyInputParcel createOperationInput() { - return new PgpDecryptVerifyInputParcel(mInputUri, mOutputUri).setAllowSymmetricDecryption(true); - } - - @Override - protected void onCryptoOperationSuccess(DecryptVerifyResult result) { - - // display signature result in activity - loadVerifyResult(result); - - // TODO delete after decrypt not implemented! - - } - -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java index 9cfe1651c..4eb8cd5e8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java @@ -182,6 +182,11 @@ public abstract class DecryptFragment extends Fragment implements LoaderManager. public void onCryptoOperationError(ImportKeyResult result) { result.createNotify(getActivity()).show(); } + + @Override + public boolean onCryptoSetProgress(String msg, int progress, int max) { + return false; + } }; mImportOpHelper = new CryptoOperationHelper<>(this, callback, R.string.progress_importing); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java index d2bff8336..d70af4058 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java @@ -258,12 +258,6 @@ public class DecryptListFragment mAdapter.setProgress(mCurrentInputUri, progress, max, msg); return true; } - - @Override - protected void dismissProgress() { - // progress shown inline, so never mind - } - @Override protected void onCryptoOperationError(DecryptVerifyResult result) { final Uri uri = mCurrentInputUri; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index b05cc6f50..ba4f759e6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -502,4 +502,9 @@ public class ImportKeysActivity extends BaseNfcActivity public void onCryptoOperationError(ImportKeyResult result) { handleResult(result); } + + @Override + public boolean onCryptoSetProgress(String msg, int progress, int max) { + return false; + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java index 0a7bd726a..da713d0d8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java @@ -259,6 +259,11 @@ public class ImportKeysProxyActivity extends FragmentActivity return; } + @Override + public boolean onCryptoSetProgress(String msg, int progress, int max) { + return false; + } + /** * NFC: Parses the NDEF Message from the intent and prints to the TextView */ diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index d80e3db39..e038cf948 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -631,6 +631,11 @@ public class KeyListFragment extends LoaderFragment public void onCryptoOperationError(ConsolidateResult result) { result.createNotify(getActivity()).show(); } + + @Override + public boolean onCryptoSetProgress(String msg, int progress, int max) { + return false; + } }; mConsolidateOpHelper = @@ -749,6 +754,11 @@ public class KeyListFragment extends LoaderFragment result.createNotify(getActivity()).show(); } + @Override + public boolean onCryptoSetProgress(String msg, int progress, int max) { + return false; + } + public class KeyListAdapter extends KeyAdapter implements StickyListHeadersAdapter { private HashMap mSelection = new HashMap<>(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java index 240dbe7ad..a1cb77546 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java @@ -208,4 +208,9 @@ public class SafeSlingerActivity extends BaseActivity setResult(RESULT_OK, data); finish(); } + + @Override + public boolean onCryptoSetProgress(String msg, int progress, int max) { + return false; + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java index a4215c67d..8b49f3b96 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java @@ -145,4 +145,9 @@ public class UploadKeyActivity extends BaseActivity public void onCryptoOperationError(ExportResult result) { // TODO: Implement proper log for key upload then show error } + + @Override + public boolean onCryptoSetProgress(String msg, int progress, int max) { + return false; + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 4b157590d..d3849c892 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -986,4 +986,9 @@ public class ViewKeyActivity extends BaseNfcActivity implements mIsRefreshing = false; result.createNotify(this).show(); } + + @Override + public boolean onCryptoSetProgress(String msg, int progress, int max) { + return false; + } } \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java index 03f8ca447..6052eec16 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java @@ -471,6 +471,11 @@ public class ViewKeyTrustFragment extends LoaderFragment implements displaySpannableResult(ssb); } + @Override + public boolean onCryptoSetProgress(String msg, int progress, int max) { + return false; + } + private void displaySpannableResult(SpannableStringBuilder ssb) { mProofVerifyHeader.setVisibility(View.VISIBLE); mProofVerifyDetail.setVisibility(View.VISIBLE); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java index b3828c428..31450c841 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java @@ -57,6 +57,12 @@ public abstract class CryptoOperationFragment(this, callback); @@ -79,7 +85,15 @@ public abstract class CryptoOperationFragment Date: Tue, 30 Jun 2015 20:22:00 +0530 Subject: made CryptoOperationFragment implement OperationHelper.Callback --- .../keychain/ui/CertifyKeyFragment.java | 6 +-- .../keychain/ui/CreateKeyFinalFragment.java | 4 +- .../ui/CreateKeyYubiKeyImportFragment.java | 4 +- .../keychain/ui/DecryptListFragment.java | 8 ++-- .../keychain/ui/EditKeyFragment.java | 4 +- .../keychain/ui/EncryptFilesFragment.java | 4 +- .../keychain/ui/EncryptTextFragment.java | 4 +- .../keychain/ui/ViewKeyYubiKeyFragment.java | 2 +- .../ui/base/CachingCryptoOperationFragment.java | 4 +- .../keychain/ui/base/CryptoOperationFragment.java | 50 ++++++---------------- .../keychain/ui/base/CryptoOperationHelper.java | 2 +- 11 files changed, 33 insertions(+), 59 deletions(-) (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java index c92ee10df..891c2268c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java @@ -295,7 +295,7 @@ public class CertifyKeyFragment } @Override - protected CertifyActionsParcel createOperationInput() { + public CertifyActionsParcel createOperationInput() { // Bail out if there is not at least one user id selected ArrayList certifyActions = mUserIdsAdapter.getSelectedCertifyActions(); @@ -318,7 +318,7 @@ public class CertifyKeyFragment } @Override - protected void onCryptoOperationSuccess(CertifyResult result) { + public void onCryptoOperationSuccess(CertifyResult result) { Intent intent = new Intent(); intent.putExtra(CertifyResult.EXTRA_RESULT, result); getActivity().setResult(Activity.RESULT_OK, intent); @@ -326,7 +326,7 @@ public class CertifyKeyFragment } @Override - protected void onCryptoOperationCancelled() { + public void onCryptoOperationCancelled() { super.onCryptoOperationCancelled(); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java index a045b34f5..c420e5af9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -151,12 +151,12 @@ public class CreateKeyFinalFragment } @Override - protected SaveKeyringParcel createOperationInput() { + public SaveKeyringParcel createOperationInput() { return mSaveKeyringParcel; } @Override - protected void onCryptoOperationSuccess(EditKeyResult result) { + public void onCryptoOperationSuccess(EditKeyResult result) { if (result.mMasterKeyId != null && mUploadCheckbox.isChecked()) { // result will be displayed after upload uploadKey(result); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java index f9ddd9e73..7997d8025 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java @@ -211,12 +211,12 @@ public class CreateKeyYubiKeyImportFragment } @Override - protected ImportKeyringParcel createOperationInput() { + public ImportKeyringParcel createOperationInput() { return new ImportKeyringParcel(mKeyList, mKeyserver); } @Override - protected void onCryptoOperationSuccess(ImportKeyResult result) { + public void onCryptoOperationSuccess(ImportKeyResult result) { long[] masterKeyIds = result.getImportedMasterKeyIds(); if (masterKeyIds.length == 0) { super.onCryptoOperationError(result); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java index d70af4058..96767463e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java @@ -254,12 +254,12 @@ public class DecryptListFragment } @Override - protected boolean onCryptoSetProgress(String msg, int progress, int max) { + public boolean onCryptoSetProgress(String msg, int progress, int max) { mAdapter.setProgress(mCurrentInputUri, progress, max, msg); return true; } @Override - protected void onCryptoOperationError(DecryptVerifyResult result) { + public void onCryptoOperationError(DecryptVerifyResult result) { final Uri uri = mCurrentInputUri; mCurrentInputUri = null; @@ -269,7 +269,7 @@ public class DecryptListFragment } @Override - protected void onCryptoOperationSuccess(DecryptVerifyResult result) { + public void onCryptoOperationSuccess(DecryptVerifyResult result) { Uri uri = mCurrentInputUri; mCurrentInputUri = null; @@ -433,7 +433,7 @@ public class DecryptListFragment } @Override - protected PgpDecryptVerifyInputParcel createOperationInput() { + public PgpDecryptVerifyInputParcel createOperationInput() { if (mCurrentInputUri == null) { if (mPendingInputUris.isEmpty()) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index 2cd916544..1363d44f2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -607,12 +607,12 @@ public class EditKeyFragment extends CryptoOperationFragment finish, return result to showkey and display there! Intent intent = new Intent(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java index d7c6b2049..215af5885 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java @@ -386,7 +386,7 @@ public class EncryptFilesFragment } @Override - protected void onCryptoOperationSuccess(final SignEncryptResult result) { + public void onCryptoOperationSuccess(final SignEncryptResult result) { if (mDeleteAfterEncrypt) { // TODO make behavior coherent here @@ -485,7 +485,7 @@ public class EncryptFilesFragment } - protected SignEncryptParcel createOperationInput() { + public SignEncryptParcel createOperationInput() { SignEncryptParcel actionsParcel = getCachedActionsParcel(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java index e0629eb73..886c52651 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java @@ -202,7 +202,7 @@ public class EncryptTextFragment } - protected SignEncryptParcel createOperationInput() { + public SignEncryptParcel createOperationInput() { if (mMessage == null || mMessage.isEmpty()) { Notify.create(getActivity(), R.string.error_empty_text, Notify.Style.ERROR) @@ -316,7 +316,7 @@ public class EncryptTextFragment } @Override - protected void onCryptoOperationSuccess(SignEncryptResult result) { + public void onCryptoOperationSuccess(SignEncryptResult result) { if (mShareAfterEncrypt) { // Share encrypted message/file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java index 10ce679f6..f8c3b59ea 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java @@ -205,7 +205,7 @@ public class ViewKeyYubiKeyFragment } @Override - protected PromoteKeyringParcel createOperationInput() { + public PromoteKeyringParcel createOperationInput() { return new PromoteKeyringParcel(mMasterKeyId, mCardAid, mSubKeyIds); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java index 0f9601153..17e4e6ede 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CachingCryptoOperationFragment.java @@ -37,7 +37,7 @@ public abstract class CachingCryptoOperationFragment - extends Fragment { + extends Fragment implements CryptoOperationHelper.Callback { private CryptoOperationHelper mOperationHelper; public CryptoOperationFragment() { - // this is implemented here instead of by the fragment so that the corresponding methods in - // CryptoOperationFragment may continue using the "protected" modifier. - CryptoOperationHelper.Callback callback = new CryptoOperationHelper.Callback() { - - @Override - public T createOperationInput() { - return CryptoOperationFragment.this.createOperationInput(); - } - - @Override - public void onCryptoOperationSuccess(S result) { - CryptoOperationFragment.this.onCryptoOperationSuccess(result); - } - - @Override - public void onCryptoOperationCancelled() { - CryptoOperationFragment.this.onCryptoOperationCancelled(); - } - - @Override - public void onCryptoOperationError(S result) { - CryptoOperationFragment.this.onCryptoOperationError(result); - } - - @Override - public boolean onCryptoSetProgress(String msg, int progress, int max) { - return CryptoOperationFragment.this.onCryptoSetProgress(msg, progress, max); - } - - }; - - mOperationHelper = new CryptoOperationHelper<>(this, callback); + + mOperationHelper = new CryptoOperationHelper<>(this, this); } public void setProgressMessageResource(int id) { @@ -78,7 +48,8 @@ public abstract class CryptoOperationFragment { - public interface Callback { + public interface Callback { T createOperationInput(); void onCryptoOperationSuccess(S result); void onCryptoOperationCancelled(); -- cgit v1.2.3