aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations
diff options
context:
space:
mode:
authorVincent Breitmoser <valodim@mugenguild.com>2015-04-24 14:18:01 +0200
committerVincent Breitmoser <valodim@mugenguild.com>2015-04-24 14:18:01 +0200
commitb4aec3114d9911cf9aef0d14ee697e5131b2853f (patch)
tree7237de5955ec34d8849737b2f9229bfbb37d0c45 /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations
parentc2163460971cc01e65d7dfd18eec491f01ebc744 (diff)
parentbaac30508d24dcda6135bf8ae338c99d8c3b8ad8 (diff)
downloadopen-keychain-b4aec3114d9911cf9aef0d14ee697e5131b2853f.tar.gz
open-keychain-b4aec3114d9911cf9aef0d14ee697e5131b2853f.tar.bz2
open-keychain-b4aec3114d9911cf9aef0d14ee697e5131b2853f.zip
Merge branch 'development' into linked-identities
Conflicts: Graphics/update-drawables.sh OpenKeychain-Test/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java OpenKeychain/build.gradle OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java58
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java9
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java15
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java48
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/CertifyResult.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DecryptVerifyResult.java58
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/EditKeyResult.java9
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/InputPendingResult.java63
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java120
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpEditKeyResult.java9
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java81
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PromoteKeyResult.java9
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SignEncryptResult.java17
14 files changed, 234 insertions, 274 deletions
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 4ceb34722..051517abd 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java
@@ -28,8 +28,9 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.Operat
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
-import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
+import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation;
+import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation.PgpCertifyResult;
import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
@@ -38,6 +39,9 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException
import org.sufficientlysecure.keychain.service.CertifyActionsParcel;
import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction;
import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
+import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
+import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
+import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.NfcSignOperationsBuilder;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Passphrase;
@@ -60,7 +64,7 @@ public class CertifyOperation extends BaseOperation {
super(context, providerHelper, progressable, cancelled);
}
- public CertifyResult certify(CertifyActionsParcel parcel, String keyServerUri) {
+ public CertifyResult certify(CertifyActionsParcel parcel, CryptoInputParcel cryptoInput, String keyServerUri) {
OperationLog log = new OperationLog();
log.add(LogType.MSG_CRT, 0);
@@ -74,13 +78,14 @@ public class CertifyOperation extends BaseOperation {
mProviderHelper.getCanonicalizedSecretKeyRing(parcel.mMasterKeyId);
log.add(LogType.MSG_CRT_UNLOCK, 1);
certificationKey = secretKeyRing.getSecretKey();
- if (certificationKey.getSecretKeyType() == SecretKeyType.DIVERT_TO_CARD) {
- log.add(LogType.MSG_CRT_ERROR_DIVERT, 2);
- return new CertifyResult(CertifyResult.RESULT_ERROR, log);
+
+ if (!cryptoInput.hasPassphrase()) {
+ return new CertifyResult(log, RequiredInputParcel.createRequiredSignPassphrase(
+ certificationKey.getKeyId(), certificationKey.getKeyId(), null));
}
// certification is always with the master key id, so use that one
- Passphrase passphrase = getCachedPassphrase(parcel.mMasterKeyId, parcel.mMasterKeyId);
+ Passphrase passphrase = cryptoInput.getPassphrase();
if (!certificationKey.unlock(passphrase)) {
log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2);
@@ -92,9 +97,6 @@ public class CertifyOperation extends BaseOperation {
} catch (NotFoundException e) {
log.add(LogType.MSG_CRT_ERROR_MASTER_NOT_FOUND, 2);
return new CertifyResult(CertifyResult.RESULT_ERROR, log);
- } catch (NoSecretKeyException e) {
- log.add(LogType.MSG_CRT_ERROR_MASTER_NOT_FOUND, 2);
- return new CertifyResult(CertifyResult.RESULT_ERROR, log);
}
ArrayList<UncachedKeyRing> certifiedKeys = new ArrayList<>();
@@ -103,6 +105,10 @@ public class CertifyOperation extends BaseOperation {
int certifyOk = 0, certifyError = 0, uploadOk = 0, uploadError = 0;
+ NfcSignOperationsBuilder allRequiredInput = new NfcSignOperationsBuilder(
+ cryptoInput.getSignatureTime(), certificationKey.getKeyId(),
+ certificationKey.getKeyId());
+
// Work through all requested certifications
for (CertifyAction action : parcel.mCertifyActions) {
@@ -123,28 +129,21 @@ public class CertifyOperation extends BaseOperation {
CanonicalizedPublicKeyRing publicRing =
mProviderHelper.getCanonicalizedPublicKeyRing(action.mMasterKeyId);
- UncachedKeyRing certifiedKey = null;
- if (action.mUserIds != null) {
- log.add(LogType.MSG_CRT_CERTIFY_UIDS, 2, action.mUserIds.size(),
- KeyFormattingUtils.convertKeyIdToHex(action.mMasterKeyId));
+ PgpCertifyOperation op = new PgpCertifyOperation();
+ PgpCertifyResult result = op.certify(certificationKey, publicRing,
+ log, 2, action, cryptoInput.getCryptoData(), cryptoInput.getSignatureTime());
- certifiedKey = certificationKey.certifyUserIds(
- publicRing, action.mUserIds, null, null);
+ if (!result.success()) {
+ certifyError += 1;
+ continue;
}
-
- if (action.mUserAttributes != null) {
- log.add(LogType.MSG_CRT_CERTIFY_UATS, 2, action.mUserAttributes.size(),
- KeyFormattingUtils.convertKeyIdToHex(action.mMasterKeyId));
-
- certifiedKey = certificationKey.certifyUserAttributes(
- publicRing, action.mUserAttributes, null, null);
+ if (result.nfcInputRequired()) {
+ RequiredInputParcel requiredInput = result.getRequiredInput();
+ allRequiredInput.addAll(requiredInput);
+ continue;
}
- if (certifiedKey == null) {
- certifyError += 1;
- log.add(LogType.MSG_CRT_WARN_CERT_FAILED, 3);
- }
- certifiedKeys.add(certifiedKey);
+ certifiedKeys.add(result.getCertifiedRing());
} catch (NotFoundException e) {
certifyError += 1;
@@ -153,6 +152,11 @@ public class CertifyOperation extends BaseOperation {
}
+ if ( ! allRequiredInput.isEmpty()) {
+ log.add(LogType.MSG_CRT_NFC_RETURN, 1);
+ return new CertifyResult(log, allRequiredInput.build());
+ }
+
log.add(LogType.MSG_CRT_SAVING, 1);
// Check if we were cancelled
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java
index a179b53ee..4072d91c5 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java
@@ -21,6 +21,7 @@ import android.content.Context;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
+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.PgpEditKeyResult;
@@ -34,6 +35,7 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException
import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
+import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.Passphrase;
import org.sufficientlysecure.keychain.util.ProgressScaler;
@@ -56,7 +58,7 @@ public class EditKeyOperation extends BaseOperation {
super(context, providerHelper, progressable, cancelled);
}
- public EditKeyResult execute(SaveKeyringParcel saveParcel, Passphrase passphrase) {
+ public OperationResult execute(SaveKeyringParcel saveParcel, CryptoInputParcel cryptoInput) {
OperationLog log = new OperationLog();
log.add(LogType.MSG_ED, 0);
@@ -81,7 +83,10 @@ public class EditKeyOperation extends BaseOperation {
CanonicalizedSecretKeyRing secRing =
mProviderHelper.getCanonicalizedSecretKeyRing(saveParcel.mMasterKeyId);
- modifyResult = keyOperations.modifySecretKeyRing(secRing, saveParcel, passphrase);
+ modifyResult = keyOperations.modifySecretKeyRing(secRing, cryptoInput, saveParcel);
+ if (modifyResult.isPending()) {
+ return modifyResult;
+ }
} catch (NotFoundException e) {
log.add(LogType.MSG_ED_ERROR_KEY_NOT_FOUND, 2);
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 f2516f1bd..ff0b545cd 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java
@@ -230,7 +230,7 @@ public class ImportExportOperation extends BaseOperation {
}
} catch (Keyserver.QueryFailedException e) {
Log.e(Constants.TAG, "query failed", e);
- log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_ERROR, 3);
+ log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_ERROR, 3, e.getMessage());
}
}
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 fd86d4b92..ef08b0b77 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java
@@ -50,7 +50,7 @@ public class PromoteKeyOperation extends BaseOperation {
super(context, providerHelper, progressable, cancelled);
}
- public PromoteKeyResult execute(long masterKeyId) {
+ public PromoteKeyResult execute(long masterKeyId, byte[] cardAid) {
OperationLog log = new OperationLog();
log.add(LogType.MSG_PR, 0);
@@ -58,27 +58,16 @@ public class PromoteKeyOperation extends BaseOperation {
// Perform actual type change
UncachedKeyRing promotedRing;
{
-
try {
- // This operation is only allowed for pure public keys
- // TODO delete secret keys if they are stripped, or have been moved to the card?
- if (mProviderHelper.getCachedPublicKeyRing(masterKeyId).hasAnySecret()) {
- log.add(LogType.MSG_PR_ERROR_ALREADY_SECRET, 2);
- return new PromoteKeyResult(PromoteKeyResult.RESULT_ERROR, log, null);
- }
-
log.add(LogType.MSG_PR_FETCHING, 1,
KeyFormattingUtils.convertKeyIdToHex(masterKeyId));
CanonicalizedPublicKeyRing pubRing =
mProviderHelper.getCanonicalizedPublicKeyRing(masterKeyId);
// create divert-to-card secret key from public key
- promotedRing = pubRing.createDummySecretRing();
+ promotedRing = pubRing.createDivertSecretRing(cardAid);
- } catch (PgpKeyNotFoundException e) {
- log.add(LogType.MSG_PR_ERROR_KEY_NOT_FOUND, 2);
- return new PromoteKeyResult(PromoteKeyResult.RESULT_ERROR, log, null);
} catch (NotFoundException e) {
log.add(LogType.MSG_PR_ERROR_KEY_NOT_FOUND, 2);
return new PromoteKeyResult(PromoteKeyResult.RESULT_ERROR, log, null);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java
index b5552a40d..651d15e8f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java
@@ -20,14 +20,21 @@ package org.sufficientlysecure.keychain.operations;
import android.content.Context;
import android.net.Uri;
+import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;
import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
+import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.PgpSignEncryptOperation;
import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
+import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
+import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
+import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.NfcSignOperationsBuilder;
+import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.RequiredInputType;
import org.sufficientlysecure.keychain.util.FileHelper;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.ProgressScaler;
@@ -55,7 +62,7 @@ public class SignEncryptOperation extends BaseOperation {
super(context, providerHelper, progressable, cancelled);
}
- public SignEncryptResult execute(SignEncryptParcel input) {
+ public SignEncryptResult execute(SignEncryptParcel input, CryptoInputParcel cryptoInput) {
OperationLog log = new OperationLog();
log.add(LogType.MSG_SE, 0);
@@ -68,6 +75,21 @@ public class SignEncryptOperation extends BaseOperation {
int total = inputBytes != null ? 1 : inputUris.size(), count = 0;
ArrayList<PgpSignEncryptResult> results = new ArrayList<>();
+ NfcSignOperationsBuilder pendingInputBuilder = null;
+
+ // if signing subkey has not explicitly been set, get first usable subkey capable of signing
+ if (input.getSignatureMasterKeyId() != Constants.key.none
+ && input.getSignatureSubKeyId() == null) {
+ try {
+ long signKeyId = mProviderHelper.getCachedPublicKeyRing(
+ input.getSignatureMasterKeyId()).getSecretSignId();
+ input.setSignatureSubKeyId(signKeyId);
+ } catch (PgpKeyNotFoundException e) {
+ e.printStackTrace();
+ return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results);
+ }
+ }
+
do {
if (checkCancelled()) {
@@ -123,15 +145,22 @@ public class SignEncryptOperation extends BaseOperation {
PgpSignEncryptOperation op = new PgpSignEncryptOperation(mContext, mProviderHelper,
new ProgressScaler(mProgressable, 100 * count / total, 100 * ++count / total, 100), mCancelled);
- PgpSignEncryptResult result = op.execute(input, inputData, outStream);
+ PgpSignEncryptResult result = op.execute(input, cryptoInput, inputData, outStream);
results.add(result);
log.add(result, 2);
if (result.isPending()) {
- return new SignEncryptResult(SignEncryptResult.RESULT_PENDING, log, results);
- }
-
- if (!result.success()) {
+ RequiredInputParcel requiredInput = result.getRequiredInputParcel();
+ // Passphrase returns immediately, nfc are aggregated
+ if (requiredInput.mType == RequiredInputType.PASSPHRASE) {
+ return new SignEncryptResult(log, requiredInput, results);
+ }
+ if (pendingInputBuilder == null) {
+ pendingInputBuilder = new NfcSignOperationsBuilder(requiredInput.mSignatureTime,
+ input.getSignatureMasterKeyId(), input.getSignatureSubKeyId());
+ }
+ pendingInputBuilder.addAll(requiredInput);
+ } else if (!result.success()) {
return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results);
}
@@ -141,9 +170,12 @@ public class SignEncryptOperation extends BaseOperation {
} while (!inputUris.isEmpty());
+ if (pendingInputBuilder != null && !pendingInputBuilder.isEmpty()) {
+ return new SignEncryptResult(log, pendingInputBuilder.build(), results);
+ }
+
if (!outputUris.isEmpty()) {
- // Any output URIs left are indicative of a programming error
- log.add(LogType.MSG_SE_WARN_OUTPUT_LEFT, 1);
+ throw new AssertionError("Got outputs left but no inputs. This is a programming error, please report!");
}
log.add(LogType.MSG_SE_SUCCESS, 1);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/CertifyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/CertifyResult.java
index f56fe4bb9..0a0e63330 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/CertifyResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/CertifyResult.java
@@ -23,6 +23,7 @@ import android.content.Intent;
import android.os.Parcel;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.ui.LogDisplayActivity;
import org.sufficientlysecure.keychain.ui.LogDisplayFragment;
import org.sufficientlysecure.keychain.ui.util.Notify;
@@ -30,16 +31,19 @@ import org.sufficientlysecure.keychain.ui.util.Notify.ActionListener;
import org.sufficientlysecure.keychain.ui.util.Notify.Showable;
import org.sufficientlysecure.keychain.ui.util.Notify.Style;
-public class CertifyResult extends OperationResult {
-
+public class CertifyResult extends InputPendingResult {
int mCertifyOk, mCertifyError, mUploadOk, mUploadError;
public CertifyResult(int result, OperationLog log) {
super(result, log);
}
+ public CertifyResult(OperationLog log, RequiredInputParcel requiredInput) {
+ super(log, requiredInput);
+ }
+
public CertifyResult(int result, OperationLog log, int certifyOk, int certifyError, int uploadOk, int uploadError) {
- this(result, log);
+ super(result, log);
mCertifyOk = certifyOk;
mCertifyError = certifyError;
mUploadOk = uploadOk;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DecryptVerifyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DecryptVerifyResult.java
index 7df37cd9b..917b3415f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DecryptVerifyResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DecryptVerifyResult.java
@@ -22,23 +22,10 @@ import android.os.Parcel;
import org.openintents.openpgp.OpenPgpMetadata;
import org.openintents.openpgp.OpenPgpSignatureResult;
+import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.util.Passphrase;
-public class DecryptVerifyResult extends OperationResult {
-
- // the fourth bit indicates a "data pending" result! (it's also a form of non-success)
- public static final int RESULT_PENDING = RESULT_ERROR + 8;
-
- // fifth to sixth bit in addition indicate specific type of pending
- public static final int RESULT_PENDING_ASYM_PASSPHRASE = RESULT_PENDING + 16;
- public static final int RESULT_PENDING_SYM_PASSPHRASE = RESULT_PENDING + 32;
- public static final int RESULT_PENDING_NFC = RESULT_PENDING + 64;
-
- long mKeyIdPassphraseNeeded;
-
- long mNfcSubKeyId;
- byte[] mNfcSessionKey;
- Passphrase mNfcPassphrase;
+public class DecryptVerifyResult extends InputPendingResult {
OpenPgpSignatureResult mSignatureResult;
OpenPgpMetadata mDecryptMetadata;
@@ -46,32 +33,6 @@ public class DecryptVerifyResult extends OperationResult {
// https://tools.ietf.org/html/rfc4880#page56
String mCharset;
- public long getKeyIdPassphraseNeeded() {
- return mKeyIdPassphraseNeeded;
- }
-
- public void setKeyIdPassphraseNeeded(long keyIdPassphraseNeeded) {
- mKeyIdPassphraseNeeded = keyIdPassphraseNeeded;
- }
-
- public void setNfcState(long subKeyId, byte[] sessionKey, Passphrase passphrase) {
- mNfcSubKeyId = subKeyId;
- mNfcSessionKey = sessionKey;
- mNfcPassphrase = passphrase;
- }
-
- public long getNfcSubKeyId() {
- return mNfcSubKeyId;
- }
-
- public byte[] getNfcEncryptedSessionKey() {
- return mNfcSessionKey;
- }
-
- public Passphrase getNfcPassphrase() {
- return mNfcPassphrase;
- }
-
public OpenPgpSignatureResult getSignatureResult() {
return mSignatureResult;
}
@@ -104,13 +65,14 @@ public class DecryptVerifyResult extends OperationResult {
super(result, log);
}
+ public DecryptVerifyResult(OperationLog log, RequiredInputParcel requiredInput) {
+ super(log, requiredInput);
+ }
+
public DecryptVerifyResult(Parcel source) {
super(source);
- mKeyIdPassphraseNeeded = source.readLong();
mSignatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader());
mDecryptMetadata = source.readParcelable(OpenPgpMetadata.class.getClassLoader());
- mNfcSessionKey = source.readInt() != 0 ? source.createByteArray() : null;
- mNfcPassphrase = source.readParcelable(Passphrase.class.getClassLoader());
}
public int describeContents() {
@@ -119,16 +81,8 @@ public class DecryptVerifyResult extends OperationResult {
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
- dest.writeLong(mKeyIdPassphraseNeeded);
dest.writeParcelable(mSignatureResult, 0);
dest.writeParcelable(mDecryptMetadata, 0);
- if (mNfcSessionKey != null) {
- dest.writeInt(1);
- dest.writeByteArray(mNfcSessionKey);
- } else {
- dest.writeInt(0);
- }
- dest.writeParcelable(mNfcPassphrase, flags);
}
public static final Creator<DecryptVerifyResult> CREATOR = new Creator<DecryptVerifyResult>() {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/EditKeyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/EditKeyResult.java
index abcf575af..842b75c3b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/EditKeyResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/EditKeyResult.java
@@ -31,13 +31,18 @@ public class EditKeyResult extends OperationResult {
public EditKeyResult(Parcel source) {
super(source);
- mMasterKeyId = source.readLong();
+ mMasterKeyId = source.readInt() != 0 ? source.readLong() : null;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
- dest.writeLong(mMasterKeyId);
+ if (mMasterKeyId != null) {
+ dest.writeInt(1);
+ dest.writeLong(mMasterKeyId);
+ } else {
+ dest.writeInt(0);
+ }
}
public static Creator<EditKeyResult> CREATOR = new Creator<EditKeyResult>() {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/InputPendingResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/InputPendingResult.java
new file mode 100644
index 000000000..0b7aa6d03
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/InputPendingResult.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2015 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.operations.results;
+
+import java.util.ArrayList;
+
+import android.os.Parcel;
+
+import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
+
+public class InputPendingResult extends OperationResult {
+
+ // the fourth bit indicates a "data pending" result! (it's also a form of non-success)
+ public static final int RESULT_PENDING = RESULT_ERROR + 8;
+
+ final RequiredInputParcel mRequiredInput;
+
+ public InputPendingResult(int result, OperationLog log) {
+ super(result, log);
+ mRequiredInput = null;
+ }
+
+ public InputPendingResult(OperationLog log, RequiredInputParcel requiredInput) {
+ super(RESULT_PENDING, log);
+ mRequiredInput = requiredInput;
+ }
+
+ public InputPendingResult(Parcel source) {
+ super(source);
+ mRequiredInput = source.readParcelable(getClass().getClassLoader());
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeParcelable(mRequiredInput, 0);
+ }
+
+ public boolean isPending() {
+ return (mResult & RESULT_PENDING) == RESULT_PENDING;
+ }
+
+ public RequiredInputParcel getRequiredInputParcel() {
+ return mRequiredInput;
+ }
+
+}
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 3270d12d5..c93db5c39 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
@@ -33,75 +33,33 @@ import org.sufficientlysecure.keychain.ui.util.Notify.Showable;
import org.sufficientlysecure.keychain.ui.util.Notify.Style;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.ParcelableCache;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-/** Represent the result of an operation.
+/**
+ * Represent the result of an operation.
*
* This class holds a result and the log of an operation. It can be subclassed
* to include typed additional information specific to the operation. To keep
* the class structure (somewhat) simple, this class contains an exhaustive
* list (ie, enum) of all possible log types, which should in all cases be tied
* to string resource ids.
- *
*/
public abstract class OperationResult implements Parcelable {
public static final String EXTRA_RESULT = "operation_result";
- public static final UUID NULL_UUID = new UUID(0,0);
/**
- * A HashMap of UUID:OperationLog which contains logs that we don't need
- * to care about. This is used such that when we become parceled, we are
- * well below the 1Mbit boundary that is specified.
+ * Instead of parceling the logs, they are cached to overcome the 1 MB boundary of
+ * Android's Binder. See ParcelableCache
*/
- private static ConcurrentHashMap<UUID, OperationLog> dehydratedLogs;
+ private static ParcelableCache<OperationLog> logCache;
static {
- // Static initializer for ConcurrentHashMap
- dehydratedLogs = new ConcurrentHashMap<UUID,OperationLog>();
- }
-
- /**
- * Dehydrate a log (such that it is available after deparcelization)
- *
- * Returns the NULL uuid (0) if you hand it null.
- * @param log An OperationLog to dehydrate
- * @return a UUID, the ticket for your dehydrated log
- *
- */
- private static UUID dehydrateLog(OperationLog log) {
- if(log == null) {
- return NULL_UUID;
- }
- else {
- UUID ticket = UUID.randomUUID();
- dehydratedLogs.put(ticket, log);
- return ticket;
- }
- }
-
- /***
- * Rehydrate a log after going through parcelization, invalidating its place in the
- * dehydration pool.
- * This is used such that when parcelized, the parcel is no larger than 1mbit.
- * @param ticket A UUID ticket that identifies the log in question.
- * @return An OperationLog.
- */
- private static OperationLog rehydrateLog(UUID ticket) {
- // UUID.equals isn't well documented; we use compareTo instead.
- if( NULL_UUID.compareTo(ticket) == 0 ) {
- return null;
- }
- else {
- OperationLog log = dehydratedLogs.get(ticket);
- dehydratedLogs.remove(ticket);
- return log;
- }
+ logCache = new ParcelableCache<>();
}
/** Holds the overall result, the number specifying varying degrees of success:
@@ -126,11 +84,8 @@ public abstract class OperationResult implements Parcelable {
public OperationResult(Parcel source) {
mResult = source.readInt();
- long mostSig = source.readLong();
- long leastSig = source.readLong();
- UUID mTicket = new UUID(mostSig, leastSig);
- // fetch the dehydrated log out of storage (this removes it from the dehydration pool)
- mLog = rehydrateLog(mTicket);
+ // get log out of cache based on UUID from source
+ mLog = logCache.readFromParcelAndGetFromCache(source);
}
public int getResult() {
@@ -250,12 +205,20 @@ public abstract class OperationResult implements Parcelable {
public Showable createNotify(final Activity activity) {
- Log.d(Constants.TAG, "mLog.getLast()"+mLog.getLast());
- Log.d(Constants.TAG, "mLog.getLast().mType"+mLog.getLast().mType);
- Log.d(Constants.TAG, "mLog.getLast().mType.getMsgId()"+mLog.getLast().mType.getMsgId());
-
// Take the last message as string
- int msgId = mLog.getLast().mType.getMsgId();
+ String logText;
+
+ LogEntryParcel entryParcel = mLog.getLast();
+ // special case: first parameter may be a quantity
+ if (entryParcel.mParameters != null && entryParcel.mParameters.length > 0
+ && entryParcel.mParameters[0] instanceof Integer) {
+ logText = activity.getResources().getQuantityString(entryParcel.mType.getMsgId(),
+ (Integer) entryParcel.mParameters[0],
+ entryParcel.mParameters);
+ } else {
+ logText = activity.getString(entryParcel.mType.getMsgId(),
+ entryParcel.mParameters);
+ }
Style style;
@@ -273,19 +236,19 @@ public abstract class OperationResult implements Parcelable {
}
if (getLog() == null || getLog().isEmpty()) {
- return Notify.create(activity, msgId, Notify.LENGTH_LONG, style);
+ return Notify.create(activity, logText, Notify.LENGTH_LONG, style);
}
- return Notify.create(activity, msgId, Notify.LENGTH_LONG, style,
- new ActionListener() {
- @Override
- public void onAction() {
- Intent intent = new Intent(
- activity, LogDisplayActivity.class);
- intent.putExtra(LogDisplayFragment.EXTRA_RESULT, OperationResult.this);
- activity.startActivity(intent);
- }
- }, R.string.view_log);
+ return Notify.create(activity, logText, Notify.LENGTH_LONG, style,
+ new ActionListener() {
+ @Override
+ public void onAction() {
+ Intent intent = new Intent(
+ activity, LogDisplayActivity.class);
+ intent.putExtra(LogDisplayFragment.EXTRA_RESULT, OperationResult.this);
+ activity.startActivity(intent);
+ }
+ }, R.string.view_log);
}
@@ -512,6 +475,7 @@ public abstract class OperationResult implements Parcelable {
// secret key modify
MSG_MF (LogLevel.START, R.string.msg_mr),
+ MSG_MF_DIVERT (LogLevel.DEBUG, R.string.msg_mf_divert),
MSG_MF_ERROR_DIVERT_SERIAL (LogLevel.ERROR, R.string.msg_mf_error_divert_serial),
MSG_MF_ERROR_ENCODE (LogLevel.ERROR, R.string.msg_mf_error_encode),
MSG_MF_ERROR_FINGERPRINT (LogLevel.ERROR, R.string.msg_mf_error_fingerprint),
@@ -521,6 +485,7 @@ public abstract class OperationResult implements Parcelable {
MSG_MF_ERROR_NO_CERTIFY (LogLevel.ERROR, R.string.msg_cr_error_no_certify),
MSG_MF_ERROR_NOEXIST_PRIMARY (LogLevel.ERROR, R.string.msg_mf_error_noexist_primary),
MSG_MF_ERROR_NOEXIST_REVOKE (LogLevel.ERROR, R.string.msg_mf_error_noexist_revoke),
+ MSG_MF_ERROR_NOOP (LogLevel.ERROR, R.string.msg_mf_error_noop),
MSG_MF_ERROR_NULL_EXPIRY (LogLevel.ERROR, R.string.msg_mf_error_null_expiry),
MSG_MF_ERROR_PASSPHRASE_MASTER(LogLevel.ERROR, R.string.msg_mf_error_passphrase_master),
MSG_MF_ERROR_PAST_EXPIRY(LogLevel.ERROR, R.string.msg_mf_error_past_expiry),
@@ -538,6 +503,9 @@ public abstract class OperationResult implements Parcelable {
MSG_MF_PASSPHRASE_FAIL (LogLevel.WARN, R.string.msg_mf_passphrase_fail),
MSG_MF_PRIMARY_REPLACE_OLD (LogLevel.DEBUG, R.string.msg_mf_primary_replace_old),
MSG_MF_PRIMARY_NEW (LogLevel.DEBUG, R.string.msg_mf_primary_new),
+ MSG_MF_RESTRICTED_MODE (LogLevel.INFO, R.string.msg_mf_restricted_mode),
+ MSG_MF_REQUIRE_DIVERT (LogLevel.OK, R.string.msg_mf_require_divert),
+ MSG_MF_REQUIRE_PASSPHRASE (LogLevel.OK, R.string.msg_mf_require_passphrase),
MSG_MF_SUBKEY_CHANGE (LogLevel.INFO, R.string.msg_mf_subkey_change),
MSG_MF_SUBKEY_NEW_ID (LogLevel.DEBUG, R.string.msg_mf_subkey_new_id),
MSG_MF_SUBKEY_NEW (LogLevel.INFO, R.string.msg_mf_subkey_new),
@@ -590,13 +558,11 @@ public abstract class OperationResult implements Parcelable {
// promote key
MSG_PR (LogLevel.START, R.string.msg_pr),
- MSG_PR_ERROR_ALREADY_SECRET (LogLevel.ERROR, R.string.msg_pr_error_already_secret),
MSG_PR_ERROR_KEY_NOT_FOUND (LogLevel.ERROR, R.string.msg_pr_error_key_not_found),
MSG_PR_FETCHING (LogLevel.DEBUG, R.string.msg_pr_fetching),
MSG_PR_SUCCESS (LogLevel.OK, R.string.msg_pr_success),
// messages used in UI code
- MSG_EK_ERROR_DIVERT (LogLevel.ERROR, R.string.msg_ek_error_divert),
MSG_EK_ERROR_DUMMY (LogLevel.ERROR, R.string.msg_ek_error_dummy),
MSG_EK_ERROR_NOT_FOUND (LogLevel.ERROR, R.string.msg_ek_error_not_found),
@@ -660,7 +626,6 @@ public abstract class OperationResult implements Parcelable {
MSG_SE_ERROR_INPUT_URI_NOT_FOUND (LogLevel.ERROR, R.string.msg_se_error_input_uri_not_found),
MSG_SE_ERROR_OUTPUT_URI_NOT_FOUND (LogLevel.ERROR, R.string.msg_se_error_output_uri_not_found),
MSG_SE_ERROR_TOO_MANY_INPUTS (LogLevel.ERROR, R.string.msg_se_error_too_many_inputs),
- MSG_SE_WARN_OUTPUT_LEFT (LogLevel.WARN, R.string.msg_se_warn_output_left),
MSG_SE_SUCCESS (LogLevel.OK, R.string.msg_se_success),
// pgpsignencrypt
@@ -697,9 +662,9 @@ public abstract class OperationResult implements Parcelable {
MSG_CRT_ERROR_MASTER_NOT_FOUND (LogLevel.ERROR, R.string.msg_crt_error_master_not_found),
MSG_CRT_ERROR_NOTHING (LogLevel.ERROR, R.string.msg_crt_error_nothing),
MSG_CRT_ERROR_UNLOCK (LogLevel.ERROR, R.string.msg_crt_error_unlock),
- MSG_CRT_ERROR_DIVERT (LogLevel.ERROR, R.string.msg_crt_error_divert),
MSG_CRT (LogLevel.START, R.string.msg_crt),
MSG_CRT_MASTER_FETCH (LogLevel.DEBUG, R.string.msg_crt_master_fetch),
+ MSG_CRT_NFC_RETURN (LogLevel.OK, R.string.msg_crt_nfc_return),
MSG_CRT_SAVE (LogLevel.DEBUG, R.string.msg_crt_save),
MSG_CRT_SAVING (LogLevel.DEBUG, R.string.msg_crt_saving),
MSG_CRT_SUCCESS (LogLevel.OK, R.string.msg_crt_success),
@@ -823,11 +788,8 @@ public abstract class OperationResult implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mResult);
- // Get a ticket for our log.
- UUID mTicket = dehydrateLog(mLog);
- // And write out the UUID most and least significant bits.
- dest.writeLong(mTicket.getMostSignificantBits());
- dest.writeLong(mTicket.getLeastSignificantBits());
+ // cache log and write UUID to dest
+ logCache.cacheAndWriteToParcel(mLog, dest);
}
public static class OperationLog implements Iterable<LogEntryParcel> {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpEditKeyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpEditKeyResult.java
index 611353ac9..38edbf6ee 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpEditKeyResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpEditKeyResult.java
@@ -22,8 +22,10 @@ import android.os.Parcel;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
+import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
-public class PgpEditKeyResult extends OperationResult {
+
+public class PgpEditKeyResult extends InputPendingResult {
private transient UncachedKeyRing mRing;
public final long mRingMasterKeyId;
@@ -35,6 +37,11 @@ public class PgpEditKeyResult extends OperationResult {
mRingMasterKeyId = ring != null ? ring.getMasterKeyId() : Constants.key.none;
}
+ public PgpEditKeyResult(OperationLog log, RequiredInputParcel requiredInput) {
+ super(log, requiredInput);
+ mRingMasterKeyId = Constants.key.none;
+ }
+
public UncachedKeyRing getRing() {
return mRing;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java
index cf40001b3..acb265462 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java
@@ -19,85 +19,31 @@ package org.sufficientlysecure.keychain.operations.results;
import android.os.Parcel;
-import org.sufficientlysecure.keychain.util.Passphrase;
+import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
-import java.util.Date;
-public class PgpSignEncryptResult extends OperationResult {
+public class PgpSignEncryptResult extends InputPendingResult {
- // the fourth bit indicates a "data pending" result! (it's also a form of non-success)
- public static final int RESULT_PENDING = RESULT_ERROR + 8;
-
- // fifth to sixth bit in addition indicate specific type of pending
- public static final int RESULT_PENDING_PASSPHRASE = RESULT_PENDING + 16;
- public static final int RESULT_PENDING_NFC = RESULT_PENDING + 32;
-
- long mKeyIdPassphraseNeeded;
-
- long mNfcKeyId;
- byte[] mNfcHash;
- int mNfcAlgo;
- Date mNfcTimestamp;
- Passphrase mNfcPassphrase;
byte[] mDetachedSignature;
- public long getKeyIdPassphraseNeeded() {
- return mKeyIdPassphraseNeeded;
- }
-
- public void setKeyIdPassphraseNeeded(long keyIdPassphraseNeeded) {
- mKeyIdPassphraseNeeded = keyIdPassphraseNeeded;
- }
-
- public void setNfcData(long nfcKeyId, byte[] nfcHash, int nfcAlgo, Date nfcTimestamp, Passphrase passphrase) {
- mNfcKeyId = nfcKeyId;
- mNfcHash = nfcHash;
- mNfcAlgo = nfcAlgo;
- mNfcTimestamp = nfcTimestamp;
- mNfcPassphrase = passphrase;
- }
-
public void setDetachedSignature(byte[] detachedSignature) {
mDetachedSignature = detachedSignature;
}
- public long getNfcKeyId() {
- return mNfcKeyId;
- }
-
- public byte[] getNfcHash() {
- return mNfcHash;
- }
-
- public int getNfcAlgo() {
- return mNfcAlgo;
- }
-
- public Date getNfcTimestamp() {
- return mNfcTimestamp;
- }
-
- public Passphrase getNfcPassphrase() {
- return mNfcPassphrase;
- }
-
public byte[] getDetachedSignature() {
return mDetachedSignature;
}
- public boolean isPending() {
- return (mResult & RESULT_PENDING) == RESULT_PENDING;
- }
-
public PgpSignEncryptResult(int result, OperationLog log) {
super(result, log);
}
+ public PgpSignEncryptResult(OperationLog log, RequiredInputParcel requiredInput) {
+ super(log, requiredInput);
+ }
+
public PgpSignEncryptResult(Parcel source) {
super(source);
- mNfcHash = source.readInt() != 0 ? source.createByteArray() : null;
- mNfcAlgo = source.readInt();
- mNfcTimestamp = source.readInt() != 0 ? new Date(source.readLong()) : null;
mDetachedSignature = source.readInt() != 0 ? source.createByteArray() : null;
}
@@ -107,19 +53,6 @@ public class PgpSignEncryptResult extends OperationResult {
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
- if (mNfcHash != null) {
- dest.writeInt(1);
- dest.writeByteArray(mNfcHash);
- } else {
- dest.writeInt(0);
- }
- dest.writeInt(mNfcAlgo);
- if (mNfcTimestamp != null) {
- dest.writeInt(1);
- dest.writeLong(mNfcTimestamp.getTime());
- } else {
- dest.writeInt(0);
- }
if (mDetachedSignature != null) {
dest.writeInt(1);
dest.writeByteArray(mDetachedSignature);
@@ -138,4 +71,4 @@ public class PgpSignEncryptResult extends OperationResult {
}
};
-} \ No newline at end of file
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PromoteKeyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PromoteKeyResult.java
index af9aff84a..d6c7a1ee0 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PromoteKeyResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PromoteKeyResult.java
@@ -31,13 +31,18 @@ public class PromoteKeyResult extends OperationResult {
public PromoteKeyResult(Parcel source) {
super(source);
- mMasterKeyId = source.readLong();
+ mMasterKeyId = source.readInt() != 0 ? source.readLong() : null;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
- dest.writeLong(mMasterKeyId);
+ if (mMasterKeyId != null) {
+ dest.writeInt(1);
+ dest.writeLong(mMasterKeyId);
+ } else {
+ dest.writeInt(0);
+ }
}
public static Creator<PromoteKeyResult> CREATOR = new Creator<PromoteKeyResult>() {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SignEncryptResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SignEncryptResult.java
index ed0de65b0..b05921b0d 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SignEncryptResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SignEncryptResult.java
@@ -21,20 +21,17 @@ import android.os.Parcel;
import java.util.ArrayList;
-public class SignEncryptResult extends OperationResult {
+import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
+
+
+public class SignEncryptResult extends InputPendingResult {
ArrayList<PgpSignEncryptResult> mResults;
byte[] mResultBytes;
- public static final int RESULT_PENDING = RESULT_ERROR + 8;
-
- public PgpSignEncryptResult getPending() {
- for (PgpSignEncryptResult sub : mResults) {
- if (sub.isPending()) {
- return sub;
- }
- }
- return null;
+ public SignEncryptResult(OperationLog log, RequiredInputParcel requiredInput, ArrayList<PgpSignEncryptResult> results) {
+ super(log, requiredInput);
+ mResults = results;
}
public SignEncryptResult(int result, OperationLog log, ArrayList<PgpSignEncryptResult> results) {