rewrite PgpSignEncrypt data flow

- introduce high-level SignEncryptOperation for uri to uri signing/encryption
- use SignEncryptParcel for high-level operation parameters
- use PgpSignEncryptInput plus streams for low-level operation parameters
- get rid of all sign/encrypt logic in KeychainIntentService
This commit is contained in:
Vincent Breitmoser
2015-02-01 23:14:26 +01:00
parent 0b6dc65c97
commit 7b24ee7b55
69 changed files with 1070 additions and 859 deletions

View File

@@ -5,6 +5,10 @@ import android.content.Context;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.keyimport.HkpKeyserver;
import org.sufficientlysecure.keychain.keyimport.Keyserver.AddKeyException;
import org.sufficientlysecure.keychain.operations.results.CertifyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
@@ -16,10 +20,6 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException;
import org.sufficientlysecure.keychain.service.CertifyActionsParcel;
import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction;
import org.sufficientlysecure.keychain.operations.results.CertifyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.Log;

View File

@@ -4,16 +4,16 @@ import android.content.Context;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;

View File

@@ -32,6 +32,10 @@ import org.sufficientlysecure.keychain.keyimport.Keyserver.AddKeyException;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
import org.sufficientlysecure.keychain.operations.results.ExportResult;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
@@ -41,10 +45,6 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.FileHelper;

View File

@@ -3,10 +3,10 @@ package org.sufficientlysecure.keychain.operations;
import android.content.Context;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult;
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.Progressable;

View File

@@ -0,0 +1,136 @@
package org.sufficientlysecure.keychain.operations;
import android.content.Context;
import android.net.Uri;
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.PgpSignEncryptOperation;
import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.util.FileHelper;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.ProgressScaler;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
/** This is a high-level operation, which encapsulates one or more sign/encrypt
* operations, using URIs or byte arrays as input and output.
*
* This operation is fail-fast: If any sign/encrypt sub-operation fails or returns
* a pending result, it will terminate.
*
*/
public class SignEncryptOperation extends BaseOperation {
public SignEncryptOperation(Context context, ProviderHelper providerHelper,
Progressable progressable, AtomicBoolean cancelled) {
super(context, providerHelper, progressable, cancelled);
}
public SignEncryptResult execute(SignEncryptParcel input) {
OperationLog log = new OperationLog();
log.add(LogType.MSG_SE, 0);
ArrayDeque<Uri> inputUris = new ArrayDeque<>(input.getInputUris());
ArrayDeque<Uri> outputUris = new ArrayDeque<>(input.getOutputUris());
byte[] inputBytes = input.getBytes();
byte[] outputBytes = null;
ArrayList<PgpSignEncryptResult> results = new ArrayList<>();
do {
if (checkCancelled()) {
log.add(LogType.MSG_OPERATION_CANCELLED, 0);
return new SignEncryptResult(SignEncryptResult.RESULT_CANCELLED, log, results);
}
InputData inputData;
{
if (inputBytes != null) {
log.add(LogType.MSG_SE_INPUT_BYTES, 1);
InputStream is = new ByteArrayInputStream(inputBytes);
inputData = new InputData(is, inputBytes.length);
inputBytes = null;
} else {
if (inputUris.isEmpty()) {
log.add(LogType.MSG_SE_ERROR_NO_INPUT, 1);
return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results);
}
log.add(LogType.MSG_SE_INPUT_URI, 1);
Uri uri = inputUris.removeFirst();
try {
InputStream is = mContext.getContentResolver().openInputStream(uri);
long fileSize = FileHelper.getFileSize(mContext, uri, 0);
String filename = FileHelper.getFilename(mContext, uri);
inputData = new InputData(is, fileSize, filename);
} catch (FileNotFoundException e) {
log.add(LogType.MSG_SE_ERROR_INPUT_URI_NOT_FOUND, 1);
return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results);
}
}
}
OutputStream outStream;
{
if (!outputUris.isEmpty()) {
try {
Uri outputUri = outputUris.removeFirst();
outStream = mContext.getContentResolver().openOutputStream(outputUri);
} catch (FileNotFoundException e) {
log.add(LogType.MSG_SE_ERROR_OUTPUT_URI_NOT_FOUND, 1);
return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results);
}
} else {
if (outputBytes != null) {
log.add(LogType.MSG_SE_ERROR_TOO_MANY_INPUTS, 1);
return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results);
}
outStream = new ByteArrayOutputStream();
}
}
PgpSignEncryptOperation op = new PgpSignEncryptOperation(mContext, mProviderHelper,
new ProgressScaler(), mCancelled);
PgpSignEncryptResult result = op.execute(input, inputData, outStream);
results.add(result);
log.add(result, 2);
if (result.isPending()) {
return new SignEncryptResult(SignEncryptResult.RESULT_PENDING, log, results);
}
if (!result.success()) {
return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results);
}
if (outStream instanceof ByteArrayOutputStream) {
outputBytes = ((ByteArrayOutputStream) outStream).toByteArray();
}
} while (!inputUris.isEmpty());
if (!outputUris.isEmpty()) {
// Any output URIs left are indicative of a programming error
log.add(LogType.MSG_SE_WARN_OUTPUT_LEFT, 1);
}
log.add(LogType.MSG_SE_SUCCESS, 1);
return new SignEncryptResult(SignEncryptResult.RESULT_OK, log, results, outputBytes);
}
}

