diff options
author | Martijn Coenen <maco@google.com> | 2013-09-18 17:56:19 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-09-18 17:56:19 +0000 |
commit | af9fbc7f6bd0da8d13f56c16e801ace0ecc611fe (patch) | |
tree | 3d34fbc4d821b160f30a9d33155a036633f78d4b | |
parent | f51cf8c4d80e71b6637e0cf2134c20aae7ae3a77 (diff) | |
parent | f9366de7b3ad1ce90859d4194dacf13c0066926b (diff) | |
download | android_packages_apps_Nfc-af9fbc7f6bd0da8d13f56c16e801ace0ecc611fe.tar.gz android_packages_apps_Nfc-af9fbc7f6bd0da8d13f56c16e801ace0ecc611fe.tar.bz2 android_packages_apps_Nfc-af9fbc7f6bd0da8d13f56c16e801ace0ecc611fe.zip |
Merge "Reject invalid AIDs." into klp-dev
-rwxr-xr-x | src/com/android/nfc/NfcService.java | 6 | ||||
-rw-r--r-- | src/com/android/nfc/cardemulation/HostEmulationManager.java | 53 |
2 files changed, 45 insertions, 14 deletions
diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java index de3dff3f..448130dd 100755 --- a/src/com/android/nfc/NfcService.java +++ b/src/com/android/nfc/NfcService.java @@ -2141,6 +2141,12 @@ public class NfcService implements DeviceHostListener { case MSG_CARD_EMULATION: if (DBG) Log.d(TAG, "Card Emulation message"); + /* Tell the host-emu manager an AID has been selected on + * a secure element. + */ + if (mHostEmulationManager != null) { + mHostEmulationManager.notifyOffHostAidSelected(); + } byte[] aid = (byte[]) msg.obj; /* Send broadcast */ Intent aidIntent = new Intent(); diff --git a/src/com/android/nfc/cardemulation/HostEmulationManager.java b/src/com/android/nfc/cardemulation/HostEmulationManager.java index d8b395d8..2fe45ec8 100644 --- a/src/com/android/nfc/cardemulation/HostEmulationManager.java +++ b/src/com/android/nfc/cardemulation/HostEmulationManager.java @@ -44,6 +44,7 @@ import java.util.ArrayList; public class HostEmulationManager { static final String TAG = "HostEmulationManager"; + static final boolean DBG = false; static final int STATE_IDLE = 0; static final int STATE_W4_SELECT = 1; @@ -51,6 +52,14 @@ public class HostEmulationManager { static final int STATE_W4_DEACTIVATE = 3; static final int STATE_XFER = 4; + /** Minimum AID lenth as per ISO7816 */ + static final int MINIMUM_AID_LENGTH = 5; + + /** Length of Select APDU header including length byte */ + static final int SELECT_APDU_HDR_LENGTH = 5; + + static final byte INSTR_SELECT = (byte)0xA4; + static final byte[] AID_NOT_FOUND = {0x6A, (byte)0x82}; static final byte[] UNKNOWN_ERROR = {0x6F, 0x00}; @@ -246,6 +255,21 @@ public class HostEmulationManager { } } + public void notifyOffHostAidSelected() { + Log.d(TAG, "notifyOffHostAidSelected"); + synchronized (mLock) { + if (mState != STATE_XFER || mActiveService == null) { + // Don't bother telling, we're not bound to any service yet + } else { + sendDeactivateToActiveServiceLocked(HostApduService.DEACTIVATION_DESELECTED); + } + mActiveService = null; + mActiveServiceName = null; + unbindServiceIfNeededLocked(); + mState = STATE_W4_SELECT; + } + } + Messenger bindServiceIfNeededLocked(ComponentName service) { if (mPaymentServiceBound && mPaymentServiceName.equals(service)) { Log.d(TAG, "Service already bound as payment service."); @@ -342,10 +366,7 @@ public class HostEmulationManager { intent.setComponent(service); if (!mContext.bindServiceAsUser(intent, mPaymentConnection, Context.BIND_AUTO_CREATE, new UserHandle(userId))) { - // TODO Remove this - Log.d(TAG, "Failed to bind interface, trying legacy."); - mContext.bindServiceAsUser(intent, mPaymentConnection, - Context.BIND_AUTO_CREATE, new UserHandle(userId)); + Log.e(TAG, "Could not bind (persistent) payment service."); } } @@ -380,21 +401,25 @@ public class HostEmulationManager { } String findSelectAid(byte[] data) { - if (data == null || data.length < 6) { - Log.d(TAG, "Data size too small for SELECT APDU"); + if (data == null || data.length < SELECT_APDU_HDR_LENGTH + MINIMUM_AID_LENGTH) { + if (DBG) Log.d(TAG, "Data size too small for SELECT APDU"); return null; } - // TODO we'll support only logical channel 0 in CLA? - // TODO support chaining bits in CLA? - // TODO what about selection using DF/EF identifiers and/or path? - // TODO what about P2? - // TODO what about the default selection status? - if (data[0] == 0x00 && data[1] == (byte)0xA4 && data[2] == 0x04) { + // To accept a SELECT AID for dispatch, we require the following: + // Class byte must be 0x00: logical channel set to zero, no secure messaging, no chaining + // Instruction byte must be 0xA4: SELECT instruction + // P1: must be 0x04: select by application identifier + // P2: File control information is only relevant for higher-level application, + // and we only support "first or only occurrence". + if (data[0] == 0x00 && data[1] == INSTR_SELECT && data[2] == 0x04) { + if (data[3] != 0x00) { + Log.d(TAG, "Selecting next, last or previous AID occurrence is not supported"); + } int aidLength = data[4]; - if (data.length < 5 + aidLength) { + if (data.length < SELECT_APDU_HDR_LENGTH + aidLength) { return null; } - return bytesToString(data, 5, aidLength); + return bytesToString(data, SELECT_APDU_HDR_LENGTH, aidLength); } return null; } |