diff options
author | Vincent Breitmoser <valodim@mugenguild.com> | 2015-10-01 17:28:43 +0200 |
---|---|---|
committer | Vincent Breitmoser <valodim@mugenguild.com> | 2015-10-01 17:28:43 +0200 |
commit | 7c79902a82602ff4e25b03e1232faa1a1768ba16 (patch) | |
tree | 03ec60c97bd961436ffffe17ad6917db768bfafa /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java | |
parent | 7f1dbccb5b1640482e9b83391400506f4ad40e04 (diff) | |
parent | 4f13dc4fc5e9be78a73fcc4bbafbc025baaf3aa0 (diff) | |
download | open-keychain-7c79902a82602ff4e25b03e1232faa1a1768ba16.tar.gz open-keychain-7c79902a82602ff4e25b03e1232faa1a1768ba16.tar.bz2 open-keychain-7c79902a82602ff4e25b03e1232faa1a1768ba16.zip |
Merge branch 'master' into encrypted-export
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java')
-rw-r--r-- | OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java | 125 |
1 files changed, 66 insertions, 59 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java index 972421abe..e68684c52 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java @@ -103,7 +103,7 @@ public abstract class BaseNfcActivity extends BaseActivity { /** * Override to handle result of NFC operations (UI thread) */ - protected void onNfcPostExecute() throws IOException { + protected void onNfcPostExecute() { final long subKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(mNfcFingerprints); @@ -134,9 +134,19 @@ public abstract class BaseNfcActivity extends BaseActivity { Notify.create(this, error, Style.WARN).show(); } + /** + * Override to do something when PIN is wrong, e.g., clear passphrases (UI thread) + */ + protected void onPinError() { + // use Toast because activity is finished afterwards + Toast.makeText(this, R.string.error_pin_wrong, Toast.LENGTH_LONG).show(); + setResult(RESULT_CANCELED); + finish(); + } + public void handleIntentInBackground(final Intent intent) { // Actual NFC operations are executed in doInBackground to not block the UI thread - new AsyncTask<Void, Void, Exception>() { + new AsyncTask<Void, Void, IOException>() { @Override protected void onPreExecute() { super.onPreExecute(); @@ -144,11 +154,9 @@ public abstract class BaseNfcActivity extends BaseActivity { } @Override - protected Exception doInBackground(Void... params) { + protected IOException doInBackground(Void... params) { try { handleTagDiscoveredIntent(intent); - } catch (CardException e) { - return e; } catch (IOException e) { return e; } @@ -157,7 +165,7 @@ public abstract class BaseNfcActivity extends BaseActivity { } @Override - protected void onPostExecute(Exception exception) { + protected void onPostExecute(IOException exception) { super.onPostExecute(exception); if (exception != null) { @@ -165,11 +173,7 @@ public abstract class BaseNfcActivity extends BaseActivity { return; } - try { - onNfcPostExecute(); - } catch (IOException e) { - handleNfcError(e); - } + onNfcPostExecute(); } }.execute(); } @@ -221,22 +225,30 @@ public abstract class BaseNfcActivity extends BaseActivity { } } - private void handleNfcError(Exception e) { - Log.e(Constants.TAG, "nfc error", e); + private void handleNfcError(IOException e) { if (e instanceof TagLostException) { onNfcError(getString(R.string.error_nfc_tag_lost)); return; } + if (e instanceof IsoDepNotSupportedException) { + onNfcError(getString(R.string.error_nfc_iso_dep_not_supported)); + return; + } + short status; if (e instanceof CardException) { status = ((CardException) e).getResponseCode(); } else { status = -1; } - // When entering a PIN, a status of 63CX indicates X attempts remaining. - if ((status & (short)0xFFF0) == 0x63C0) { + + // Wrong PIN, a status of 63CX indicates X attempts remaining. + if ((status & (short) 0xFFF0) == 0x63C0) { + // hook to do something different when PIN is wrong + onPinError(); + int tries = status & 0x000F; onNfcError(getResources().getQuantityString(R.plurals.error_pin, tries, tries)); return; @@ -307,12 +319,6 @@ public abstract class BaseNfcActivity extends BaseActivity { } - public void handlePinError() { - toast("Wrong PIN!"); - setResult(RESULT_CANCELED); - finish(); - } - /** * Called when the system is about to start resuming a previous activity, * disables NFC Foreground Dispatch @@ -337,7 +343,7 @@ public abstract class BaseNfcActivity extends BaseActivity { protected void obtainYubiKeyPin(RequiredInputParcel requiredInput) { - // shortcut if we only use the default yubikey pin + // shortcut if we only use the default YubiKey pin Preferences prefs = Preferences.getPreferences(this); if (prefs.useDefaultYubiKeyPin()) { mPin = new Passphrase("123456"); @@ -345,10 +351,10 @@ public abstract class BaseNfcActivity extends BaseActivity { } try { - Passphrase phrase = PassphraseCacheService.getCachedPassphrase(this, + Passphrase passphrase = PassphraseCacheService.getCachedPassphrase(this, requiredInput.getMasterKeyId(), requiredInput.getSubKeyId()); - if (phrase != null) { - mPin = phrase; + if (passphrase != null) { + mPin = passphrase; return; } @@ -363,10 +369,6 @@ public abstract class BaseNfcActivity extends BaseActivity { } - protected void setYubiKeyPin(Passphrase pin) { - mPin = pin; - } - @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { @@ -406,6 +408,9 @@ public abstract class BaseNfcActivity extends BaseActivity { // Connect to the detected tag, setting a couple of settings mIsoDep = IsoDep.get(detectedTag); + if (mIsoDep == null) { + throw new IsoDepNotSupportedException("Tag does not support ISO-DEP (ISO 14443-4)"); + } mIsoDep.setTimeout(TIMEOUT); // timeout is set to 100 seconds to avoid cancellation during calculation mIsoDep.connect(); @@ -448,7 +453,7 @@ public abstract class BaseNfcActivity extends BaseActivity { * @return The long key id of the requested key, or null if not found. */ public Long nfcGetKeyId(int idx) throws IOException { - byte[] fp = nfcGetFingerprint(idx); + byte[] fp = nfcGetMasterKeyFingerprint(idx); if (fp == null) { return null; } @@ -469,7 +474,7 @@ public abstract class BaseNfcActivity extends BaseActivity { byte[] buf = mIsoDep.transceive(Hex.decode(data)); Iso7816TLV tlv = Iso7816TLV.readSingle(buf, true); - Log.d(Constants.TAG, "nfc tlv data:\n" + tlv.prettyPrint()); + Log.d(Constants.TAG, "nfcGetFingerprints() Iso7816TLV tlv data:\n" + tlv.prettyPrint()); Iso7816TLV fptlv = Iso7816TLV.findRecursive(tlv, 0xc5); if (fptlv == null) { @@ -494,8 +499,11 @@ public abstract class BaseNfcActivity extends BaseActivity { * @param idx Index of the key to return the fingerprint from. * @return The fingerprint of the requested key, or null if not found. */ - public byte[] nfcGetFingerprint(int idx) throws IOException { + public byte[] nfcGetMasterKeyFingerprint(int idx) throws IOException { byte[] data = nfcGetFingerprints(); + if (data == null) { + return null; + } // return the master key fingerprint ByteBuffer fpbuf = ByteBuffer.wrap(data); @@ -507,14 +515,11 @@ public abstract class BaseNfcActivity extends BaseActivity { } public byte[] nfcGetAid() throws IOException { - String info = "00CA004F00"; return mIsoDep.transceive(Hex.decode(info)); - } public String nfcGetUserId() throws IOException { - String info = "00CA006500"; return nfcGetHolderName(nfcCommunicate(info)); } @@ -648,8 +653,6 @@ public abstract class BaseNfcActivity extends BaseActivity { String decryptedSessionKey = nfcGetDataField(second); - Log.d(Constants.TAG, "decryptedSessionKey: " + decryptedSessionKey); - return Hex.decode(decryptedSessionKey); } @@ -682,7 +685,6 @@ public abstract class BaseNfcActivity extends BaseActivity { + Hex.toHexString(pin); String response = nfcCommunicate(login); // login if (!response.equals(accepted)) { - handlePinError(); throw new CardException("Bad PIN!", parseCardStatus(response)); } @@ -737,7 +739,6 @@ public abstract class BaseNfcActivity extends BaseActivity { + getHex(newPin); String response = nfcCommunicate(changeReferenceDataApdu); // change PIN if (!response.equals("9000")) { - handlePinError(); throw new CardException("Failed to change PIN", parseCardStatus(response)); } } @@ -906,15 +907,6 @@ public abstract class BaseNfcActivity extends BaseActivity { } /** - * Prints a message to the screen - * - * @param text the text which should be contained within the toast - */ - protected void toast(String text) { - Toast.makeText(this, text, Toast.LENGTH_LONG).show(); - } - - /** * Receive new NFC Intents to this activity only by enabling foreground dispatch. * This can only be done in onResume! */ @@ -930,12 +922,10 @@ public abstract class BaseNfcActivity extends BaseActivity { new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED) }; - // https://code.google.com/p/android/issues/detail?id=62918 - // maybe mNfcAdapter.enableReaderMode(); ? try { mNfcAdapter.enableForegroundDispatch(this, nfcPendingIntent, writeTagFilters, null); } catch (IllegalStateException e) { - Log.i(Constants.TAG, "NfcForegroundDispatch Error!", e); + Log.i(Constants.TAG, "NfcForegroundDispatch Exception: Activity is not currently in the foreground?", e); } Log.d(Constants.TAG, "NfcForegroundDispatch has been enabled!"); } @@ -952,14 +942,23 @@ public abstract class BaseNfcActivity extends BaseActivity { } public String nfcGetHolderName(String name) { - String slength; - int ilength; - name = name.substring(6); - slength = name.substring(0, 2); - ilength = Integer.parseInt(slength, 16) * 2; - name = name.substring(2, ilength + 2); - name = (new String(Hex.decode(name))).replace('<', ' '); - return (name); + try { + String slength; + int ilength; + name = name.substring(6); + slength = name.substring(0, 2); + ilength = Integer.parseInt(slength, 16) * 2; + name = name.substring(2, ilength + 2); + name = (new String(Hex.decode(name))).replace('<', ' '); + return name; + } catch (IndexOutOfBoundsException e) { + // try-catch for https://github.com/FluffyKaon/OpenPGP-Card + // Note: This should not happen, but happens with + // https://github.com/FluffyKaon/OpenPGP-Card, thus return an empty string for now! + + Log.e(Constants.TAG, "Couldn't get holder name, returning empty string!", e); + return ""; + } } private String nfcGetDataField(String output) { @@ -974,6 +973,14 @@ public abstract class BaseNfcActivity extends BaseActivity { return new String(Hex.encode(raw)); } + public class IsoDepNotSupportedException extends IOException { + + public IsoDepNotSupportedException(String detailMessage) { + super(detailMessage); + } + + } + public class CardException extends IOException { private short mResponseCode; |