View File

@@ -21,8 +21,6 @@ package org.sufficientlysecure.keychain.operations.results;
import android.app.Activity;
import android.content.Intent;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.View;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.LogDisplayActivity;

View File

@@ -20,15 +20,8 @@ package org.sufficientlysecure.keychain.operations.results;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.View;
import com.nispok.snackbar.Snackbar;
import com.nispok.snackbar.Snackbar.SnackbarDuration;
import com.nispok.snackbar.SnackbarManager;
import com.nispok.snackbar.listeners.ActionClickListener;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
@@ -593,28 +586,42 @@ public abstract class OperationResult implements Parcelable {
MSG_DC_UNLOCKING (LogLevel.INFO, R.string.msg_dc_unlocking),
// signencrypt
MSG_SE_ASYMMETRIC (LogLevel.INFO, R.string.msg_se_asymmetric),
MSG_SE_CLEARSIGN_ONLY (LogLevel.DEBUG, R.string.msg_se_clearsign_only),
MSG_SE_COMPRESSING (LogLevel.DEBUG, R.string.msg_se_compressing),
MSG_SE_ENCRYPTING (LogLevel.DEBUG, R.string.msg_se_encrypting),
MSG_SE_ERROR_BAD_PASSPHRASE (LogLevel.ERROR, R.string.msg_se_error_bad_passphrase),
MSG_SE_ERROR_IO (LogLevel.ERROR, R.string.msg_se_error_io),
MSG_SE_ERROR_SIGN_KEY(LogLevel.ERROR, R.string.msg_se_error_sign_key),
MSG_SE_ERROR_KEY_SIGN (LogLevel.ERROR, R.string.msg_se_error_key_sign),
MSG_SE_ERROR_NFC (LogLevel.ERROR, R.string.msg_se_error_nfc),
MSG_SE_ERROR_PGP (LogLevel.ERROR, R.string.msg_se_error_pgp),
MSG_SE_ERROR_SIG (LogLevel.ERROR, R.string.msg_se_error_sig),
MSG_SE_ERROR_UNLOCK (LogLevel.ERROR, R.string.msg_se_error_unlock),
MSG_SE_KEY_OK (LogLevel.OK, R.string.msg_se_key_ok),
MSG_SE_KEY_UNKNOWN (LogLevel.DEBUG, R.string.msg_se_key_unknown),
MSG_SE_KEY_WARN (LogLevel.WARN, R.string.msg_se_key_warn),
MSG_SE_OK (LogLevel.OK, R.string.msg_se_ok),
MSG_SE_PENDING_NFC (LogLevel.INFO, R.string.msg_se_pending_nfc),
MSG_SE_PENDING_PASSPHRASE (LogLevel.INFO, R.string.msg_se_pending_passphrase),
MSG_SE (LogLevel.DEBUG, R.string.msg_se),
MSG_SE_SIGNING (LogLevel.DEBUG, R.string.msg_se_signing),
MSG_SE_SIGCRYPTING (LogLevel.DEBUG, R.string.msg_se_sigcrypting),
MSG_SE_SYMMETRIC (LogLevel.INFO, R.string.msg_se_symmetric),
MSG_SE (LogLevel.START, R.string.msg_se),
MSG_SE_INPUT_BYTES (LogLevel.INFO, R.string.msg_se_input_bytes),
MSG_SE_INPUT_URI (LogLevel.INFO, R.string.msg_se_input_uri),
MSG_SE_ERROR_NO_INPUT (LogLevel.DEBUG, R.string.msg_se_error_no_input),
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
MSG_PSE_ASYMMETRIC (LogLevel.INFO, R.string.msg_pse_asymmetric),
MSG_PSE_CLEARSIGN_ONLY (LogLevel.DEBUG, R.string.msg_pse_clearsign_only),
MSG_PSE_COMPRESSING (LogLevel.DEBUG, R.string.msg_pse_compressing),
MSG_PSE_ENCRYPTING (LogLevel.DEBUG, R.string.msg_pse_encrypting),
MSG_PSE_ERROR_BAD_PASSPHRASE (LogLevel.ERROR, R.string.msg_pse_error_bad_passphrase),
MSG_PSE_ERROR_HASH_ALGO (LogLevel.ERROR, R.string.msg_pse_error_hash_algo),
MSG_PSE_ERROR_IO (LogLevel.ERROR, R.string.msg_pse_error_io),
MSG_PSE_ERROR_SIGN_KEY(LogLevel.ERROR, R.string.msg_pse_error_sign_key),
MSG_PSE_ERROR_KEY_SIGN (LogLevel.ERROR, R.string.msg_pse_error_key_sign),
MSG_PSE_ERROR_NFC (LogLevel.ERROR, R.string.msg_pse_error_nfc),
MSG_PSE_ERROR_PGP (LogLevel.ERROR, R.string.msg_pse_error_pgp),
MSG_PSE_ERROR_SIG (LogLevel.ERROR, R.string.msg_pse_error_sig),
MSG_PSE_ERROR_UNLOCK (LogLevel.ERROR, R.string.msg_pse_error_unlock),
MSG_PSE_KEY_OK (LogLevel.OK, R.string.msg_pse_key_ok),
MSG_PSE_KEY_UNKNOWN (LogLevel.DEBUG, R.string.msg_pse_key_unknown),
MSG_PSE_KEY_WARN (LogLevel.WARN, R.string.msg_pse_key_warn),
MSG_PSE_OK (LogLevel.OK, R.string.msg_pse_ok),
MSG_PSE_PENDING_NFC (LogLevel.INFO, R.string.msg_pse_pending_nfc),
MSG_PSE_PENDING_PASSPHRASE (LogLevel.INFO, R.string.msg_pse_pending_passphrase),
MSG_PSE (LogLevel.DEBUG, R.string.msg_pse),
MSG_PSE_SIGNING (LogLevel.DEBUG, R.string.msg_pse_signing),
MSG_PSE_SIGNING_CLEARTEXT (LogLevel.DEBUG, R.string.msg_pse_signing_cleartext),
MSG_PSE_SIGNING_DETACHED (LogLevel.DEBUG, R.string.msg_pse_signing_detached),
MSG_PSE_SIGCRYPTING (LogLevel.DEBUG, R.string.msg_pse_sigcrypting),
MSG_PSE_SYMMETRIC (LogLevel.INFO, R.string.msg_pse_symmetric),
MSG_CRT_CERTIFYING (LogLevel.DEBUG, R.string.msg_crt_certifying),
MSG_CRT_CERTIFY_ALL (LogLevel.DEBUG, R.string.msg_crt_certify_all),

View File

@@ -0,0 +1,139 @@
/*
* 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.operations.results;
import android.os.Parcel;
import java.util.Date;
public class PgpSignEncryptResult 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_PASSPHRASE = RESULT_PENDING + 16;
public static final int RESULT_PENDING_NFC = RESULT_PENDING + 32;
long mKeyIdPassphraseNeeded;
long mNfcKeyId;
byte[] mNfcHash;
int mNfcAlgo;
Date mNfcTimestamp;
String 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, String 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 String 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(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;
}
public int describeContents() {
return 0;
}
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);
} else {
dest.writeInt(0);
}
}
public static final Creator<PgpSignEncryptResult> CREATOR = new Creator<PgpSignEncryptResult>() {
public PgpSignEncryptResult createFromParcel(final Parcel source) {
return new PgpSignEncryptResult(source);
}
public PgpSignEncryptResult[] newArray(final int size) {
return new PgpSignEncryptResult[size];
}
};
}

View File

@@ -19,84 +19,42 @@ package org.sufficientlysecure.keychain.operations.results;
import android.os.Parcel;
import java.util.Date;
import java.util.ArrayList;
public class SignEncryptResult extends OperationResult {
// the fourth bit indicates a "data pending" result! (it's also a form of non-success)
ArrayList<PgpSignEncryptResult> mResults;
byte[] mResultBytes;
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;
String mNfcPassphrase;
byte[] mDetachedSignature;
public long getKeyIdPassphraseNeeded() {
return mKeyIdPassphraseNeeded;
public PgpSignEncryptResult getPending() {
for (PgpSignEncryptResult sub : mResults) {
if (sub.isPending()) {
return sub;
}
}
return null;
}
public void setKeyIdPassphraseNeeded(long keyIdPassphraseNeeded) {
mKeyIdPassphraseNeeded = keyIdPassphraseNeeded;
}
public void setNfcData(long nfcKeyId, byte[] nfcHash, int nfcAlgo, Date nfcTimestamp, String 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 String getNfcPassphrase() {
return mNfcPassphrase;
}
public byte[] getDetachedSignature() {
return mDetachedSignature;
}
public boolean isPending() {
return (mResult & RESULT_PENDING) == RESULT_PENDING;
}
public SignEncryptResult(int result, OperationLog log) {
public SignEncryptResult(int result, OperationLog log, ArrayList<PgpSignEncryptResult> results) {
super(result, log);
mResults = results;
}
public SignEncryptResult(int result, OperationLog log, ArrayList<PgpSignEncryptResult> results, byte[] resultBytes) {
super(result, log);
mResults = results;
mResultBytes = resultBytes;
}
public SignEncryptResult(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;
mResults = source.createTypedArrayList(PgpSignEncryptResult.CREATOR);
}
public byte[] getResultBytes() {
return mResultBytes;
}
public int describeContents() {
@@ -105,25 +63,7 @@ public class SignEncryptResult 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);
} else {
dest.writeInt(0);
}
dest.writeTypedList(mResults);
}
public static final Creator<SignEncryptResult> CREATOR = new Creator<SignEncryptResult>() {

View File

@@ -18,13 +18,8 @@
package org.sufficientlysecure.keychain.operations.results;
import android.app.Activity;
import android.os.Parcel;
import com.github.johnpersano.supertoasts.SuperCardToast;
import com.github.johnpersano.supertoasts.SuperToast;
import com.github.johnpersano.supertoasts.util.Style;
/** This is a simple subclass meant to contain only a single log message. This log
* message is also shown without a log button in the createNotify SuperToast. */
public class SingletonResult extends OperationResult {