generalize NfcOperationParcel to RequiredInputParcel, including passphrases

This commit is contained in:
Vincent Breitmoser 2015-03-19 14:21:30 +01:00
parent d46fc3740b
commit 25d89b5550
12 changed files with 147 additions and 95 deletions

View File

@ -28,7 +28,6 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.Operat
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult; import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation; import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation;
import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation.PgpCertifyResult; import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation.PgpCertifyResult;
@ -40,8 +39,8 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException
import org.sufficientlysecure.keychain.service.CertifyActionsParcel; import org.sufficientlysecure.keychain.service.CertifyActionsParcel;
import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction; import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction;
import org.sufficientlysecure.keychain.service.ContactSyncAdapterService; import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
import org.sufficientlysecure.keychain.service.input.NfcOperationsParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.service.input.NfcOperationsParcel.NfcSignOperationsBuilder; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.NfcSignOperationsBuilder;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
@ -78,8 +77,13 @@ public class CertifyOperation extends BaseOperation {
log.add(LogType.MSG_CRT_UNLOCK, 1); log.add(LogType.MSG_CRT_UNLOCK, 1);
certificationKey = secretKeyRing.getSecretKey(); certificationKey = secretKeyRing.getSecretKey();
if (!parcel.mCryptoInput.hasPassphrase()) {
return new CertifyResult(log, RequiredInputParcel.createRequiredPassphrase(
certificationKey.getKeyId(), null));
}
// certification is always with the master key id, so use that one // certification is always with the master key id, so use that one
String passphrase = getCachedPassphrase(parcel.mMasterKeyId, parcel.mMasterKeyId); String passphrase = parcel.mCryptoInput.getPassphrase();
if (!certificationKey.unlock(passphrase)) { if (!certificationKey.unlock(passphrase)) {
log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2); log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2);
@ -91,9 +95,6 @@ public class CertifyOperation extends BaseOperation {
} catch (NotFoundException e) { } catch (NotFoundException e) {
log.add(LogType.MSG_CRT_ERROR_MASTER_NOT_FOUND, 2); log.add(LogType.MSG_CRT_ERROR_MASTER_NOT_FOUND, 2);
return new CertifyResult(CertifyResult.RESULT_ERROR, log); 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<>(); ArrayList<UncachedKeyRing> certifiedKeys = new ArrayList<>();
@ -133,7 +134,7 @@ public class CertifyOperation extends BaseOperation {
continue; continue;
} }
if (result.nfcInputRequired()) { if (result.nfcInputRequired()) {
NfcOperationsParcel requiredInput = result.getRequiredInput(); RequiredInputParcel requiredInput = result.getRequiredInput();
allRequiredInput.addAll(requiredInput); allRequiredInput.addAll(requiredInput);
continue; continue;
} }

View File

@ -23,7 +23,7 @@ import android.content.Intent;
import android.os.Parcel; import android.os.Parcel;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.service.input.NfcOperationsParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.ui.LogDisplayActivity; import org.sufficientlysecure.keychain.ui.LogDisplayActivity;
import org.sufficientlysecure.keychain.ui.LogDisplayFragment; import org.sufficientlysecure.keychain.ui.LogDisplayFragment;
import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.Notify;
@ -38,7 +38,7 @@ public class CertifyResult extends InputPendingResult {
super(result, log); super(result, log);
} }
public CertifyResult(OperationLog log, NfcOperationsParcel requiredInput) { public CertifyResult(OperationLog log, RequiredInputParcel requiredInput) {
super(log, requiredInput); super(log, requiredInput);
} }

View File

