summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartijn Coenen <maco@google.com>2013-09-18 17:56:19 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-09-18 17:56:19 +0000
commitaf9fbc7f6bd0da8d13f56c16e801ace0ecc611fe (patch)
tree3d34fbc4d821b160f30a9d33155a036633f78d4b
parentf51cf8c4d80e71b6637e0cf2134c20aae7ae3a77 (diff)
parentf9366de7b3ad1ce90859d4194dacf13c0066926b (diff)
downloadandroid_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-xsrc/com/android/nfc/NfcService.java6
-rw-r--r--src/com/android/nfc/cardemulation/HostEmulationManager.java53
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;
}