summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartijn Coenen <maco@google.com>2013-10-22 15:09:49 -0700
committerMartijn Coenen <maco@google.com>2013-10-23 12:51:48 -0700
commitdba891595bc0bbcb8f0810b4d014e935aa1955c5 (patch)
treed8b541b0fed7084a5137b88a750964d1fa3e7248
parentaa907049d48c734036c7aedaf065cb230a7bb045 (diff)
downloadandroid_packages_apps_Nfc-dba891595bc0bbcb8f0810b4d014e935aa1955c5.tar.gz
android_packages_apps_Nfc-dba891595bc0bbcb8f0810b4d014e935aa1955c5.tar.bz2
android_packages_apps_Nfc-dba891595bc0bbcb8f0810b4d014e935aa1955c5.zip
HCE: Fix potential crash and handle Android AID.
For new "default route" CTS test. Also, fix a potential crash for starting off-host services and check that HCE services have declared the NFC permission. Bug: 10681671 Change-Id: If86d9820d6eef5a0661be92be67168d5f81ddc64
-rw-r--r--src/com/android/nfc/cardemulation/HostEmulationManager.java15
-rw-r--r--src/com/android/nfc/cardemulation/RegisteredServicesCache.java8
2 files changed, 23 insertions, 0 deletions
diff --git a/src/com/android/nfc/cardemulation/HostEmulationManager.java b/src/com/android/nfc/cardemulation/HostEmulationManager.java
index 0dc75b59..a4e7f757 100644
--- a/src/com/android/nfc/cardemulation/HostEmulationManager.java
+++ b/src/com/android/nfc/cardemulation/HostEmulationManager.java
@@ -60,6 +60,9 @@ public class HostEmulationManager {
static final byte INSTR_SELECT = (byte)0xA4;
+ static final String ANDROID_HCE_AID = "A000000476416E64726F6964484345";
+ static final byte[] ANDROID_HCE_RESPONSE = {0x14, (byte)0x81, 0x00, 0x00, (byte)0x90, 0x00};
+
static final byte[] AID_NOT_FOUND = {0x6A, (byte)0x82};
static final byte[] UNKNOWN_ERROR = {0x6F, 0x00};
@@ -161,6 +164,10 @@ public class HostEmulationManager {
return;
}
if (selectAid != null) {
+ if (selectAid.equals(ANDROID_HCE_AID)) {
+ NfcService.getInstance().sendData(ANDROID_HCE_RESPONSE);
+ return;
+ }
AidResolveInfo resolveInfo = mAidCache.resolveAidPrefix(selectAid);
if (resolveInfo == null || resolveInfo.services.size() == 0) {
// Tell the remote we don't handle this AID
@@ -179,6 +186,14 @@ public class HostEmulationManager {
launchTapAgain(resolveInfo.defaultService, category);
return;
}
+ // In no circumstance should this be an OffHostService -
+ // we should never get this AID on the host in the first place
+ if (!resolveInfo.defaultService.isOnHost()) {
+ Log.e(TAG, "AID that was meant to go off-host was routed to host." +
+ " Check routing table configuration.");
+ NfcService.getInstance().sendData(AID_NOT_FOUND);
+ return;
+ }
resolvedService = resolveInfo.defaultService.getComponent();
} else if (mActiveServiceName != null) {
for (ApduServiceInfo service : resolveInfo.services) {
diff --git a/src/com/android/nfc/cardemulation/RegisteredServicesCache.java b/src/com/android/nfc/cardemulation/RegisteredServicesCache.java
index 2e037d2c..0cfc0e0b 100644
--- a/src/com/android/nfc/cardemulation/RegisteredServicesCache.java
+++ b/src/com/android/nfc/cardemulation/RegisteredServicesCache.java
@@ -207,6 +207,14 @@ public class RegisteredServicesCache {
boolean onHost = !resolvedOffHostServices.contains(resolvedService);
ServiceInfo si = resolvedService.serviceInfo;
ComponentName componentName = new ComponentName(si.packageName, si.name);
+ // Check if the package holds the NFC permission
+ if (pm.checkPermission(android.Manifest.permission.NFC, si.packageName) !=
+ PackageManager.PERMISSION_GRANTED) {
+ Log.e(TAG, "Skipping APDU service " + componentName +
+ ": it does not require the permission " +
+ android.Manifest.permission.NFC);
+ continue;
+ }
if (!android.Manifest.permission.BIND_NFC_SERVICE.equals(
si.permission)) {
Log.e(TAG, "Skipping APDU service " + componentName +