UiccCarrierPrivilegeRules.java revision 32bbe4213fc554ebf00553cd9935d17fe7530aa1
14baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal/* 24baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * Copyright (C) 2014 The Android Open Source Project 34baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * 44baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * Licensed under the Apache License, Version 2.0 (the "License"); 54baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * you may not use this file except in compliance with the License. 64baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * You may obtain a copy of the License at 74baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * 84baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * http://www.apache.org/licenses/LICENSE-2.0 94baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * 104baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * Unless required by applicable law or agreed to in writing, software 114baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * distributed under the License is distributed on an "AS IS" BASIS, 124baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * See the License for the specific language governing permissions and 144baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * limitations under the License. 154baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal */ 164baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 174baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalpackage com.android.internal.telephony.uicc; 184baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 19c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawalimport android.content.Intent; 20c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawalimport android.content.pm.PackageInfo; 21c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawalimport android.content.pm.PackageManager; 22c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawalimport android.content.pm.ResolveInfo; 234baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport android.content.pm.Signature; 244baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport android.os.AsyncResult; 25c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawalimport android.os.Binder; 264baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport android.os.Handler; 274baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport android.os.Message; 284baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport android.telephony.Rlog; 294baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport android.telephony.TelephonyManager; 304baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 314baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport com.android.internal.telephony.CommandsInterface; 324baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport com.android.internal.telephony.uicc.IccUtils; 334baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 344baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport java.io.ByteArrayInputStream; 354baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport java.lang.IllegalArgumentException; 364baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport java.security.MessageDigest; 374baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport java.security.NoSuchAlgorithmException; 384baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport java.security.cert.Certificate; 394baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport java.security.cert.CertificateException; 404baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport java.security.cert.CertificateFactory; 414baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport java.security.cert.X509Certificate; 424baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport java.util.ArrayList; 434baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport java.util.Arrays; 444baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport java.util.List; 454baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport java.util.Locale; 467f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawalimport java.util.concurrent.atomic.AtomicInteger; 474baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 484baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal/** 494baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * Class that reads and stores the carrier privileged rules from the UICC. 504baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * 514baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * The rules are read when the class is created, hence it should only be created 524baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * after the UICC can be read. And it should be deleted when a UICC is changed. 534baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * 544baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * The spec for the rules: 55e5b5f10d2d09f62c265381cab0816edfbdf566f0Junda Liu * GP Secure Element Access Control: 56e5b5f10d2d09f62c265381cab0816edfbdf566f0Junda Liu * http://www.globalplatform.org/specifications/review/GPD_SE_Access_Control_v1.0.20.pdf 57e5b5f10d2d09f62c265381cab0816edfbdf566f0Junda Liu * Extension spec: 58e5b5f10d2d09f62c265381cab0816edfbdf566f0Junda Liu * https://code.google.com/p/seek-for-android/ 594baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * 604baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * 614baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * TODO: Notifications. 624baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * 634baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * {@hide} 644baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal */ 654baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalpublic class UiccCarrierPrivilegeRules extends Handler { 664baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final String LOG_TAG = "UiccCarrierPrivilegeRules"; 674baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 68e5b5f10d2d09f62c265381cab0816edfbdf566f0Junda Liu private static final String AID = "A00000015141434C00"; 694baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final int CLA = 0x80; 70004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu private static final int COMMAND = 0xB0; 71004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu private static final int P1 = 0x00; 72004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu private static final int P2 = 0x00; 734baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final int P3 = 0x00; 744baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final String DATA = ""; 754baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 76004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu /* 77004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * Rules format: 78004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * ALL_REF_AR_DO = TAG_ALL_REF_AR_DO + len + [REF_AR_DO]*n 79004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * REF_AR_DO = TAG_REF_AR_DO + len + REF-DO + AR-DO 80004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * 81004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * REF_DO = TAG_REF_DO + len + DEVICE_APP_ID_REF_DO + (optional) PKG_REF_DO 82004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * AR_DO = TAG_AR_DO + len + PERM_AR_DO 83004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * 84004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * DEVICE_APP_ID_REF_DO = TAG_DEVICE_APP_ID_REF_DO + len + sha1 hexstring of cert (20 bytes) 85004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * PKG_REF_DO = TAG_PKG_REF_DO + len + package name 86004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * PERM_AR_DO = TAG_PERM_AR_DO + len + detailed permission (8 bytes) 87004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * 88004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * Data objects hierarchy by TAG: 89004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * FF40 90004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * E2 91004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * E1 92004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * C1 93004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * CA 94004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * E3 95004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * DB 96004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu */ 974baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal // Values from the data standard. 984baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final String TAG_ALL_REF_AR_DO = "FF40"; 994baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final String TAG_REF_AR_DO = "E2"; 1004baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final String TAG_REF_DO = "E1"; 1014baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final String TAG_DEVICE_APP_ID_REF_DO = "C1"; 1024baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final String TAG_PKG_REF_DO = "CA"; 103004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu private static final String TAG_AR_DO = "E3"; 104004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu private static final String TAG_PERM_AR_DO = "DB"; 1054baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1064baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final int EVENT_OPEN_LOGICAL_CHANNEL_DONE = 1; 1074baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final int EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE = 2; 1084baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final int EVENT_CLOSE_LOGICAL_CHANNEL_DONE = 3; 1094baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1104baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal // State of the object. 1114baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final int STATE_LOADING = 0; 1124baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final int STATE_LOADED = 1; 1134baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final int STATE_ERROR = 2; 1144baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1154baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal // Describes a single rule. 1164baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static class AccessRule { 1174baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal public byte[] certificateHash; 1184baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal public String packageName; 1194baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal public long accessType; // This bit is not currently used, but reserved for future use. 1204baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1214baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal AccessRule(byte[] certificateHash, String packageName, long accessType) { 1224baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal this.certificateHash = certificateHash; 1234baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal this.packageName = packageName; 1244baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal this.accessType = accessType; 1254baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1264baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1274baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal boolean matches(byte[] certHash, String packageName) { 1284baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return certHash != null && Arrays.equals(this.certificateHash, certHash) && 1294baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal (this.packageName == null || this.packageName.equals(packageName)); 1304baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1314baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1324baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal @Override 1334baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal public String toString() { 1344baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return "cert: " + certificateHash + " pkg: " + packageName + 1354baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal " access: " + accessType; 1364baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1374baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1384baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1394baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal // Used for parsing the data from the UICC. 1404baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static class TLV { 1414baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private String tag; 1424baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private Integer length; 1434baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private String value; 1444baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1454baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal public TLV(String tag) { 1464baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal this.tag = tag; 1474baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1484baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1494baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal public String parse(String data, boolean shouldConsumeAll) { 150004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu Rlog.d(LOG_TAG, "Parse TLV: " + tag); 1514baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal if (!data.startsWith(tag)) { 1524baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal throw new IllegalArgumentException("Tags don't match."); 1534baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1544baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal int index = tag.length(); 1554baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal if (index + 2 > data.length()) { 1564baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal throw new IllegalArgumentException("No length."); 1574baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1584baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal length = new Integer(2 * Integer.parseInt( 1594baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal data.substring(index, index + 2), 16)); 1604baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal index += 2; 1614baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1624baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal int remainingLength = data.length() - (index + length); 1634baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal if (remainingLength < 0) { 1644baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal throw new IllegalArgumentException("Not enough data."); 1654baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1664baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal if (shouldConsumeAll && (remainingLength != 0)) { 1674baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal throw new IllegalArgumentException("Did not consume all."); 1684baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1694baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal value = data.substring(index, index + length); 1704baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 171004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu Rlog.d(LOG_TAG, "Got TLV: " + tag + "," + length + "," + value); 1724baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1734baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return data.substring(index + length); 1744baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1754baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1764baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1774baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private UiccCard mUiccCard; // Parent 1784baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private AtomicInteger mState; 1794baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private List<AccessRule> mAccessRules; 1804baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1814baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal public UiccCarrierPrivilegeRules(UiccCard uiccCard) { 1824baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.d(LOG_TAG, "Creating UiccCarrierPrivilegeRules"); 1834baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal mUiccCard = uiccCard; 1844baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal mState = new AtomicInteger(STATE_LOADING); 1854baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1864baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal // Start loading the rules. 1874baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal mUiccCard.iccOpenLogicalChannel(AID, 1884baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal obtainMessage(EVENT_OPEN_LOGICAL_CHANNEL_DONE, null)); 1894baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1904baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1914baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal /** 192c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * Returns the status of the carrier privileges for the input certificate and package name. 1934baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * 1944baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * @param signature The signature of the certificate. 1954baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * @param packageName name of the package. 1964baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * @return Access status. 1974baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal */ 198c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal public int getCarrierPrivilegeStatus(Signature signature, String packageName) { 1994baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.d(LOG_TAG, "hasCarrierPrivileges: " + signature + " : " + packageName); 2004baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal int state = mState.get(); 2014baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal if (state == STATE_LOADING) { 2024baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.d(LOG_TAG, "Rules not loaded."); 2034baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 2044baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } else if (state == STATE_ERROR) { 2054baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.d(LOG_TAG, "Error loading rules."); 2064baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES; 2074baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 2084baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 2094baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal byte[] certHash = getCertHash(signature); 2104baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal if (certHash == null) { 2114baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 2124baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 2134baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.e(LOG_TAG, "Checking: " + IccUtils.bytesToHexString(certHash) + " : " + packageName); 2144baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 2154baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal for (AccessRule ar : mAccessRules) { 2164baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal if (ar.matches(certHash, packageName)) { 217004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu Rlog.d(LOG_TAG, "Match found!"); 2184baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS; 2194baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 2204baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 2214baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 2224baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.d(LOG_TAG, "No matching rule found. Returning false."); 2234baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 2244baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 2254baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 226c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal /** 227c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * Returns the status of the carrier privileges for the input package name. 228c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * 229c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * @param packageManager PackageManager for getting signatures. 230c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * @param packageName name of the package. 231c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * @return Access status. 232c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal */ 233c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal public int getCarrierPrivilegeStatus(PackageManager packageManager, String packageName) { 234c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal try { 235c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal PackageInfo pInfo = packageManager.getPackageInfo(packageName, 236c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal PackageManager.GET_SIGNATURES); 237c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal Signature[] signatures = pInfo.signatures; 238c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal for (Signature sig : signatures) { 239c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal int accessStatus = getCarrierPrivilegeStatus(sig, pInfo.packageName); 240c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal if (accessStatus != TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS) { 241c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal return accessStatus; 242c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 243c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 244c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } catch (PackageManager.NameNotFoundException ex) { 245c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal Rlog.e(LOG_TAG, "NameNotFoundException", ex); 246c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 247c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 248c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 249c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal 250c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal /** 251c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * Returns the status of the carrier privileges for the caller of the current transaction. 252c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * 253c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * @param packageManager PackageManager for getting signatures and package names. 254c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * @return Access status. 255c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal */ 256c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal public int getCarrierPrivilegeStatusForCurrentTransaction(PackageManager packageManager) { 257c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal String[] packages = packageManager.getPackagesForUid(Binder.getCallingUid()); 258c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal 259c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal for (String pkg : packages) { 260c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal int accessStatus = getCarrierPrivilegeStatus(packageManager, pkg); 261c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal if (accessStatus != TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS) { 262c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal return accessStatus; 263c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 264c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 265c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 266c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 267c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal 268c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal /** 2697f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal * Returns the package name of the carrier app that should handle the input intent. 270c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * 271c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * @param packageManager PackageManager for getting receivers. 272c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * @param intent Intent that will be broadcast. 2737f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal * @return list of carrier app package names that can handle the intent. 2747f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal * Returns null if there is an error and an empty list if there 2757f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal * are no matching packages. 276c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal */ 2777f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal public List<String> getCarrierPackageNamesForBroadcastIntent( 278c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal PackageManager packageManager, Intent intent) { 2797f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal List<String> packages = new ArrayList<String>(); 280c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal List<ResolveInfo> receivers = packageManager.queryBroadcastReceivers(intent, 0); 281c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal for (ResolveInfo resolveInfo : receivers) { 282c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal if (resolveInfo.activityInfo == null) { 283c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal continue; 284c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 285c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal String packageName = resolveInfo.activityInfo.packageName; 2867f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal int status = getCarrierPrivilegeStatus(packageManager, packageName); 2877f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal if (status == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 2887f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal packages.add(packageName); 2897f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal } else if (status != TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS) { 2907f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal // Any status apart from HAS_ACCESS and NO_ACCESS is considered an error. 2917f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal return null; 292c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 293c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 294c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal 2957f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal return packages; 296c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 297c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal 2984baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal @Override 2994baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal public void handleMessage(Message msg) { 3004baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal AsyncResult ar; 3014baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 3024baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal switch (msg.what) { 3034baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 3044baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal case EVENT_OPEN_LOGICAL_CHANNEL_DONE: 3054baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.d(LOG_TAG, "EVENT_OPEN_LOGICAL_CHANNEL_DONE"); 3064baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal ar = (AsyncResult) msg.obj; 3074baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal if (ar.exception == null && ar.result != null) { 3084baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal int channelId = ((int[]) ar.result)[0]; 3094baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal mUiccCard.iccTransmitApduLogicalChannel(channelId, CLA, COMMAND, P1, P2, P3, DATA, 3104baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal obtainMessage(EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE, new Integer(channelId))); 3114baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } else { 3124baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.e(LOG_TAG, "Error opening channel"); 3134baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal mState.set(STATE_ERROR); 3144baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 3154baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal break; 3164baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 3174baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal case EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE: 3184baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.d(LOG_TAG, "EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE"); 3194baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal ar = (AsyncResult) msg.obj; 3204baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal if (ar.exception == null && ar.result != null) { 3214baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal IccIoResult response = (IccIoResult) ar.result; 3224baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal if (response.payload != null && response.sw1 == 0x90 && response.sw2 == 0x00) { 3234baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal try { 3244baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal mAccessRules = parseRules(IccUtils.bytesToHexString(response.payload)); 3254baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal mState.set(STATE_LOADED); 3264baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } catch (IllegalArgumentException ex) { 3274baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.e(LOG_TAG, "Error parsing rules: " + ex); 3284baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal mState.set(STATE_ERROR); 3294baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 3304baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } else { 3314baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.e(LOG_TAG, "Invalid response: payload=" + response.payload + 3324baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal " sw1=" + response.sw1 + " sw2=" + response.sw2); 3334baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 3344baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } else { 3354baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.e(LOG_TAG, "Error reading value from SIM."); 3364baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal mState.set(STATE_ERROR); 3374baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 3384baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 3394baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal int channelId = (Integer) ar.userObj; 3404baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal mUiccCard.iccCloseLogicalChannel(channelId, obtainMessage( 3414baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal EVENT_CLOSE_LOGICAL_CHANNEL_DONE)); 3424baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal break; 3434baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 3444baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal case EVENT_CLOSE_LOGICAL_CHANNEL_DONE: 3454baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.d(LOG_TAG, "EVENT_CLOSE_LOGICAL_CHANNEL_DONE"); 3464baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal break; 3474baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 3484baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal default: 3494baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.e(LOG_TAG, "Unknown event " + msg.what); 3504baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 3514baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 3524baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 3534baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal /* 3544baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * Parses the rules from the input string. 3554baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal */ 3564baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static List<AccessRule> parseRules(String rules) { 3574baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal rules = rules.toUpperCase(Locale.US); 3584baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.d(LOG_TAG, "Got rules: " + rules); 3594baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 360004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu TLV allRefArDo = new TLV(TAG_ALL_REF_AR_DO); //FF40 3614baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal allRefArDo.parse(rules, true); 3624baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 3634baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal String arDos = allRefArDo.value; 3644baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal List<AccessRule> accessRules = new ArrayList<AccessRule>(); 3654baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal while (!arDos.isEmpty()) { 366004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu TLV refArDo = new TLV(TAG_REF_AR_DO); //E2 3674baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal arDos = refArDo.parse(arDos, false); 36832bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu AccessRule accessRule = parseRefArdo(refArDo.value); 36932bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu if (accessRule != null) { 37032bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu accessRules.add(accessRule); 37132bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu } else { 37232bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu Rlog.e(LOG_TAG, "Skip unrecognized rule." + refArDo.value); 37332bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu } 3744baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 3754baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return accessRules; 3764baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 3774baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 3784baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal /* 3794baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * Parses a single rule. 3804baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal */ 3814baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static AccessRule parseRefArdo(String rule) { 3824baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.d(LOG_TAG, "Got rule: " + rule); 3834baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 3844baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal String certificateHash = null; 3854baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal String packageName = null; 386004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu String tmp = null; 3874baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal long accessType = 0; 3884baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 3894baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal while (!rule.isEmpty()) { 3904baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal if (rule.startsWith(TAG_REF_DO)) { 391004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu TLV refDo = new TLV(TAG_REF_DO); //E1 3924baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal rule = refDo.parse(rule, false); 3934baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 39432bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu // Skip unrelated rules. 39532bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu if (!refDo.value.startsWith(TAG_DEVICE_APP_ID_REF_DO)) { 39632bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu return null; 39732bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu } 39832bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu 399004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu TLV deviceDo = new TLV(TAG_DEVICE_APP_ID_REF_DO); //C1 400004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu tmp = deviceDo.parse(refDo.value, false); 401004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu certificateHash = deviceDo.value; 402004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu 403004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu if (!tmp.isEmpty()) { 40432bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu if (!tmp.startsWith(TAG_PKG_REF_DO)) { 40532bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu return null; 40632bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu } 407004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu TLV pkgDo = new TLV(TAG_PKG_REF_DO); //CA 408004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu pkgDo.parse(tmp, true); 409004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu packageName = new String(IccUtils.hexStringToBytes(pkgDo.value)); 4104baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } else { 411004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu packageName = null; 4124baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 4134baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } else if (rule.startsWith(TAG_AR_DO)) { 414004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu TLV arDo = new TLV(TAG_AR_DO); //E3 4154baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal rule = arDo.parse(rule, false); 4164baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 41732bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu // Skip unrelated rules. 41832bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu if (!arDo.value.startsWith(TAG_PERM_AR_DO)) { 41932bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu return null; 42032bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu } 42132bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu 422004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu TLV permDo = new TLV(TAG_PERM_AR_DO); //DB 4234baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal permDo.parse(arDo.value, true); 4244baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.e(LOG_TAG, permDo.value); 4254baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } else { 42632bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu // Spec requires it must be either TAG_REF_DO or TAG_AR_DO. 4274baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal throw new RuntimeException("Invalid Rule type"); 4284baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 4294baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 4304baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 4314baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.e(LOG_TAG, "Adding: " + certificateHash + " : " + packageName + " : " + accessType); 4324baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 4334baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal AccessRule accessRule = new AccessRule(IccUtils.hexStringToBytes(certificateHash), 4344baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal packageName, accessType); 4354baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.e(LOG_TAG, "Parsed rule: " + accessRule); 4364baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return accessRule; 4374baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 4384baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 4394baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal /* 4404baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * Converts a Signature into a Certificate hash usable for comparison. 4414baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal */ 4424baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static byte[] getCertHash(Signature signature) { 4434baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal // TODO: Is the following sufficient. 4444baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal try { 4454baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); 4464baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal X509Certificate cert = (X509Certificate) certFactory.generateCertificate( 4474baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal new ByteArrayInputStream(signature.toByteArray())); 4484baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 4494baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal MessageDigest md = MessageDigest.getInstance("SHA"); 4504baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return md.digest(cert.getEncoded()); 4514baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } catch (CertificateException ex) { 4524baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.e(LOG_TAG, "CertificateException: " + ex); 4534baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } catch (NoSuchAlgorithmException ex) { 4544baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.e(LOG_TAG, "NoSuchAlgorithmException: " + ex); 4554baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 4564baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 4574baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal Rlog.e(LOG_TAG, "Cannot compute cert hash"); 4584baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return null; 4594baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 4604baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal} 461