fix Encrypt* with RequiredInputParcel

This commit is contained in:
Vincent Breitmoser
2015-03-30 23:35:32 +02:00
parent d7b79e55fb
commit 39b131c7e5
21 changed files with 184 additions and 559 deletions

View File

@@ -20,15 +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;
@@ -69,6 +75,20 @@ public class SignEncryptOperation extends BaseOperation {
int total = inputBytes != null ? 1 : inputUris.size(), count = 0;
ArrayList<PgpSignEncryptResult> results = new ArrayList<>();
NfcSignOperationsBuilder pendingInputBuilder = null;
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()) {
@@ -129,10 +149,17 @@ public class SignEncryptOperation extends BaseOperation {
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);
}
@@ -142,9 +169,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);

View File

@@ -18,6 +18,8 @@
package org.sufficientlysecure.keychain.operations.results;
import java.util.ArrayList;
import android.os.Parcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;

View File

@@ -671,7 +671,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

View File

@@ -19,76 +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;
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;
public class PgpSignEncryptResult extends InputPendingResult {
// 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;
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, Passphrase passphrase) {
mNfcKeyId = nfcKeyId;
mNfcHash = nfcHash;
mNfcAlgo = nfcAlgo;
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 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();
mDetachedSignature = source.readInt() != 0 ? source.createByteArray() : null;
}
@@ -98,13 +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 (mDetachedSignature != null) {
dest.writeInt(1);
dest.writeByteArray(mDetachedSignature);

View File

@@ -21,22 +21,17 @@ import android.os.Parcel;
import java.util.ArrayList;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
public class SignEncryptResult extends OperationResult {
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) {