@ -3,7 +3,7 @@ package org.sufficientlysecure.keychain.operations.results;
import android.os.Parcel; import android.os.Parcel;
import org.sufficientlysecure.keychain.service.input.NfcOperationsParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
public class InputPendingResult extends OperationResult { public class InputPendingResult extends OperationResult {
@ -14,7 +14,7 @@ public class InputPendingResult extends OperationResult {
public static final int RESULT_PENDING_PASSPHRASE = RESULT_PENDING + 16; public static final int RESULT_PENDING_PASSPHRASE = RESULT_PENDING + 16;
public static final int RESULT_PENDING_NFC = RESULT_PENDING + 32; public static final int RESULT_PENDING_NFC = RESULT_PENDING + 32;
final NfcOperationsParcel mRequiredInput; final RequiredInputParcel mRequiredInput;
final Long mKeyIdPassphraseNeeded; final Long mKeyIdPassphraseNeeded;
public InputPendingResult(int result, OperationLog log) { public InputPendingResult(int result, OperationLog log) {
@ -23,7 +23,7 @@ public class InputPendingResult extends OperationResult {
mKeyIdPassphraseNeeded = null; mKeyIdPassphraseNeeded = null;
} }
public InputPendingResult(OperationLog log, NfcOperationsParcel requiredInput) { public InputPendingResult(OperationLog log, RequiredInputParcel requiredInput) {
super(RESULT_PENDING_NFC, log); super(RESULT_PENDING_NFC, log);
mRequiredInput = requiredInput; mRequiredInput = requiredInput;
mKeyIdPassphraseNeeded = null; mKeyIdPassphraseNeeded = null;
@ -65,7 +65,7 @@ public class InputPendingResult extends OperationResult {
return (mResult & RESULT_PENDING_PASSPHRASE) == RESULT_PENDING_PASSPHRASE; return (mResult & RESULT_PENDING_PASSPHRASE) == RESULT_PENDING_PASSPHRASE;
} }
public NfcOperationsParcel getNfcOperationsParcel() { public RequiredInputParcel getRequiredInputParcel() {
return mRequiredInput; return mRequiredInput;
} }

View File

@ -21,8 +21,6 @@ import android.os.Parcel;
import java.util.ArrayList; import java.util.ArrayList;
import org.sufficientlysecure.keychain.service.input.NfcOperationsParcel;
public class SignEncryptResult extends OperationResult { public class SignEncryptResult extends OperationResult {

View File

@ -3,7 +3,6 @@ package org.sufficientlysecure.keychain.pgp;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPException;
@ -19,8 +18,8 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction; import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction;
import org.sufficientlysecure.keychain.service.input.NfcOperationsParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.service.input.NfcOperationsParcel.NfcSignOperationsBuilder; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.NfcSignOperationsBuilder;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
@ -110,7 +109,7 @@ public class PgpCertifyOperation {
public static class PgpCertifyResult { public static class PgpCertifyResult {
final NfcOperationsParcel mRequiredInput; final RequiredInputParcel mRequiredInput;
final UncachedKeyRing mCertifiedRing; final UncachedKeyRing mCertifiedRing;
PgpCertifyResult() { PgpCertifyResult() {
@ -118,7 +117,7 @@ public class PgpCertifyOperation {
mCertifiedRing = null; mCertifiedRing = null;
} }
PgpCertifyResult(NfcOperationsParcel requiredInput) { PgpCertifyResult(RequiredInputParcel requiredInput) {
mRequiredInput = requiredInput; mRequiredInput = requiredInput;
mCertifiedRing = null; mCertifiedRing = null;
} }
@ -140,7 +139,7 @@ public class PgpCertifyOperation {
return mCertifiedRing; return mCertifiedRing;
} }
public NfcOperationsParcel getRequiredInput() { public RequiredInputParcel getRequiredInput() {
return mRequiredInput; return mRequiredInput;
} }

View File

@ -15,18 +15,26 @@ import android.os.Parcelable;
*/ */
public class CryptoInputParcel implements Parcelable { public class CryptoInputParcel implements Parcelable {
Date mSignatureTime; final Date mSignatureTime;
final String mPassphrase;
// this map contains both decrypted session keys and signed hashes to be // this map contains both decrypted session keys and signed hashes to be
// used in the crypto operation described by this parcel. // used in the crypto operation described by this parcel.
private HashMap<ByteBuffer,byte[]> mCryptoData = new HashMap<>(); private HashMap<ByteBuffer,byte[]> mCryptoData = new HashMap<>();
public CryptoInputParcel(Date signatureTime, String passphrase) {
mSignatureTime = signatureTime == null ? new Date() : signatureTime;
mPassphrase = passphrase;
}
public CryptoInputParcel(Date signatureTime) { public CryptoInputParcel(Date signatureTime) {
mSignatureTime = signatureTime == null ? new Date() : signatureTime; mSignatureTime = signatureTime == null ? new Date() : signatureTime;
mPassphrase = null;
} }
protected CryptoInputParcel(Parcel source) { protected CryptoInputParcel(Parcel source) {
mSignatureTime = new Date(source.readLong()); mSignatureTime = new Date(source.readLong());
mPassphrase = source.readString();
{ {
int count = source.readInt(); int count = source.readInt();
@ -48,6 +56,7 @@ public class CryptoInputParcel implements Parcelable {
@Override @Override
public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(mSignatureTime.getTime()); dest.writeLong(mSignatureTime.getTime());
dest.writeString(mPassphrase);
dest.writeInt(mCryptoData.size()); dest.writeInt(mCryptoData.size());
for (HashMap.Entry<ByteBuffer,byte[]> entry : mCryptoData.entrySet()) { for (HashMap.Entry<ByteBuffer,byte[]> entry : mCryptoData.entrySet()) {
@ -68,6 +77,14 @@ public class CryptoInputParcel implements Parcelable {
return mSignatureTime; return mSignatureTime;
} }
public boolean hasPassphrase() {
return mPassphrase != null;
}
public String getPassphrase() {
return mPassphrase;
}
public static final Creator<CryptoInputParcel> CREATOR = new Creator<CryptoInputParcel>() { public static final Creator<CryptoInputParcel> CREATOR = new Creator<CryptoInputParcel>() {
public CryptoInputParcel createFromParcel(final Parcel source) { public CryptoInputParcel createFromParcel(final Parcel source) {
return new CryptoInputParcel(source); return new CryptoInputParcel(source);

View File

@ -8,29 +8,31 @@ import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
public class NfcOperationsParcel implements Parcelable { public class RequiredInputParcel implements Parcelable {
public enum NfcOperationType { public enum RequiredInputType {
NFC_SIGN, NFC_DECRYPT PASSPHRASE, NFC_SIGN, NFC_DECRYPT
} }
public Date mSignatureTime; public Date mSignatureTime;
public final NfcOperationType mType; public final RequiredInputType mType;
public final byte[][] mInputHashes; public final byte[][] mInputHashes;
public final int[] mSignAlgos; public final int[] mSignAlgos;
private Long mSubKeyId;
private NfcOperationsParcel(NfcOperationType type, byte[][] inputHashes, private RequiredInputParcel(RequiredInputType type, byte[][] inputHashes,
int[] signAlgos, Date signatureTime) { int[] signAlgos, Date signatureTime, Long keyId) {
mType = type; mType = type;
mInputHashes = inputHashes; mInputHashes = inputHashes;
mSignAlgos = signAlgos; mSignAlgos = signAlgos;
mSignatureTime = signatureTime; mSignatureTime = signatureTime;
mSubKeyId = keyId;
} }
public NfcOperationsParcel(Parcel source) { public RequiredInputParcel(Parcel source) {
mType = NfcOperationType.values()[source.readInt()]; mType = RequiredInputType.values()[source.readInt()];
{ if (source.readInt() != 0) {
int count = source.readInt(); int count = source.readInt();
mInputHashes = new byte[count][]; mInputHashes = new byte[count][];
mSignAlgos = new int[count]; mSignAlgos = new int[count];
@ -38,21 +40,34 @@ public class NfcOperationsParcel implements Parcelable {
mInputHashes[i] = source.createByteArray(); mInputHashes[i] = source.createByteArray();
mSignAlgos[i] = source.readInt(); mSignAlgos[i] = source.readInt();
} }
} else {
mInputHashes = null;
mSignAlgos = null;
} }
mSignatureTime = source.readInt() != 0 ? new Date(source.readLong()) : null; mSignatureTime = source.readInt() != 0 ? new Date(source.readLong()) : null;
mSubKeyId = source.readInt() != 0 ? source.readLong() : null;
} }
public static NfcOperationsParcel createNfcSignOperation( public long getSubKeyId() {
return mSubKeyId;
}
public static RequiredInputParcel createNfcSignOperation(
byte[] inputHash, int signAlgo, Date signatureTime) { byte[] inputHash, int signAlgo, Date signatureTime) {
return new NfcOperationsParcel(NfcOperationType.NFC_SIGN, return new RequiredInputParcel(RequiredInputType.NFC_SIGN,
new byte[][] { inputHash }, new int[] { signAlgo }, signatureTime); new byte[][] { inputHash }, new int[] { signAlgo }, signatureTime, null);
} }
public static NfcOperationsParcel createNfcDecryptOperation(byte[] inputHash) { public static RequiredInputParcel createNfcDecryptOperation(byte[] inputHash) {
return new NfcOperationsParcel(NfcOperationType.NFC_DECRYPT, return new RequiredInputParcel(RequiredInputType.NFC_DECRYPT,
new byte[][] { inputHash }, null, null); new byte[][] { inputHash }, null, null, null);
}
public static RequiredInputParcel createRequiredPassphrase(long keyId, Date signatureTime) {
return new RequiredInputParcel(RequiredInputType.PASSPHRASE,
null, null, signatureTime, keyId);
} }
@Override @Override
@ -63,10 +78,15 @@ public class NfcOperationsParcel implements Parcelable {
@Override @Override
public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mType.ordinal()); dest.writeInt(mType.ordinal());
dest.writeInt(mInputHashes.length); if (mInputHashes != null) {
for (int i = 0; i < mInputHashes.length; i++) { dest.writeInt(1);
dest.writeByteArray(mInputHashes[i]); dest.writeInt(mInputHashes.length);
dest.writeInt(mSignAlgos[i]); for (int i = 0; i < mInputHashes.length; i++) {
dest.writeByteArray(mInputHashes[i]);
dest.writeInt(mSignAlgos[i]);
}
} else {
dest.writeInt(0);
} }
if (mSignatureTime != null) { if (mSignatureTime != null) {
dest.writeInt(1); dest.writeInt(1);
@ -74,16 +94,22 @@ public class NfcOperationsParcel implements Parcelable {
} else { } else {
dest.writeInt(0); dest.writeInt(0);
} }
if (mSubKeyId != null) {
dest.writeInt(1);
dest.writeLong(mSubKeyId);
} else {
dest.writeInt(0);
}
} }
public static final Creator<NfcOperationsParcel> CREATOR = new Creator<NfcOperationsParcel>() { public static final Creator<RequiredInputParcel> CREATOR = new Creator<RequiredInputParcel>() {
public NfcOperationsParcel createFromParcel(final Parcel source) { public RequiredInputParcel createFromParcel(final Parcel source) {
return new NfcOperationsParcel(source); return new RequiredInputParcel(source);
} }
public NfcOperationsParcel[] newArray(final int size) { public RequiredInputParcel[] newArray(final int size) {
return new NfcOperationsParcel[size]; return new RequiredInputParcel[size];
} }
}; };
@ -96,7 +122,7 @@ public class NfcOperationsParcel implements Parcelable {
mSignatureTime = signatureTime; mSignatureTime = signatureTime;
} }
public NfcOperationsParcel build() { public RequiredInputParcel build() {
byte[][] inputHashes = new byte[mInputHashes.size()][]; byte[][] inputHashes = new byte[mInputHashes.size()][];
mInputHashes.toArray(inputHashes); mInputHashes.toArray(inputHashes);
int[] signAlgos = new int[mSignAlgos.size()]; int[] signAlgos = new int[mSignAlgos.size()];
@ -104,8 +130,8 @@ public class NfcOperationsParcel implements Parcelable {
signAlgos[i] = mSignAlgos.get(i); signAlgos[i] = mSignAlgos.get(i);
} }
return new NfcOperationsParcel(NfcOperationType.NFC_SIGN, return new RequiredInputParcel(RequiredInputType.NFC_SIGN,
inputHashes, signAlgos, mSignatureTime); inputHashes, signAlgos, mSignatureTime, null);
} }
public void addHash(byte[] hash, int algo) { public void addHash(byte[] hash, int algo) {
@ -113,11 +139,11 @@ public class NfcOperationsParcel implements Parcelable {
mSignAlgos.add(algo); mSignAlgos.add(algo);
} }
public void addAll(NfcOperationsParcel input) { public void addAll(RequiredInputParcel input) {
if (!mSignatureTime.equals(input.mSignatureTime)) { if (!mSignatureTime.equals(input.mSignatureTime)) {
throw new AssertionError("input times must match, this is a programming error!"); throw new AssertionError("input times must match, this is a programming error!");
} }
if (input.mType != NfcOperationType.NFC_SIGN) { if (input.mType != RequiredInputType.NFC_SIGN) {
throw new AssertionError("operation types must match, this is a progrmming error!"); throw new AssertionError("operation types must match, this is a progrmming error!");
} }

View File

@ -166,7 +166,7 @@ public class CertifyKeyFragment extends CryptoOperationFragment
Notify.showNotify(getActivity(), getString(R.string.select_key_to_certify), Notify.showNotify(getActivity(), getString(R.string.select_key_to_certify),
Notify.Style.ERROR); Notify.Style.ERROR);
} else { } else {
cryptoOperation(); cryptoOperation(null);
} }
} }
}); });
@ -307,15 +307,6 @@ public class CertifyKeyFragment extends CryptoOperationFragment
mUserIdsAdapter.swapCursor(null); mUserIdsAdapter.swapCursor(null);
} }
protected void cryptoOperation() {
cryptoOperation((CryptoInputParcel) null);
}
@Override
protected void cryptoOperation(String passphrase) {
cryptoOperation((CryptoInputParcel) null);
}
@Override @Override
protected void cryptoOperation(CryptoInputParcel cryptoInput) { protected void cryptoOperation(CryptoInputParcel cryptoInput) {
// Bail out if there is not at least one user id selected // Bail out if there is not at least one user id selected

View File

@ -11,7 +11,7 @@ import org.sufficientlysecure.keychain.operations.results.CertifyResult;
import org.sufficientlysecure.keychain.operations.results.InputPendingResult; import org.sufficientlysecure.keychain.operations.results.InputPendingResult;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler.MessageStatus; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler.MessageStatus;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.service.input.NfcOperationsParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
public abstract class CryptoOperationFragment extends Fragment { public abstract class CryptoOperationFragment extends Fragment {
@ -19,17 +19,28 @@ public abstract class CryptoOperationFragment extends Fragment {
public static final int REQUEST_CODE_PASSPHRASE = 0x00008001; public static final int REQUEST_CODE_PASSPHRASE = 0x00008001;
public static final int REQUEST_CODE_NFC = 0x00008002; public static final int REQUEST_CODE_NFC = 0x00008002;
private void startPassphraseDialog(long subkeyId) { private void initiateInputActivity(RequiredInputParcel requiredInput) {
Intent intent = new Intent(getActivity(), PassphraseDialogActivity.class);
intent.putExtra(PassphraseDialogActivity.EXTRA_SUBKEY_ID, subkeyId); switch (requiredInput.mType) {
startActivityForResult(intent, REQUEST_CODE_PASSPHRASE); case NFC_DECRYPT:
} case NFC_SIGN: {
Intent intent = new Intent(getActivity(), NfcOperationActivity.class);
intent.putExtra(NfcOperationActivity.EXTRA_PIN, "123456");
intent.putExtra(NfcOperationActivity.EXTRA_REQUIRED_INPUT, requiredInput);
startActivityForResult(intent, REQUEST_CODE_NFC);
return;
}
case PASSPHRASE: {
Intent intent = new Intent(getActivity(), PassphraseDialogActivity.class);
intent.putExtra(PassphraseDialogActivity.EXTRA_REQUIRED_INPUT, requiredInput);
startActivityForResult(intent, REQUEST_CODE_PASSPHRASE);
return;
}
}
throw new RuntimeException("Unhandled pending result!");
private void initiateNfcInput(NfcOperationsParcel nfcOps) {
Intent intent = new Intent(getActivity(), NfcOperationActivity.class);
intent.putExtra(NfcOperationActivity.EXTRA_PIN, "123456");
intent.putExtra(NfcOperationActivity.EXTRA_NFC_OPS, nfcOps);
startActivityForResult(intent, REQUEST_CODE_NFC);
} }
@Override @Override
@ -37,8 +48,9 @@ public abstract class CryptoOperationFragment extends Fragment {
switch (requestCode) { switch (requestCode) {
case REQUEST_CODE_PASSPHRASE: { case REQUEST_CODE_PASSPHRASE: {
if (resultCode == Activity.RESULT_OK && data != null) { if (resultCode == Activity.RESULT_OK && data != null) {
String passphrase = data.getStringExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE); CryptoInputParcel cryptoInput =
cryptoOperation(passphrase); data.getParcelableExtra(PassphraseDialogActivity.RESULT_DATA);
cryptoOperation(cryptoInput);
} }
return; return;
} }
@ -67,16 +79,9 @@ public abstract class CryptoOperationFragment extends Fragment {
InputPendingResult result = data.getParcelable(CertifyResult.EXTRA_RESULT); InputPendingResult result = data.getParcelable(CertifyResult.EXTRA_RESULT);
if (result != null && result.isPending()) { if (result != null && result.isPending()) {
if (result.isPassphrasePending()) { RequiredInputParcel requiredInput = result.getRequiredInputParcel();
startPassphraseDialog(result.getPassphraseKeyId()); initiateInputActivity(requiredInput);
return true; return true;
} else if (result.isNfcPending()) {
NfcOperationsParcel requiredInput = result.getNfcOperationsParcel();
initiateNfcInput(requiredInput);
return true;
} else {
throw new RuntimeException("Unhandled pending result!");
}
} }
} }
@ -84,6 +89,5 @@ public abstract class CryptoOperationFragment extends Fragment {
} }
protected abstract void cryptoOperation(CryptoInputParcel cryptoInput); protected abstract void cryptoOperation(CryptoInputParcel cryptoInput);
protected abstract void cryptoOperation(String passphrase);
} }

View File

@ -32,7 +32,7 @@ import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.service.input.NfcOperationsParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
public abstract class EncryptActivity extends BaseActivity { public abstract class EncryptActivity extends BaseActivity {
@ -62,11 +62,11 @@ public abstract class EncryptActivity extends BaseActivity {
startActivityForResult(intent, REQUEST_CODE_PASSPHRASE); startActivityForResult(intent, REQUEST_CODE_PASSPHRASE);
} }
protected void startNfcSign(long keyId, String pin, NfcOperationsParcel nfcOps) { protected void startNfcSign(long keyId, String pin, RequiredInputParcel nfcOps) {
Intent intent = new Intent(this, NfcOperationActivity.class); Intent intent = new Intent(this, NfcOperationActivity.class);
intent.putExtra(NfcOperationActivity.EXTRA_PIN, pin); intent.putExtra(NfcOperationActivity.EXTRA_PIN, pin);
intent.putExtra(NfcOperationActivity.EXTRA_NFC_OPS, nfcOps); intent.putExtra(NfcOperationActivity.EXTRA_REQUIRED_INPUT, nfcOps);
// TODO respect keyid(?) // TODO respect keyid(?)
startActivityForResult(intent, REQUEST_CODE_NFC); startActivityForResult(intent, REQUEST_CODE_NFC);
@ -144,7 +144,7 @@ public abstract class EncryptActivity extends BaseActivity {
} else if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_NFC) == } else if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_NFC) ==
PgpSignEncryptResult.RESULT_PENDING_NFC) { PgpSignEncryptResult.RESULT_PENDING_NFC) {
NfcOperationsParcel parcel = NfcOperationsParcel.createNfcSignOperation( RequiredInputParcel parcel = RequiredInputParcel.createNfcSignOperation(
pgpResult.getNfcHash(), pgpResult.getNfcHash(),
pgpResult.getNfcAlgo(), pgpResult.getNfcAlgo(),
input.getSignatureTime()); input.getSignatureTime());

View File

@ -23,7 +23,7 @@ import org.spongycastle.util.encoders.Hex;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.service.input.NfcOperationsParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.util.Iso7816TLV; import org.sufficientlysecure.keychain.util.Iso7816TLV;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
@ -41,7 +41,7 @@ import java.nio.ByteBuffer;
public class NfcOperationActivity extends BaseActivity { public class NfcOperationActivity extends BaseActivity {
public static final String EXTRA_PIN = "pin"; public static final String EXTRA_PIN = "pin";
public static final String EXTRA_NFC_OPS = "nfc_operations"; public static final String EXTRA_REQUIRED_INPUT = "required_input";
public static final String RESULT_DATA = "result_data"; public static final String RESULT_DATA = "result_data";
@ -52,7 +52,7 @@ public class NfcOperationActivity extends BaseActivity {
private String mPin; private String mPin;
NfcOperationsParcel mNfcOperations; RequiredInputParcel mNfcOperations;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -69,7 +69,7 @@ public class NfcOperationActivity extends BaseActivity {
Bundle data = intent.getExtras(); Bundle data = intent.getExtras();
mNfcOperations = data.getParcelable(EXTRA_NFC_OPS); mNfcOperations = data.getParcelable(EXTRA_REQUIRED_INPUT);
mPin = data.getString(EXTRA_PIN); mPin = data.getString(EXTRA_PIN);
} }

View File

@ -41,6 +41,7 @@ import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import junit.framework.Assert;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
@ -53,6 +54,9 @@ import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.RequiredInputType;
import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder; import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.Preferences;
@ -63,7 +67,9 @@ import org.sufficientlysecure.keychain.util.Preferences;
*/ */
public class PassphraseDialogActivity extends FragmentActivity { public class PassphraseDialogActivity extends FragmentActivity {
public static final String MESSAGE_DATA_PASSPHRASE = "passphrase"; public static final String MESSAGE_DATA_PASSPHRASE = "passphrase";
public static final String RESULT_DATA = "result_data";
public static final String EXTRA_REQUIRED_INPUT = "required_input";
public static final String EXTRA_SUBKEY_ID = "secret_key_id"; public static final String EXTRA_SUBKEY_ID = "secret_key_id";
// special extra for OpenPgpService // special extra for OpenPgpService
@ -86,7 +92,16 @@ public class PassphraseDialogActivity extends FragmentActivity {
// this activity itself has no content view (see manifest) // this activity itself has no content view (see manifest)
long keyId = getIntent().getLongExtra(EXTRA_SUBKEY_ID, 0); long keyId;
if (getIntent().hasExtra(EXTRA_SUBKEY_ID)) {
keyId = getIntent().getLongExtra(EXTRA_SUBKEY_ID, 0);
} else {
RequiredInputParcel requiredInput = getIntent().getParcelableExtra(EXTRA_REQUIRED_INPUT);
if (requiredInput.mType != RequiredInputType.PASSPHRASE) {
throw new AssertionError("Wrong required input type for PassphraseDialogActivity!");
}
keyId = requiredInput.getSubKeyId();
}
Intent serviceIntent = getIntent().getParcelableExtra(EXTRA_DATA); Intent serviceIntent = getIntent().getParcelableExtra(EXTRA_DATA);
@ -410,6 +425,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
// also return passphrase back to activity // also return passphrase back to activity
Intent returnIntent = new Intent(); Intent returnIntent = new Intent();
returnIntent.putExtra(MESSAGE_DATA_PASSPHRASE, passphrase); returnIntent.putExtra(MESSAGE_DATA_PASSPHRASE, passphrase);
returnIntent.putExtra(RESULT_DATA, new CryptoInputParcel(null, passphrase));
getActivity().setResult(RESULT_OK, returnIntent); getActivity().setResult(RESULT_OK, returnIntent);
} }