Merge "Add useful logs regarding channels and ATR"
diff --git a/src/com/android/se/security/AccessControlEnforcer.java b/src/com/android/se/security/AccessControlEnforcer.java
index 2366ce7..07df7e6 100644
--- a/src/com/android/se/security/AccessControlEnforcer.java
+++ b/src/com/android/se/security/AccessControlEnforcer.java
@@ -46,6 +46,7 @@
 import com.android.se.Channel;
 import com.android.se.SecureElementService;
 import com.android.se.Terminal;
+import com.android.se.internal.ByteArrayConverter;
 import com.android.se.security.ChannelAccess.ACCESS;
 import com.android.se.security.ara.AraController;
 import com.android.se.security.arf.ArfController;
@@ -64,6 +65,7 @@
 public class AccessControlEnforcer {
 
     private final String mTag = "SecureElement-AccessControlEnforcer";
+    private static final boolean DEBUG = Build.IS_DEBUGGABLE;
     private PackageManager mPackageManager = null;
     private boolean mNoRuleFound = false;
     private AraController mAraController = null;
@@ -235,7 +237,11 @@
         }
         String reason = ca.getReason();
         if (reason.length() == 0) {
-            reason = "Command not allowed!";
+            reason = "Unspecified";
+        }
+        if (DEBUG) {
+            Log.i(mTag, "checkCommand() : Access = " + ca.getAccess() + " APDU Access = "
+                    + ca.getApduAccess() + " Reason = " + reason);
         }
         if (ca.getAccess() != ACCESS.ALLOWED) {
             throw new AccessControlException(mTag + reason);
@@ -318,6 +324,12 @@
     public ChannelAccess getAccessRule(
             byte[] aid, List<byte []> appCertHashes)
             throws AccessControlException {
+        if (DEBUG) {
+            for (byte[] appCertHash : appCertHashes) {
+                Log.i(mTag, "getAccessRule() appCert = "
+                        + ByteArrayConverter.byteArrayToHexString(appCertHash));
+            }
+        }
         ChannelAccess channelAccess = null;
         // if read all is true get rule from cache.
         if (mRulesRead) {
diff --git a/src/com/android/se/security/AccessRuleCache.java b/src/com/android/se/security/AccessRuleCache.java
index 8a74465..2d3763b 100644
--- a/src/com/android/se/security/AccessRuleCache.java
+++ b/src/com/android/se/security/AccessRuleCache.java
@@ -257,6 +257,31 @@
     /** Find Access Rule for the given AID and Application */
     public ChannelAccess findAccessRule(byte[] aid, List<byte[]> appCertHashes)
             throws AccessControlException {
+        ChannelAccess ca = findAccessRuleInternal(aid, appCertHashes);
+        if (ca != null) {
+            if ((ca.getApduAccess() == ChannelAccess.ACCESS.UNDEFINED) && !ca.isUseApduFilter()) {
+                // Rule for APDU access does not exist.
+                // All the APDU access requests shall never be allowed in this case.
+                // This missing rule resolution is valid for both ARA and ARF
+                // if the supported GP SEAC version is v1.1 or later.
+                ca.setApduAccess(ChannelAccess.ACCESS.DENIED);
+            }
+            if (ca.getNFCEventAccess() == ChannelAccess.ACCESS.UNDEFINED) {
+                // Missing NFC access rule shall be treated as ALLOWED
+                // if relevant APDU access rule is ALLOWED or APDU filter is specified.
+                if (ca.isUseApduFilter()) {
+                    ca.setNFCEventAccess(ChannelAccess.ACCESS.ALLOWED);
+                } else {
+                    ca.setNFCEventAccess(ca.getApduAccess());
+                }
+            }
+            // Note that the GP SEAC v1.1 has not been supported as GSMA TS.26 does not require it.
+        }
+        return ca;
+    }
+
+    private ChannelAccess findAccessRuleInternal(byte[] aid, List<byte[]> appCertHashes)
+            throws AccessControlException {
 
         // TODO: check difference between DeviceCertHash and Certificate Chain (EndEntityCertHash,
         // IntermediateCertHash (1..n), RootCertHash)
@@ -276,17 +301,8 @@
             ref_do = new REF_DO(aid_ref_do, hash_ref_do);
 
             if (mRuleCache.containsKey(ref_do)) {
-                // let's take care about the undefined rules, according to the GP specification:
-                ChannelAccess ca = mRuleCache.get(ref_do);
-                if (ca.getApduAccess() == ChannelAccess.ACCESS.UNDEFINED) {
-                    ca.setApduAccess(ChannelAccess.ACCESS.DENIED);
-                }
-                if ((ca.getNFCEventAccess() == ChannelAccess.ACCESS.UNDEFINED)
-                        && (ca.getApduAccess() != ChannelAccess.ACCESS.UNDEFINED)) {
-                    ca.setNFCEventAccess(ca.getApduAccess());
-                }
                 if (DEBUG) {
-                    Log.i(mTag, "findAccessRule() " + ref_do.toString() + ", "
+                    Log.i(mTag, "findAccessRule() Case A " + ref_do.toString() + ", "
                             + mRuleCache.get(ref_do).toString());
                 }
                 return mRuleCache.get(ref_do);
@@ -313,17 +329,8 @@
         ref_do = new REF_DO(aid_ref_do, hash_ref_do);
 
         if (mRuleCache.containsKey(ref_do)) {
-            // let's take care about the undefined rules, according to the GP specification:
-            ChannelAccess ca = mRuleCache.get(ref_do);
-            if (ca.getApduAccess() == ChannelAccess.ACCESS.UNDEFINED) {
-                ca.setApduAccess(ChannelAccess.ACCESS.DENIED);
-            }
-            if ((ca.getNFCEventAccess() == ChannelAccess.ACCESS.UNDEFINED)
-                    && (ca.getApduAccess() != ChannelAccess.ACCESS.UNDEFINED)) {
-                ca.setNFCEventAccess(ca.getApduAccess());
-            }
             if (DEBUG) {
-                Log.i(mTag, "findAccessRule() " + ref_do.toString() + ", "
+                Log.i(mTag, "findAccessRule() Case B " + ref_do.toString() + ", "
                         + mRuleCache.get(ref_do).toString());
             }
             return mRuleCache.get(ref_do);
@@ -336,17 +343,8 @@
             ref_do = new REF_DO(aid_ref_do, hash_ref_do);
 
             if (mRuleCache.containsKey(ref_do)) {
-                // let's take care about the undefined rules, according to the GP specification:
-                ChannelAccess ca = mRuleCache.get(ref_do);
-                if (ca.getApduAccess() == ChannelAccess.ACCESS.UNDEFINED) {
-                    ca.setApduAccess(ChannelAccess.ACCESS.DENIED);
-                }
-                if ((ca.getNFCEventAccess() == ChannelAccess.ACCESS.UNDEFINED)
-                        && (ca.getApduAccess() != ChannelAccess.ACCESS.UNDEFINED)) {
-                    ca.setNFCEventAccess(ca.getApduAccess());
-                }
                 if (DEBUG) {
-                    Log.i(mTag, "findAccessRule() " + ref_do.toString() + ", "
+                    Log.i(mTag, "findAccessRule() Case C " + ref_do.toString() + ", "
                             + mRuleCache.get(ref_do).toString());
                 }
                 return mRuleCache.get(ref_do);
@@ -375,17 +373,8 @@
         ref_do = new REF_DO(aid_ref_do, hash_ref_do);
 
         if (mRuleCache.containsKey(ref_do)) {
-            // let's take care about the undefined rules, according to the GP specification:
-            ChannelAccess ca = mRuleCache.get(ref_do);
-            if (ca.getApduAccess() == ChannelAccess.ACCESS.UNDEFINED) {
-                ca.setApduAccess(ChannelAccess.ACCESS.DENIED);
-            }
-            if ((ca.getNFCEventAccess() == ChannelAccess.ACCESS.UNDEFINED)
-                    && (ca.getApduAccess() != ChannelAccess.ACCESS.UNDEFINED)) {
-                ca.setNFCEventAccess(ca.getApduAccess());
-            }
             if (DEBUG) {
-                Log.i(mTag, "findAccessRule() " + ref_do.toString() + ", "
+                Log.i(mTag, "findAccessRule() Case D " + ref_do.toString() + ", "
                         + mRuleCache.get(ref_do).toString());
             }
             return mRuleCache.get(ref_do);
diff --git a/src/com/android/se/security/ara/AraController.java b/src/com/android/se/security/ara/AraController.java
index 1e1fee8..bc4ea19 100644
--- a/src/com/android/se/security/ara/AraController.java
+++ b/src/com/android/se/security/ara/AraController.java
@@ -95,7 +95,7 @@
 
         // set access conditions to access ARA-M.
         ChannelAccess araChannelAccess = new ChannelAccess();
-        araChannelAccess.setAccess(ChannelAccess.ACCESS.ALLOWED, mTag);
+        araChannelAccess.setAccess(ChannelAccess.ACCESS.ALLOWED, "");
         araChannelAccess.setApduAccess(ChannelAccess.ACCESS.ALLOWED);
         channel.setChannelAccess(araChannelAccess);