summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-01-18 02:21:03 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-01-18 02:21:03 +0000
commitad7ee467d57d28c5e852efc0850fc0c106fb0e5a (patch)
tree4b14a3d11e317ec2539ff0ceed7b874c3604ab03
parent0260a8c34fbc70772c90dcd129dd95dfa3ab6bf1 (diff)
parentaa39f5e4a17d1b439f568ee3c629ccee8d66bb6a (diff)
downloadSecureElement-ad7ee467d57d28c5e852efc0850fc0c106fb0e5a.tar.gz
Add Carrier Privilege support am: 2b58f07680 am: aa39f5e4a1
Change-Id: Ifa56c3fba9cf26c0d92e58e62fe83d952b851394
-rw-r--r--src/com/android/se/Terminal.java68
-rw-r--r--src/com/android/se/security/AccessControlEnforcer.java29
-rw-r--r--src/com/android/se/security/AccessRuleCache.java39
-rwxr-xr-xsrc/com/android/se/security/ChannelAccess.java11
4 files changed, 134 insertions, 13 deletions
diff --git a/src/com/android/se/Terminal.java b/src/com/android/se/Terminal.java
index c248c89..d7d9d99 100644
--- a/src/com/android/se/Terminal.java
+++ b/src/com/android/se/Terminal.java
@@ -24,7 +24,9 @@
package com.android.se;
import android.content.Context;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.hardware.secure_element.V1_0.ISecureElement;
import android.hardware.secure_element.V1_0.ISecureElementHalCallback;
import android.hardware.secure_element.V1_0.LogicalChannelResponse;
@@ -387,17 +389,19 @@ public class Terminal {
throw new IOException("Secure Element is not connected");
}
- Log.w(mTag, "Enable access control on basic channel for " + packageName);
- StatsLog.write(
- StatsLog.SE_OMAPI_REPORTED,
- StatsLog.SE_OMAPI_REPORTED__OPERATION__OPEN_CHANNEL,
- mName,
- packageName);
- ChannelAccess channelAccess;
- try {
- channelAccess = setUpChannelAccess(aid, packageName, pid);
- } catch (MissingResourceException e) {
- return null;
+ ChannelAccess channelAccess = null;
+ if (packageName != null) {
+ Log.w(mTag, "Enable access control on basic channel for " + packageName);
+ StatsLog.write(
+ StatsLog.SE_OMAPI_REPORTED,
+ StatsLog.SE_OMAPI_REPORTED__OPERATION__OPEN_CHANNEL,
+ mName,
+ packageName);
+ try {
+ channelAccess = setUpChannelAccess(aid, packageName, pid);
+ } catch (MissingResourceException e) {
+ return null;
+ }
}
synchronized (mLock) {
@@ -680,6 +684,9 @@ public class Terminal {
if (isPrivilegedApplication(packageName)) {
return ChannelAccess.getPrivilegeAccess(packageName, pid);
+ } else if (getName().startsWith(SecureElementService.UICC_TERMINAL)
+ && isCarrierPrivilegeApplication(packageName)) {
+ return ChannelAccess.getCarrierPrivilegeAccess(packageName, pid);
}
synchronized (mLock) {
@@ -739,6 +746,45 @@ public class Terminal {
return mContext;
}
+ /**
+ * Checks if Carrier Privilege exists for the given package
+ */
+ private boolean isCarrierPrivilegeApplication(String packageName) {
+ try {
+ PackageManager pm = mContext.getPackageManager();
+ if (pm != null) {
+ PackageInfo pkgInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+ return checkCarrierPrivilegeRules(pkgInfo);
+ }
+ } catch (NameNotFoundException ne) { }
+ return false;
+ }
+
+ /**
+ * Checks if Carrier Privilege exists for the given package
+ */
+ public boolean checkCarrierPrivilegeRules(PackageInfo pInfo) {
+ boolean checkRefreshTag = true;
+ if (mAccessControlEnforcer == null || mAccessControlEnforcer.isNoRuleFound()) {
+ try {
+ initializeAccessControl();
+ } catch (IOException e) {
+ return false;
+ }
+ checkRefreshTag = false;
+ }
+ mAccessControlEnforcer.setPackageManager(mContext.getPackageManager());
+
+ synchronized (mLock) {
+ try {
+ return mAccessControlEnforcer.checkCarrierPrivilege(pInfo, checkRefreshTag);
+ } catch (Exception e) {
+ Log.i(mTag, "checkCarrierPrivilege() Exception: " + e.getMessage());
+ return false;
+ }
+ }
+ }
+
/** Dump data for debug purpose . */
public void dump(PrintWriter writer) {
writer.println("SECURE ELEMENT SERVICE TERMINAL: " + mName);
diff --git a/src/com/android/se/security/AccessControlEnforcer.java b/src/com/android/se/security/AccessControlEnforcer.java
index a4ceb70..bcf3a9a 100644
--- a/src/com/android/se/security/AccessControlEnforcer.java
+++ b/src/com/android/se/security/AccessControlEnforcer.java
@@ -451,6 +451,35 @@ public class AccessControlEnforcer {
}
}
+ /** Returns true if the given package has Carrier Privileges */
+ public synchronized boolean checkCarrierPrivilege(PackageInfo pInfo, boolean checkRefreshTag) {
+ if (!mUseAra && !mUseArf) {
+ return false;
+ }
+ if (checkRefreshTag) {
+ try {
+ updateAccessRuleIfNeed();
+ } catch (IOException | MissingResourceException e) {
+ throw new AccessControlException("Access-Control not found in "
+ + mTerminal.getName());
+ }
+ }
+ if (mRulesRead) {
+ return false;
+ }
+ try {
+ List<byte[]> appCertHashes = getAppCertHashes(pInfo.packageName);
+ if (appCertHashes == null || appCertHashes.size() == 0) {
+ return false;
+ }
+
+ return mAccessRuleCache.checkCarrierPrivilege(pInfo.packageName, appCertHashes);
+ } catch (Exception e) {
+ Log.w(mTag, " checkCarrierPrivilege: " + e.getLocalizedMessage());
+ }
+ return false;
+ }
+
/** Debug information to be used by dumpsys */
public void dump(PrintWriter writer) {
writer.println(mTag + ":");
diff --git a/src/com/android/se/security/AccessRuleCache.java b/src/com/android/se/security/AccessRuleCache.java
index 6d854c0..97c63bb 100644
--- a/src/com/android/se/security/AccessRuleCache.java
+++ b/src/com/android/se/security/AccessRuleCache.java
@@ -41,6 +41,7 @@ import android.util.Log;
import com.android.se.security.gpac.AID_REF_DO;
import com.android.se.security.gpac.AR_DO;
import com.android.se.security.gpac.Hash_REF_DO;
+import com.android.se.security.gpac.PKG_REF_DO;
import com.android.se.security.gpac.REF_DO;
import java.io.PrintWriter;
@@ -65,6 +66,7 @@ public class AccessRuleCache {
// recreated.
private byte[] mRefreshTag = null;
private Map<REF_DO, ChannelAccess> mRuleCache = new HashMap<REF_DO, ChannelAccess>();
+ private ArrayList<REF_DO> mCarrierPrivilegeCache = new ArrayList<REF_DO>();
private static AID_REF_DO getAidRefDo(byte[] aid) {
byte[] defaultAid = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00};
@@ -132,17 +134,19 @@ public class AccessRuleCache {
public void reset() {
mRefreshTag = null;
mRuleCache.clear();
+ mCarrierPrivilegeCache.clear();
}
/** Clears access rule cache only. */
public void clearCache() {
mRuleCache.clear();
+ mCarrierPrivilegeCache.clear();
}
/** Adds the Rule to the Cache */
public void putWithMerge(REF_DO refDo, AR_DO arDo) {
if (refDo.isCarrierPrivilegeRefDo()) {
- // Ignore Carrier Privilege Rules
+ mCarrierPrivilegeCache.add(refDo);
return;
}
ChannelAccess channelAccess = mapArDo2ChannelAccess(arDo);
@@ -152,7 +156,7 @@ public class AccessRuleCache {
/** Adds the Rule to the Cache */
public void putWithMerge(REF_DO refDo, ChannelAccess channelAccess) {
if (refDo.isCarrierPrivilegeRefDo()) {
- // Ignore Carrier Privilege Rules
+ mCarrierPrivilegeCache.add(refDo);
return;
}
if (mRuleCache.containsKey(refDo)) {
@@ -443,6 +447,27 @@ public class AccessRuleCache {
return null;
}
+ /** Check if the carrier privilege exists for the given package */
+ public boolean checkCarrierPrivilege(String packageName, List<byte[]> appCertHashes) {
+ for (byte[] hash : appCertHashes) {
+ for (REF_DO ref_do : mCarrierPrivilegeCache) {
+ Hash_REF_DO hash_ref_do = ref_do.getHashDo();
+ PKG_REF_DO pkg_ref_do = ref_do.getPkgDo();
+ if (Hash_REF_DO.equals(hash_ref_do, new Hash_REF_DO(hash))) {
+ // If PKG_REF_DO exists then package name should match, otherwise allow
+ if (pkg_ref_do != null) {
+ if (packageName.equals(pkg_ref_do.getPackageName())) {
+ return true;
+ }
+ } else {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
/** Check if the given Refresh Tag is equal to the last known */
public boolean isRefreshTagEqual(byte[] refreshTag) {
if (refreshTag == null || mRefreshTag == null) return false;
@@ -481,5 +506,15 @@ public class AccessRuleCache {
writer.println(entry.getKey().toString() + " -> " + entry.getValue().toString());
}
writer.println();
+
+ /* Dump the Carrier Privilege cache */
+ writer.println("Carrier Privilege:");
+ i = 0;
+ for (REF_DO ref_do : mCarrierPrivilegeCache) {
+ i++;
+ writer.print("carrier privilege " + i + ": ");
+ writer.println(ref_do.toString());
+ }
+ writer.println();
}
}
diff --git a/src/com/android/se/security/ChannelAccess.java b/src/com/android/se/security/ChannelAccess.java
index 31ca45e..d75ad15 100755
--- a/src/com/android/se/security/ChannelAccess.java
+++ b/src/com/android/se/security/ChannelAccess.java
@@ -144,6 +144,17 @@ public class ChannelAccess {
return ca;
}
+ /** Provides the ChannelAccess with CarrierPrivilege Access */
+ public static ChannelAccess getCarrierPrivilegeAccess(String packageName, int pid) {
+ ChannelAccess ca = new ChannelAccess();
+ ca.setPackageName(packageName);
+ ca.setCallingPid(pid);
+ ca.setAccess(ACCESS.ALLOWED, "Carrier-Privilege");
+ ca.setApduAccess(ACCESS.ALLOWED);
+
+ return ca;
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();