From 93c7eb72fbbf93938043566dfc1707b6714f325b Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 21 Mar 2015 15:16:32 +0100 Subject: [PATCH] more data in RequiredInputParcel, OperationResult notifications - pass both masterkeyid and subkeyid though RequiredInputParcel parcel - fix numeric vales in OperationResult.createNotify() --- .../keychain/operations/CertifyOperation.java | 6 +- .../operations/results/EditKeyResult.java | 9 ++- .../operations/results/OperationResult.java | 22 ++++--- .../keychain/pgp/PgpCertifyOperation.java | 3 +- .../keychain/pgp/PgpKeyOperation.java | 7 ++- .../service/input/RequiredInputParcel.java | 39 +++++++++--- .../keychain/ui/NfcOperationActivity.java | 60 +++++++++++++++---- 7 files changed, 110 insertions(+), 36 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 7c299a6bd..eb2a3d33f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java @@ -81,7 +81,7 @@ public class CertifyOperation extends BaseOperation { if (!cryptoInput.hasPassphrase()) { return new CertifyResult(log, RequiredInputParcel.createRequiredPassphrase( - certificationKey.getKeyId(), null)); + certificationKey.getKeyId(), certificationKey.getKeyId(), null)); } // certification is always with the master key id, so use that one @@ -105,7 +105,9 @@ public class CertifyOperation extends BaseOperation { int certifyOk = 0, certifyError = 0, uploadOk = 0, uploadError = 0; - NfcSignOperationsBuilder allRequiredInput = new NfcSignOperationsBuilder(cryptoInput.getSignatureTime()); + NfcSignOperationsBuilder allRequiredInput = new NfcSignOperationsBuilder( + cryptoInput.getSignatureTime(), certificationKey.getKeyId(), + certificationKey.getKeyId()); // Work through all requested certifications for (CertifyAction action : parcel.mCertifyActions) { 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 CREATOR = new Creator() { 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 033039df6..d6e71046d 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 @@ -250,12 +250,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,10 +281,10 @@ public abstract class OperationResult implements Parcelable { } if (getLog() == null || getLog().isEmpty()) { - return Notify.createNotify(activity, msgId, Notify.LENGTH_LONG, style); + return Notify.createNotify(activity, logText, Notify.LENGTH_LONG, style); } - return Notify.createNotify(activity, msgId, Notify.LENGTH_LONG, style, + return Notify.createNotify(activity, logText, Notify.LENGTH_LONG, style, new ActionListener() { @Override public void onAction() { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpCertifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpCertifyOperation.java index ff162775a..90ec3053f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpCertifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpCertifyOperation.java @@ -58,7 +58,8 @@ public class PgpCertifyOperation { // get the master subkey (which we certify for) PGPPublicKey publicKey = publicRing.getPublicKey().getPublicKey(); - NfcSignOperationsBuilder requiredInput = new NfcSignOperationsBuilder(creationTimestamp); + NfcSignOperationsBuilder requiredInput = new NfcSignOperationsBuilder(creationTimestamp, + publicKey.getKeyID(), publicKey.getKeyID()); try { if (action.mUserIds != null) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index f4eccf298..f73bada06 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -409,7 +409,8 @@ public class PgpKeyOperation { if (!isDivertToCard(masterSecretKey) && !cryptoInput.hasPassphrase()) { log.add(LogType.MSG_MF_REQUIRE_PASSPHRASE, indent); return new PgpEditKeyResult(log, RequiredInputParcel.createRequiredPassphrase( - masterSecretKey.getKeyID(), cryptoInput.getSignatureTime())); + masterSecretKey.getKeyID(), masterSecretKey.getKeyID(), + cryptoInput.getSignatureTime())); } // read masterKeyFlags, and use the same as before. @@ -431,7 +432,9 @@ public class PgpKeyOperation { int indent = 1; - NfcSignOperationsBuilder nfcSignOps = new NfcSignOperationsBuilder(cryptoInput.getSignatureTime()); + NfcSignOperationsBuilder nfcSignOps = new NfcSignOperationsBuilder( + cryptoInput.getSignatureTime(), masterSecretKey.getKeyID(), + masterSecretKey.getKeyID()); progress(R.string.progress_modify, 0); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java index 3d91812eb..d8d87114e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java @@ -18,19 +18,20 @@ public class RequiredInputParcel implements Parcelable { public final RequiredInputType mType; - public String mNfcPin = "123456"; public final byte[][] mInputHashes; public final int[] mSignAlgos; + private Long mMasterKeyId; private Long mSubKeyId; private RequiredInputParcel(RequiredInputType type, byte[][] inputHashes, - int[] signAlgos, Date signatureTime, Long keyId) { + int[] signAlgos, Date signatureTime, Long masterKeyId, Long subKeyId) { mType = type; mInputHashes = inputHashes; mSignAlgos = signAlgos; mSignatureTime = signatureTime; - mSubKeyId = keyId; + mMasterKeyId = masterKeyId; + mSubKeyId = subKeyId; } public RequiredInputParcel(Parcel source) { @@ -50,6 +51,7 @@ public class RequiredInputParcel implements Parcelable { } mSignatureTime = source.readInt() != 0 ? new Date(source.readLong()) : null; + mMasterKeyId = source.readInt() != 0 ? source.readLong() : null; mSubKeyId = source.readInt() != 0 ? source.readLong() : null; } @@ -61,19 +63,28 @@ public class RequiredInputParcel implements Parcelable { public static RequiredInputParcel createNfcSignOperation( byte[] inputHash, int signAlgo, Date signatureTime) { return new RequiredInputParcel(RequiredInputType.NFC_SIGN, - new byte[][] { inputHash }, new int[] { signAlgo }, signatureTime, null); + new byte[][] { inputHash }, new int[] { signAlgo }, + signatureTime, null, null); } public static RequiredInputParcel createNfcDecryptOperation(byte[] inputHash) { return new RequiredInputParcel(RequiredInputType.NFC_DECRYPT, - new byte[][] { inputHash }, null, null, null); + new byte[][] { inputHash }, null, null, null, null); } - public static RequiredInputParcel createRequiredPassphrase(long keyId, Date signatureTime) { + public static RequiredInputParcel createRequiredPassphrase( + long masterKeyId, long subKeyId, Date signatureTime) { return new RequiredInputParcel(RequiredInputType.PASSPHRASE, - null, null, signatureTime, keyId); + null, null, signatureTime, masterKeyId, subKeyId); } + public static RequiredInputParcel createRequiredPassphrase( + RequiredInputParcel req) { + return new RequiredInputParcel(RequiredInputType.PASSPHRASE, + null, null, req.mSignatureTime, req.mMasterKeyId, req.mSubKeyId); + } + + @Override public int describeContents() { return 0; @@ -98,6 +109,12 @@ public class RequiredInputParcel implements Parcelable { } else { dest.writeInt(0); } + if (mMasterKeyId != null) { + dest.writeInt(1); + dest.writeLong(mMasterKeyId); + } else { + dest.writeInt(0); + } if (mSubKeyId != null) { dest.writeInt(1); dest.writeLong(mSubKeyId); @@ -121,9 +138,13 @@ public class RequiredInputParcel implements Parcelable { Date mSignatureTime; ArrayList mSignAlgos = new ArrayList<>(); ArrayList mInputHashes = new ArrayList<>(); + long mMasterKeyId; + long mSubKeyId; - public NfcSignOperationsBuilder(Date signatureTime) { + public NfcSignOperationsBuilder(Date signatureTime, long masterKeyId, long subKeyId) { mSignatureTime = signatureTime; + mMasterKeyId = masterKeyId; + mSubKeyId = subKeyId; } public RequiredInputParcel build() { @@ -135,7 +156,7 @@ public class RequiredInputParcel implements Parcelable { } return new RequiredInputParcel(RequiredInputType.NFC_SIGN, - inputHashes, signAlgos, mSignatureTime, null); + inputHashes, signAlgos, mSignatureTime, mMasterKeyId, mSubKeyId); } public void addHash(byte[] hash, int algo) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java index 69467daac..68eee2513 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java @@ -26,6 +26,8 @@ import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.util.Iso7816TLV; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.Passphrase; +import org.sufficientlysecure.keychain.util.Preferences; import java.io.IOException; import java.nio.ByteBuffer; @@ -40,6 +42,8 @@ import java.nio.ByteBuffer; @TargetApi(Build.VERSION_CODES.GINGERBREAD_MR1) public class NfcOperationActivity extends BaseActivity { + public static final int REQUEST_CODE_PASSPHRASE = 1; + public static final String EXTRA_REQUIRED_INPUT = "required_input"; public static final String RESULT_DATA = "result_data"; @@ -49,7 +53,8 @@ public class NfcOperationActivity extends BaseActivity { private NfcAdapter mNfcAdapter; private IsoDep mIsoDep; - RequiredInputParcel mNfcOperations; + RequiredInputParcel mRequiredInput; + private Passphrase mPin; @Override protected void onCreate(Bundle savedInstanceState) { @@ -66,8 +71,38 @@ public class NfcOperationActivity extends BaseActivity { Bundle data = intent.getExtras(); - mNfcOperations = data.getParcelable(EXTRA_REQUIRED_INPUT); + mRequiredInput = data.getParcelable(EXTRA_REQUIRED_INPUT); + obtainPassphrase(); + + } + + private void obtainPassphrase() { + + Preferences prefs = Preferences.getPreferences(this); + if (prefs.useDefaultYubikeyPin()) { + mPin = new Passphrase("123456"); + return; + } + + Intent intent = new Intent(this, PassphraseDialogActivity.class); + intent.putExtra(PassphraseDialogActivity.EXTRA_REQUIRED_INPUT, + RequiredInputParcel.createRequiredPassphrase(mRequiredInput)); + startActivityForResult(intent, REQUEST_CODE_PASSPHRASE); + + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case REQUEST_CODE_PASSPHRASE: + CryptoInputParcel input = data.getParcelableExtra(PassphraseDialogActivity.RESULT_DATA); + mPin = input.getPassphrase(); + break; + + default: + super.onActivityResult(requestCode, resultCode, data); + } } @Override @@ -157,7 +192,7 @@ public class NfcOperationActivity extends BaseActivity { return; } - String pin = mNfcOperations.mNfcPin; + byte[] pin = new String(mPin.getCharArray()).getBytes(); // Command APDU for VERIFY command (page 32) String login = @@ -165,8 +200,8 @@ public class NfcOperationActivity extends BaseActivity { + "20" // INS + "00" // P1 + "82" // P2 (PW1) - + String.format("%02x", pin.length()) // Lc - + Hex.toHexString(pin.getBytes()); + + String.format("%02x", pin.length) // Lc + + Hex.toHexString(pin); if ( ! card(login).equals(accepted)) { // login toast("Wrong PIN!"); setResult(RESULT_CANCELED); @@ -174,23 +209,22 @@ public class NfcOperationActivity extends BaseActivity { return; } - CryptoInputParcel resultData = new CryptoInputParcel(mNfcOperations.mSignatureTime); + CryptoInputParcel resultData = new CryptoInputParcel(mRequiredInput.mSignatureTime); - switch (mNfcOperations.mType) { + switch (mRequiredInput.mType) { case NFC_DECRYPT: - - for (int i = 0; i < mNfcOperations.mInputHashes.length; i++) { - byte[] hash = mNfcOperations.mInputHashes[i]; + for (int i = 0; i < mRequiredInput.mInputHashes.length; i++) { + byte[] hash = mRequiredInput.mInputHashes[i]; byte[] decryptedSessionKey = nfcDecryptSessionKey(hash); resultData.addCryptoData(hash, decryptedSessionKey); } break; case NFC_SIGN: - for (int i = 0; i < mNfcOperations.mInputHashes.length; i++) { - byte[] hash = mNfcOperations.mInputHashes[i]; - int algo = mNfcOperations.mSignAlgos[i]; + for (int i = 0; i < mRequiredInput.mInputHashes.length; i++) { + byte[] hash = mRequiredInput.mInputHashes[i]; + int algo = mRequiredInput.mSignAlgos[i]; byte[] signedHash = nfcCalculateSignature(hash, algo); resultData.addCryptoData(hash, signedHash); }