diff options
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service')
9 files changed, 485 insertions, 808 deletions
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..15d109814 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ConsolidateInputParcel.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de> + * Copyright (C) 2015 Vincent Breitmoser <v.breitmoser@mugenguild.com> + * Copyright (C) 2015 Adithya Abraham Philip <adithyaphilip@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.service; + +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<ConsolidateInputParcel> CREATOR = new Parcelable.Creator<ConsolidateInputParcel>() { + @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/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 <dominik@dominikschuermann.de> + * Copyright (C) 2015 Vincent Breitmoser <v.breitmoser@mugenguild.com> + * Copyright (C) 2015 Adithya Abraham Philip <adithyaphilip@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.service; + +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<DeleteKeyringParcel> CREATOR = new Parcelable.Creator<DeleteKeyringParcel>() { + @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 new file mode 100644 index 000000000..ef5b48df3 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ExportKeyringParcel.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de> + * Copyright (C) 2015 Vincent Breitmoser <v.breitmoser@mugenguild.com> + * Copyright (C) 2015 Adithya Abraham Philip <adithyaphilip@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.service; + +import android.net.Uri; +import android.os.Parcel; +import android.os.Parcelable; + +public class ExportKeyringParcel 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<ExportKeyringParcel> CREATOR = new Parcelable.Creator<ExportKeyringParcel>() { + @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/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 <dominik@dominikschuermann.de> + * Copyright (C) 2015 Adithya Abraham Philip <adithyaphilip@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.service; + +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<ParcelableKeyRing> mKeyList; + public String mKeyserver; // must be set if keys are to be imported from a keyserver + + public ImportKeyringParcel (ArrayList<ParcelableKeyRing> 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<ImportKeyringParcel> CREATOR = new Parcelable.Creator<ImportKeyringParcel>() { + @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/KeybaseVerificationParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeybaseVerificationParcel.java new file mode 100644 index 000000000..1872191af --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeybaseVerificationParcel.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de> + * Copyright (C) 2015 Vincent Breitmoser <v.breitmoser@mugenguild.com> + * Copyright (C) 2015 Adithya Abraham Philip <adithyaphilip@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.service; + +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<KeybaseVerificationParcel> CREATOR = new Parcelable.Creator<KeybaseVerificationParcel>() { + @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 deleted file mode 100644 index 9e33a1421..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainNewService.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de> - * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package org.sufficientlysecure.keychain.service; - - -import java.util.concurrent.atomic.AtomicBoolean; - -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.EditKeyOperation; -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.util.Log; - -/** - * 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"; - - // this attribute can possibly merged with the one above? not sure... - private AtomicBoolean mActionCanceled = new AtomicBoolean(false); - - ThreadLocal<Messenger> 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) { - - 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.<Messenger>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 CertifyAction) { - op = new CertifyOperation(outerThis, new ProviderHelper(outerThis), outerThis, mActionCanceled); - } 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 index ba877c2a2..1cd76b462 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainService.java @@ -20,70 +20,35 @@ 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.Parcelable; 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.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.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; -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; -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.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.service.input.CryptoInputParcel; 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; -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 java.util.concurrent.atomic.AtomicBoolean; /** * This Service contains all important long lasting operations for OpenKeychain. It receives Intents with @@ -91,75 +56,19 @@ import de.measite.minidns.record.TXT; */ public class KeychainService extends Service implements Progressable { - /* extras that can be given by intent */ + // messenger for communication (hack) 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_EDIT_KEYRING = Constants.INTENT_PREFIX + "EDIT_KEYRING"; - - 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"; - - 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"; - - // save keyring - public static final String EDIT_KEYRING_PARCEL = "save_parcel"; - public static final String EDIT_KEYRING_PASSPHRASE = "passphrase"; + // extras for operation + public static final String EXTRA_OPERATION_INPUT = "op_input"; 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"; - - // 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"; - public static final String PROMOTE_SUBKEY_IDS = "promote_fingerprints"; - - // consolidate - public static final String CONSOLIDATE_RECOVERY = "consolidate_recovery"; - - Messenger mMessenger; + 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); - - private KeyImportAccumulator mKeyImportAccumulator; - - private KeychainService mKeychainService; + ThreadLocal<Messenger> mMessenger = new ThreadLocal<>(); @Override public IBinder onBind(Intent intent) { @@ -171,9 +80,8 @@ 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())) { + if (intent.getAction() != null && intent.getAction().equals(ACTION_CANCEL)) { mActionCanceled.set(true); return START_NOT_STICKY; } @@ -185,315 +93,62 @@ public class KeychainService extends Service implements Progressable { 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!"); + // Set messenger for communication (for this particular thread) + mMessenger.set(extras.<Messenger>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) { + 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); + } else if (inputParcel instanceof KeybaseVerificationParcel) { + op = new KeybaseVerificationOperation(outerThis, new ProviderHelper(outerThis), + outerThis); + } else { 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; - } + @SuppressWarnings("unchecked") // this is unchecked, we make sure it's the correct op above! + OperationResult result = op.execute(inputParcel, cryptoInput); + sendMessageToHandler(MessageStatus.OKAY, result); - Log.logDebugBundle(data, "EXTRA_DATA"); - - ProviderHelper providerHelper = new ProviderHelper(mKeychainService); - - String action = intent.getAction(); - - // 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(mKeychainService); - } else { - result = providerHelper.consolidateDatabaseStep1(mKeychainService); - } - - // Result - sendMessageToHandler(MessageStatus.OKAY, result); - - break; - } - 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<List<byte[]>> extents = new ArrayList<List<byte[]>>(); - 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(mKeychainService, providerHelper, - mKeychainService); - - 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; - } - case ACTION_DELETE: { - - // Input - long[] masterKeyIds = data.getLongArray(DELETE_KEY_LIST); - boolean isSecret = data.getBoolean(DELETE_IS_SECRET); - - // Operation - DeleteOperation op = new DeleteOperation(mKeychainService, providerHelper, mKeychainService); - DeleteResult result = op.execute(masterKeyIds, isSecret); - - // Result - sendMessageToHandler(MessageStatus.OKAY, result); - - 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(mKeychainService, providerHelper, - mKeychainService, mActionCanceled); - OperationResult result = op.execute(saveParcel, cryptoInput); - - // Result - sendMessageToHandler(MessageStatus.OKAY, result); - - 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( - mKeychainService, providerHelper, mKeychainService, - mActionCanceled); - PromoteKeyResult result = op.execute(keyRingId, cardAid, subKeyIds); - - // Result - sendMessageToHandler(MessageStatus.OKAY, result); - - 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( - mKeychainService, providerHelper, mKeychainService); - 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<ParcelableKeyRing> 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<String> 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); - } - } - - 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(mKeychainService, - providerHelper, mKeychainService); - - 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; - } - } - if (!intent.getAction().equals(ACTION_IMPORT_KEYRING)) { - // import keyring handles stopping service on its own - stopSelf(); - } } }; Thread actionThread = new Thread(actionRunnable); actionThread.start(); - - return START_NOT_STICKY; - } - - private void sendProofError(List<String> 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(mKeychainService); - 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); + return START_NOT_STICKY; } private void sendMessageToHandler(MessageStatus status, Integer arg2, Bundle data) { @@ -509,7 +164,7 @@ public class KeychainService extends Service implements Progressable { } try { - mMessenger.send(msg); + mMessenger.get().send(msg); } catch (RemoteException e) { Log.w(Constants.TAG, "Exception sending message, Is handler present?", e); } catch (NullPointerException e) { @@ -523,10 +178,6 @@ public class KeychainService extends Service implements Progressable { sendMessageToHandler(status, null, bundle); } - private void sendMessageToHandler(MessageStatus status, Bundle data) { - sendMessageToHandler(status, null, data); - } - private void sendMessageToHandler(MessageStatus status) { sendMessageToHandler(status, null, null); } @@ -564,214 +215,4 @@ public class KeychainService extends Service implements Progressable { sendMessageToHandler(MessageStatus.PREVENT_CANCEL); } - public void serialKeyImport(ArrayList<ParcelableKeyRing> keyList, final String keyServer, - ProviderHelper providerHelper) { - Log.d(Constants.TAG, "serial key import starting"); - ParcelableFileCache<ParcelableKeyRing> 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<ParcelableKeyRing> 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<Runnable>()); - - 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<ParcelableKeyRing> 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<Long> mImportedMasterKeyIds = new ArrayList<Long>(); - 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; - } - } } 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..d268c3694 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PromoteKeyringParcel.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de> + * Copyright (C) 2015 Vincent Breitmoser <v.breitmoser@mugenguild.com> + * Copyright (C) 2015 Adithya Abraham Philip <adithyaphilip@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.service; + +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<PromoteKeyringParcel> CREATOR = new Parcelable.Creator<PromoteKeyringParcel>() { + @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/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); } }); |