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 19ed0cfa93b9e42486bfc7caeca83ceae1a2f7328eAbhijith Shastryimport android.annotation.Nullable; 20c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawalimport android.content.Intent; 21c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawalimport android.content.pm.PackageInfo; 22c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawalimport android.content.pm.PackageManager; 23c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawalimport android.content.pm.ResolveInfo; 244baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport android.content.pm.Signature; 254baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport android.os.AsyncResult; 26c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawalimport android.os.Binder; 274baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport android.os.Handler; 284baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport android.os.Message; 294baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport android.telephony.Rlog; 304baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport android.telephony.TelephonyManager; 31277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidsonimport android.telephony.UiccAccessRule; 3288151624f06b1a3c7d75d68e2a87cd6c04aab996Junda Liuimport android.text.TextUtils; 334baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 34b757d07125d8294062586b5258e4e79d0b8417a3Junda Liuimport com.android.internal.telephony.CommandException; 354baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 3638aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawalimport java.io.FileDescriptor; 3738aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawalimport java.io.PrintWriter; 384baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport java.util.ArrayList; 399566fe7f15b78503b9e7ce51e27464b523838e28goneilimport java.util.Collections; 404baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport java.util.List; 414baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalimport java.util.Locale; 427f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawalimport java.util.concurrent.atomic.AtomicInteger; 434baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 444baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal/** 454baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * Class that reads and stores the carrier privileged rules from the UICC. 464baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * 474baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * The rules are read when the class is created, hence it should only be created 484baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * after the UICC can be read. And it should be deleted when a UICC is changed. 494baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * 50a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * Document: https://source.android.com/devices/tech/config/uicc.html 514baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * 524baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * {@hide} 534baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal */ 544baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawalpublic class UiccCarrierPrivilegeRules extends Handler { 554baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final String LOG_TAG = "UiccCarrierPrivilegeRules"; 56c3ac6ac3d62e0e1637ff8fddf945953dca60eebaJunda Liu private static final boolean DBG = false; 574baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 58dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie private static final String ARAM_AID = "A00000015141434C00"; 59dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie private static final String ARAD_AID = "A00000015144414300"; 60dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie private static final int ARAM = 1; 61dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie private static final int ARAD = 0; 624baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final int CLA = 0x80; 637b122b5ef07eca751ca8b6938562737d6e3de2c8Shishir Agrawal private static final int COMMAND = 0xCA; 647b122b5ef07eca751ca8b6938562737d6e3de2c8Shishir Agrawal private static final int P1 = 0xFF; 657b122b5ef07eca751ca8b6938562737d6e3de2c8Shishir Agrawal private static final int P2 = 0x40; 667541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu private static final int P2_EXTENDED_DATA = 0x60; 674baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final int P3 = 0x00; 684baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final String DATA = ""; 694baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 70004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu /* 71004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * Rules format: 72004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * ALL_REF_AR_DO = TAG_ALL_REF_AR_DO + len + [REF_AR_DO]*n 73004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * REF_AR_DO = TAG_REF_AR_DO + len + REF-DO + AR-DO 74004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * 75004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * REF_DO = TAG_REF_DO + len + DEVICE_APP_ID_REF_DO + (optional) PKG_REF_DO 76004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * AR_DO = TAG_AR_DO + len + PERM_AR_DO 77004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * 78c05061bdcff84d8211d51a5080c57f442e4edf74Junda Liu * DEVICE_APP_ID_REF_DO = TAG_DEVICE_APP_ID_REF_DO + len + sha256 hexstring of cert 79004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * PKG_REF_DO = TAG_PKG_REF_DO + len + package name 80004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * PERM_AR_DO = TAG_PERM_AR_DO + len + detailed permission (8 bytes) 81004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * 82004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * Data objects hierarchy by TAG: 83004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * FF40 84004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * E2 85004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * E1 86004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * C1 87004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * CA 88004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * E3 89004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu * DB 90004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu */ 914baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal // Values from the data standard. 924baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final String TAG_ALL_REF_AR_DO = "FF40"; 934baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final String TAG_REF_AR_DO = "E2"; 944baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final String TAG_REF_DO = "E1"; 954baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final String TAG_DEVICE_APP_ID_REF_DO = "C1"; 964baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final String TAG_PKG_REF_DO = "CA"; 97004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu private static final String TAG_AR_DO = "E3"; 98004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu private static final String TAG_PERM_AR_DO = "DB"; 99fb41d485d74fba0504e24dd13474d4acdd75a5efCassie private static final String TAG_AID_REF_DO = "4F"; 100fb41d485d74fba0504e24dd13474d4acdd75a5efCassie private static final String CARRIER_PRIVILEGE_AID = "FFFFFFFFFFFF"; 1014baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1024baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final int EVENT_OPEN_LOGICAL_CHANNEL_DONE = 1; 1034baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final int EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE = 2; 1044baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final int EVENT_CLOSE_LOGICAL_CHANNEL_DONE = 3; 105a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static final int EVENT_PKCS15_READ_DONE = 4; 1064baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1074baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal // State of the object. 1084baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final int STATE_LOADING = 0; 1094baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final int STATE_LOADED = 1; 1104baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private static final int STATE_ERROR = 2; 1114baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 112b757d07125d8294062586b5258e4e79d0b8417a3Junda Liu // Max number of retries for open logical channel, interval is 10s. 11391e0d7fae8ab78b99ba25aa307ec1a558b5769fcJunda Liu private static final int MAX_RETRY = 1; 114b757d07125d8294062586b5258e4e79d0b8417a3Junda Liu private static final int RETRY_INTERVAL_MS = 10000; 115b757d07125d8294062586b5258e4e79d0b8417a3Junda Liu 1164baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal // Used for parsing the data from the UICC. 117a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu public static class TLV { 1187541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu private static final int SINGLE_BYTE_MAX_LENGTH = 0x80; 1194baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private String tag; 1207541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu // Length encoding is in GPC_Specification_2.2.1: 11.1.5 APDU Message and Data Length. 1217541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu // Length field could be either 1 byte if length < 128, or multiple bytes with first byte 1227541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu // specifying how many bytes are used for length, followed by length bytes. 1237541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu // Bytes for the length field, in ASCII HEX string form. 1247541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu private String lengthBytes; 1257541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu // Decoded length as integer. 1264baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private Integer length; 1274baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private String value; 1284baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1294baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal public TLV(String tag) { 1304baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal this.tag = tag; 1314baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1324baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 133a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu public String getValue() { 134a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (value == null) return ""; 135a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu return value; 136a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 137a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 1387541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu public String parseLength(String data) { 1397541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu int offset = tag.length(); 1407541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu int firstByte = Integer.parseInt(data.substring(offset, offset + 2), 16); 14164e02b05d7334a9d5704ee2b9f4710a310d9937eIan Pedowitz if (firstByte < SINGLE_BYTE_MAX_LENGTH) { 1427541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu length = firstByte * 2; 1437541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu lengthBytes = data.substring(offset, offset + 2); 1447541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu } else { 1457541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu int numBytes = firstByte - SINGLE_BYTE_MAX_LENGTH; 1467541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu length = Integer.parseInt(data.substring(offset + 2, offset + 2 + numBytes * 2), 16) * 2; 1477541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu lengthBytes = data.substring(offset, offset + 2 + numBytes * 2); 1487541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu } 149c3ac6ac3d62e0e1637ff8fddf945953dca60eebaJunda Liu log("TLV parseLength length=" + length + "lenghtBytes: " + lengthBytes); 1507541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu return lengthBytes; 1517541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu } 1527541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu 1534baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal public String parse(String data, boolean shouldConsumeAll) { 154c3ac6ac3d62e0e1637ff8fddf945953dca60eebaJunda Liu log("Parse TLV: " + tag); 1554baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal if (!data.startsWith(tag)) { 1564baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal throw new IllegalArgumentException("Tags don't match."); 1574baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1584baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal int index = tag.length(); 1594baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal if (index + 2 > data.length()) { 1604baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal throw new IllegalArgumentException("No length."); 1614baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1624baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1637541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu parseLength(data); 1647541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu index += lengthBytes.length(); 1657541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu 166c3ac6ac3d62e0e1637ff8fddf945953dca60eebaJunda Liu log("index="+index+" length="+length+"data.length="+data.length()); 1674baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal int remainingLength = data.length() - (index + length); 1684baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal if (remainingLength < 0) { 1694baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal throw new IllegalArgumentException("Not enough data."); 1704baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1714baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal if (shouldConsumeAll && (remainingLength != 0)) { 1724baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal throw new IllegalArgumentException("Did not consume all."); 1734baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1744baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal value = data.substring(index, index + length); 1754baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 176c3ac6ac3d62e0e1637ff8fddf945953dca60eebaJunda Liu log("Got TLV: " + tag + "," + length + "," + value); 1774baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1784baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return data.substring(index + length); 1794baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1804baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 1814baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 1825b07a62f59800c985a89045fbdb7b91f80b6fb18Amit Mahajan private UiccProfile mUiccProfile; // Parent 183a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private UiccPkcs15 mUiccPkcs15; // ARF fallback 1844baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal private AtomicInteger mState; 185277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson private List<UiccAccessRule> mAccessRules; 1867541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu private String mRules; 187c9877fe39ad8f3641d16fd980404916da7f6ce70Shishir Agrawal private Message mLoadedCallback; 18838aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal private String mStatusMessage; // Only used for debugging. 1897541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu private int mChannelId; // Channel Id for communicating with UICC. 190b757d07125d8294062586b5258e4e79d0b8417a3Junda Liu private int mRetryCount; // Number of retries for open logical channel. 191dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie private boolean mCheckedRules = false; // Flag that used to mark whether get rules from ARA-D. 192dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie private int mAIDInUse; // Message component to identify which AID is currently in-use. 193b757d07125d8294062586b5258e4e79d0b8417a3Junda Liu private final Runnable mRetryRunnable = new Runnable() { 194b757d07125d8294062586b5258e4e79d0b8417a3Junda Liu @Override 195b757d07125d8294062586b5258e4e79d0b8417a3Junda Liu public void run() { 196dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie openChannel(mAIDInUse); 197b757d07125d8294062586b5258e4e79d0b8417a3Junda Liu } 198b757d07125d8294062586b5258e4e79d0b8417a3Junda Liu }; 199b757d07125d8294062586b5258e4e79d0b8417a3Junda Liu 200dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie private void openChannel(int aidId) { 201b757d07125d8294062586b5258e4e79d0b8417a3Junda Liu // Send open logical channel request. 202dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie String aid = (aidId == ARAD) ? ARAD_AID : ARAM_AID; 20310d75a759b897da1077e3aa21ced4c46698c5552Ajay Nambi int p2 = 0x00; 2045b07a62f59800c985a89045fbdb7b91f80b6fb18Amit Mahajan mUiccProfile.iccOpenLogicalChannel(aid, p2, /* supported p2 value */ 205dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie obtainMessage(EVENT_OPEN_LOGICAL_CHANNEL_DONE, 0, aidId, null)); 206b757d07125d8294062586b5258e4e79d0b8417a3Junda Liu } 2074baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 2085b07a62f59800c985a89045fbdb7b91f80b6fb18Amit Mahajan public UiccCarrierPrivilegeRules(UiccProfile uiccProfile, Message loadedCallback) { 209c3ac6ac3d62e0e1637ff8fddf945953dca60eebaJunda Liu log("Creating UiccCarrierPrivilegeRules"); 2105b07a62f59800c985a89045fbdb7b91f80b6fb18Amit Mahajan mUiccProfile = uiccProfile; 2114baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal mState = new AtomicInteger(STATE_LOADING); 21238aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal mStatusMessage = "Not loaded."; 213c9877fe39ad8f3641d16fd980404916da7f6ce70Shishir Agrawal mLoadedCallback = loadedCallback; 2147541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu mRules = ""; 215277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson mAccessRules = new ArrayList<>(); 2164baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 217dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie // Open logical channel with ARA_D. 218dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie mAIDInUse = ARAD; 219dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie openChannel(mAIDInUse); 2204baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 2214baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 2224baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal /** 223c9877fe39ad8f3641d16fd980404916da7f6ce70Shishir Agrawal * Returns true if the carrier privilege rules have finished loading. 224c9877fe39ad8f3641d16fd980404916da7f6ce70Shishir Agrawal */ 225c9877fe39ad8f3641d16fd980404916da7f6ce70Shishir Agrawal public boolean areCarrierPriviligeRulesLoaded() { 226c9877fe39ad8f3641d16fd980404916da7f6ce70Shishir Agrawal return mState.get() != STATE_LOADING; 227c9877fe39ad8f3641d16fd980404916da7f6ce70Shishir Agrawal } 228c9877fe39ad8f3641d16fd980404916da7f6ce70Shishir Agrawal 229c9877fe39ad8f3641d16fd980404916da7f6ce70Shishir Agrawal /** 230aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani * Returns true if the carrier privilege rules have finished loading and some rules were 231aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani * specified. 232aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani */ 233aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani public boolean hasCarrierPrivilegeRules() { 234aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani return mState.get() != STATE_LOADING && mAccessRules != null && mAccessRules.size() > 0; 235aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani } 236aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani 237aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani /** 23888151624f06b1a3c7d75d68e2a87cd6c04aab996Junda Liu * Returns package names for privilege rules. 23988151624f06b1a3c7d75d68e2a87cd6c04aab996Junda Liu * Return empty list if no rules defined or package name is empty string. 24088151624f06b1a3c7d75d68e2a87cd6c04aab996Junda Liu */ 24188151624f06b1a3c7d75d68e2a87cd6c04aab996Junda Liu public List<String> getPackageNames() { 24288151624f06b1a3c7d75d68e2a87cd6c04aab996Junda Liu List<String> pkgNames = new ArrayList<String>(); 24388151624f06b1a3c7d75d68e2a87cd6c04aab996Junda Liu if (mAccessRules != null) { 244277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson for (UiccAccessRule ar : mAccessRules) { 245277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson if (!TextUtils.isEmpty(ar.getPackageName())) { 246277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson pkgNames.add(ar.getPackageName()); 24788151624f06b1a3c7d75d68e2a87cd6c04aab996Junda Liu } 24888151624f06b1a3c7d75d68e2a87cd6c04aab996Junda Liu } 24988151624f06b1a3c7d75d68e2a87cd6c04aab996Junda Liu } 25088151624f06b1a3c7d75d68e2a87cd6c04aab996Junda Liu return pkgNames; 25188151624f06b1a3c7d75d68e2a87cd6c04aab996Junda Liu } 25288151624f06b1a3c7d75d68e2a87cd6c04aab996Junda Liu 25388151624f06b1a3c7d75d68e2a87cd6c04aab996Junda Liu /** 2549566fe7f15b78503b9e7ce51e27464b523838e28goneil * Returns list of access rules. 2559566fe7f15b78503b9e7ce51e27464b523838e28goneil */ 2569566fe7f15b78503b9e7ce51e27464b523838e28goneil public List<UiccAccessRule> getAccessRules() { 2579566fe7f15b78503b9e7ce51e27464b523838e28goneil if (mAccessRules == null) { 2589566fe7f15b78503b9e7ce51e27464b523838e28goneil return Collections.emptyList(); 2599566fe7f15b78503b9e7ce51e27464b523838e28goneil } 2609566fe7f15b78503b9e7ce51e27464b523838e28goneil return Collections.unmodifiableList(mAccessRules); 2619566fe7f15b78503b9e7ce51e27464b523838e28goneil } 2629566fe7f15b78503b9e7ce51e27464b523838e28goneil 2639566fe7f15b78503b9e7ce51e27464b523838e28goneil /** 264c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * Returns the status of the carrier privileges for the input certificate and package name. 2654baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * 2664baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * @param signature The signature of the certificate. 2674baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * @param packageName name of the package. 2684baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * @return Access status. 2694baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal */ 270c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal public int getCarrierPrivilegeStatus(Signature signature, String packageName) { 2714baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal int state = mState.get(); 2724baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal if (state == STATE_LOADING) { 2734baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 2744baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } else if (state == STATE_ERROR) { 2754baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES; 2764baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 2774baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 278277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson for (UiccAccessRule ar : mAccessRules) { 279277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson int accessStatus = ar.getCarrierPrivilegeStatus(signature, packageName); 280277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson if (accessStatus != TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS) { 281277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson return accessStatus; 2824baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 2834baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 2844baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 2854baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 2864baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 2874baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 288c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal /** 289c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * Returns the status of the carrier privileges for the input package name. 290c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * 291c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * @param packageManager PackageManager for getting signatures. 292c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * @param packageName name of the package. 293c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * @return Access status. 294c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal */ 295c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal public int getCarrierPrivilegeStatus(PackageManager packageManager, String packageName) { 296c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal try { 297aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani // Short-circuit if there are no rules to check against, so we don't need to fetch 298aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani // the package info with signatures. 299aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani if (!hasCarrierPrivilegeRules()) { 300aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani int state = mState.get(); 301aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani if (state == STATE_LOADING) { 302aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 303aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani } else if (state == STATE_ERROR) { 304aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani return TelephonyManager.CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES; 305aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani } 306aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 307aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani } 308cd30338d719dcd77db99766bf21438e494564174Jeff Davidson // Include DISABLED_UNTIL_USED components. This facilitates cases where a carrier app 309cd30338d719dcd77db99766bf21438e494564174Jeff Davidson // is disabled by default, and some other component wants to enable it when it has 310cd30338d719dcd77db99766bf21438e494564174Jeff Davidson // gained carrier privileges (as an indication that a matching SIM has been inserted). 311c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal PackageInfo pInfo = packageManager.getPackageInfo(packageName, 312277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson PackageManager.GET_SIGNATURES 313daed5e29637607defb16881eb4bfc17d1d875137Sanry Huang | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS); 314aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani return getCarrierPrivilegeStatus(pInfo); 315c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } catch (PackageManager.NameNotFoundException ex) { 316b2a8b88ff6ee032bea26eb69cca72e432a7918f9Jeff Davidson log("Package " + packageName + " not found for carrier privilege status check"); 317c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 318c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 319c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 320c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal 321c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal /** 322aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani * Returns the status of the carrier privileges for the input package info. 323aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani * 324aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani * @param packageInfo PackageInfo for the package, containing the package signatures. 325aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani * @return Access status. 326aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani */ 327aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani public int getCarrierPrivilegeStatus(PackageInfo packageInfo) { 328277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson int state = mState.get(); 329277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson if (state == STATE_LOADING) { 330277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 331277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } else if (state == STATE_ERROR) { 332277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson return TelephonyManager.CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES; 333277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson } 334277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson 335277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson for (UiccAccessRule ar : mAccessRules) { 336277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson int accessStatus = ar.getCarrierPrivilegeStatus(packageInfo); 337aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani if (accessStatus != TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS) { 338aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani return accessStatus; 339aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani } 340aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani } 341aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 342aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani } 343aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani 344aeb6df6edf6902d1919bb712fd62bc10f1c623ccAmith Yamasani /** 345c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * Returns the status of the carrier privileges for the caller of the current transaction. 346c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * 347c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * @param packageManager PackageManager for getting signatures and package names. 348c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * @return Access status. 349c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal */ 350c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal public int getCarrierPrivilegeStatusForCurrentTransaction(PackageManager packageManager) { 351828a763161a8e9312052de1864f2f1954dd468c5Jeff Davidson return getCarrierPrivilegeStatusForUid(packageManager, Binder.getCallingUid()); 352828a763161a8e9312052de1864f2f1954dd468c5Jeff Davidson } 353828a763161a8e9312052de1864f2f1954dd468c5Jeff Davidson 354828a763161a8e9312052de1864f2f1954dd468c5Jeff Davidson /** 355828a763161a8e9312052de1864f2f1954dd468c5Jeff Davidson * Returns the status of the carrier privileges for the caller of the current transaction. 356828a763161a8e9312052de1864f2f1954dd468c5Jeff Davidson * 357828a763161a8e9312052de1864f2f1954dd468c5Jeff Davidson * @param packageManager PackageManager for getting signatures and package names. 358828a763161a8e9312052de1864f2f1954dd468c5Jeff Davidson * @return Access status. 359828a763161a8e9312052de1864f2f1954dd468c5Jeff Davidson */ 360828a763161a8e9312052de1864f2f1954dd468c5Jeff Davidson public int getCarrierPrivilegeStatusForUid( 361828a763161a8e9312052de1864f2f1954dd468c5Jeff Davidson PackageManager packageManager, int uid) { 362828a763161a8e9312052de1864f2f1954dd468c5Jeff Davidson String[] packages = packageManager.getPackagesForUid(uid); 363c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal 364c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal for (String pkg : packages) { 365c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal int accessStatus = getCarrierPrivilegeStatus(packageManager, pkg); 366c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal if (accessStatus != TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS) { 367c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal return accessStatus; 368c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 369c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 370c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 371c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 372c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal 373c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal /** 3747f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal * Returns the package name of the carrier app that should handle the input intent. 375c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * 376c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal * @param packageManager PackageManager for getting receivers. 377934a24a6aa2b7a981e872fa350648904ed80280aDiego Pontoriero * @param intent Intent that will be sent. 3787f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal * @return list of carrier app package names that can handle the intent. 3797f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal * Returns null if there is an error and an empty list if there 3807f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal * are no matching packages. 381c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal */ 382934a24a6aa2b7a981e872fa350648904ed80280aDiego Pontoriero public List<String> getCarrierPackageNamesForIntent( 383c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal PackageManager packageManager, Intent intent) { 3847f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal List<String> packages = new ArrayList<String>(); 385934a24a6aa2b7a981e872fa350648904ed80280aDiego Pontoriero List<ResolveInfo> receivers = new ArrayList<ResolveInfo>(); 386934a24a6aa2b7a981e872fa350648904ed80280aDiego Pontoriero receivers.addAll(packageManager.queryBroadcastReceivers(intent, 0)); 387934a24a6aa2b7a981e872fa350648904ed80280aDiego Pontoriero receivers.addAll(packageManager.queryIntentContentProviders(intent, 0)); 388934a24a6aa2b7a981e872fa350648904ed80280aDiego Pontoriero receivers.addAll(packageManager.queryIntentActivities(intent, 0)); 389934a24a6aa2b7a981e872fa350648904ed80280aDiego Pontoriero receivers.addAll(packageManager.queryIntentServices(intent, 0)); 390934a24a6aa2b7a981e872fa350648904ed80280aDiego Pontoriero 391c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal for (ResolveInfo resolveInfo : receivers) { 392ed0cfa93b9e42486bfc7caeca83ceae1a2f7328eAbhijith Shastry String packageName = getPackageName(resolveInfo); 393ed0cfa93b9e42486bfc7caeca83ceae1a2f7328eAbhijith Shastry if (packageName == null) { 394c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal continue; 395c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 396ed0cfa93b9e42486bfc7caeca83ceae1a2f7328eAbhijith Shastry 3977f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal int status = getCarrierPrivilegeStatus(packageManager, packageName); 3987f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal if (status == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 3997f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal packages.add(packageName); 4007f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal } else if (status != TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS) { 4017f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal // Any status apart from HAS_ACCESS and NO_ACCESS is considered an error. 4027f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal return null; 403c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 404c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 405c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal 4067f1a3f0ab65c144fde56e1246c5747b0c555034aShishir Agrawal return packages; 407c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 408c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal 409ed0cfa93b9e42486bfc7caeca83ceae1a2f7328eAbhijith Shastry @Nullable 410ed0cfa93b9e42486bfc7caeca83ceae1a2f7328eAbhijith Shastry private String getPackageName(ResolveInfo resolveInfo) { 411ed0cfa93b9e42486bfc7caeca83ceae1a2f7328eAbhijith Shastry if (resolveInfo.activityInfo != null) { 412ed0cfa93b9e42486bfc7caeca83ceae1a2f7328eAbhijith Shastry return resolveInfo.activityInfo.packageName; 413ed0cfa93b9e42486bfc7caeca83ceae1a2f7328eAbhijith Shastry } else if (resolveInfo.serviceInfo != null) { 414ed0cfa93b9e42486bfc7caeca83ceae1a2f7328eAbhijith Shastry return resolveInfo.serviceInfo.packageName; 415ed0cfa93b9e42486bfc7caeca83ceae1a2f7328eAbhijith Shastry } else if (resolveInfo.providerInfo != null) { 416ed0cfa93b9e42486bfc7caeca83ceae1a2f7328eAbhijith Shastry return resolveInfo.providerInfo.packageName; 417ed0cfa93b9e42486bfc7caeca83ceae1a2f7328eAbhijith Shastry } 418ed0cfa93b9e42486bfc7caeca83ceae1a2f7328eAbhijith Shastry return null; 419ed0cfa93b9e42486bfc7caeca83ceae1a2f7328eAbhijith Shastry } 420ed0cfa93b9e42486bfc7caeca83ceae1a2f7328eAbhijith Shastry 4214baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal @Override 4224baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal public void handleMessage(Message msg) { 4234baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal AsyncResult ar; 424dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie mAIDInUse = msg.arg2; // 0 means ARA-D and 1 means ARA-M. 4254baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 4264baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal switch (msg.what) { 4274baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 4287444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson case EVENT_OPEN_LOGICAL_CHANNEL_DONE: 4297444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson log("EVENT_OPEN_LOGICAL_CHANNEL_DONE"); 4307444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson ar = (AsyncResult) msg.obj; 4317444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson if (ar.exception == null && ar.result != null) { 4327444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson mChannelId = ((int[]) ar.result)[0]; 4335b07a62f59800c985a89045fbdb7b91f80b6fb18Amit Mahajan mUiccProfile.iccTransmitApduLogicalChannel(mChannelId, CLA, COMMAND, P1, P2, P3, 434dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie DATA, obtainMessage(EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE, mChannelId, 435dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie mAIDInUse)); 4367444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson } else { 4377444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson // MISSING_RESOURCE could be due to logical channels temporarily unavailable, 4387444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson // so we retry up to MAX_RETRY times, with an interval of RETRY_INTERVAL_MS. 4397444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson if (ar.exception instanceof CommandException && mRetryCount < MAX_RETRY 4407444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson && ((CommandException) (ar.exception)).getCommandError() 441dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie == CommandException.Error.MISSING_RESOURCE) { 4427444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson mRetryCount++; 4437444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson removeCallbacks(mRetryRunnable); 4447444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson postDelayed(mRetryRunnable, RETRY_INTERVAL_MS); 4457444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson } else { 446dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie if (mAIDInUse == ARAD) { 447dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie // Open logical channel with ARA_M. 448dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie mRules = ""; 449dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie openChannel(1); 450dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie } 451dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie if (mAIDInUse == ARAM) { 452dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie if (mCheckedRules) { 453dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie updateState(STATE_LOADED, "Success!"); 454dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie } else { 455dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie // if rules cannot be read from both ARA_D and ARA_M applet, 456dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie // fallback to PKCS15-based ARF. 457dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie log("No ARA, try ARF next."); 4585b07a62f59800c985a89045fbdb7b91f80b6fb18Amit Mahajan mUiccPkcs15 = new UiccPkcs15(mUiccProfile, 459dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie obtainMessage(EVENT_PKCS15_READ_DONE)); 460dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie } 461dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie } 4627444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson } 4637444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson } 4647444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson break; 4657444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson 4667444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson case EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE: 4677444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson log("EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE"); 4687444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson ar = (AsyncResult) msg.obj; 4697444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson if (ar.exception == null && ar.result != null) { 4707444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson IccIoResult response = (IccIoResult) ar.result; 4717444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson if (response.sw1 == 0x90 && response.sw2 == 0x00 4727444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson && response.payload != null && response.payload.length > 0) { 4737444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson try { 4747444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson mRules += IccUtils.bytesToHexString(response.payload) 4757444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson .toUpperCase(Locale.US); 4767444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson if (isDataComplete()) { 477dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie mAccessRules.addAll(parseRules(mRules)); 478dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie if (mAIDInUse == ARAD) { 479dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie mCheckedRules = true; 480dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie } else { 481dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie updateState(STATE_LOADED, "Success!"); 482dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie } 4837444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson } else { 4845b07a62f59800c985a89045fbdb7b91f80b6fb18Amit Mahajan mUiccProfile.iccTransmitApduLogicalChannel(mChannelId, CLA, COMMAND, 4857444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson P1, P2_EXTENDED_DATA, P3, DATA, 4867444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson obtainMessage(EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE, 487dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie mChannelId, mAIDInUse)); 4887444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson break; 4897444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson } 4907444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson } catch (IllegalArgumentException | IndexOutOfBoundsException ex) { 491dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie if (mAIDInUse == ARAM) { 492dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie updateState(STATE_ERROR, "Error parsing rules: " + ex); 493dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie } 4947444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson } 4957444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson } else { 496dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie if (mAIDInUse == ARAM) { 497dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie String errorMsg = "Invalid response: payload=" + response.payload 498dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie + " sw1=" + response.sw1 + " sw2=" + response.sw2; 499dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie updateState(STATE_ERROR, errorMsg); 500dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie } 5017444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson } 5027444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson } else { 503dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie if (mAIDInUse == ARAM) { 504dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie updateState(STATE_ERROR, "Error reading value from SIM."); 505dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie } 5067444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson } 5077444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson 5085b07a62f59800c985a89045fbdb7b91f80b6fb18Amit Mahajan mUiccProfile.iccCloseLogicalChannel(mChannelId, obtainMessage( 509dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie EVENT_CLOSE_LOGICAL_CHANNEL_DONE, 0, mAIDInUse)); 5107444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson mChannelId = -1; 5117444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson break; 5127444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson 5137444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson case EVENT_CLOSE_LOGICAL_CHANNEL_DONE: 5147444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson log("EVENT_CLOSE_LOGICAL_CHANNEL_DONE"); 515dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie if (mAIDInUse == ARAD) { 516dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie // Close logical channel with ARA_D and then open logical channel with ARA_M. 517dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie mRules = ""; 518dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie openChannel(1); 519dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie } 5207444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson break; 5217444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson 5227444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson case EVENT_PKCS15_READ_DONE: 5237444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson log("EVENT_PKCS15_READ_DONE"); 5247444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson if (mUiccPkcs15 == null || mUiccPkcs15.getRules() == null) { 5257444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson updateState(STATE_ERROR, "No ARA or ARF."); 5267444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson } else { 5277444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson for (String cert : mUiccPkcs15.getRules()) { 528277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson UiccAccessRule accessRule = new UiccAccessRule( 5297444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson IccUtils.hexStringToBytes(cert), "", 0x00); 5307444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson mAccessRules.add(accessRule); 5317444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson } 5327444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson updateState(STATE_LOADED, "Success!"); 5337444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson } 5347444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson break; 5357444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson 5367444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson default: 5377444a9e9a16749d4653e6038ec81d06f65d0eb85Jeff Davidson Rlog.e(LOG_TAG, "Unknown event " + msg.what); 5384baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 5394baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 5404baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 5414baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal /* 5427541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu * Check if all rule bytes have been read from UICC. 5437541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu * For long payload, we need to fetch it repeatly before start parsing it. 5447541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu */ 5457541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu private boolean isDataComplete() { 546c3ac6ac3d62e0e1637ff8fddf945953dca60eebaJunda Liu log("isDataComplete mRules:" + mRules); 5477541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu if (mRules.startsWith(TAG_ALL_REF_AR_DO)) { 5487541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu TLV allRules = new TLV(TAG_ALL_REF_AR_DO); 5497541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu String lengthBytes = allRules.parseLength(mRules); 550c3ac6ac3d62e0e1637ff8fddf945953dca60eebaJunda Liu log("isDataComplete lengthBytes: " + lengthBytes); 5517541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu if (mRules.length() == TAG_ALL_REF_AR_DO.length() + lengthBytes.length() + 552dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie allRules.length) { 553c3ac6ac3d62e0e1637ff8fddf945953dca60eebaJunda Liu log("isDataComplete yes"); 5547541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu return true; 5557541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu } else { 556c3ac6ac3d62e0e1637ff8fddf945953dca60eebaJunda Liu log("isDataComplete no"); 5577541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu return false; 5587541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu } 5597541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu } else { 5607541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu throw new IllegalArgumentException("Tags don't match."); 5617541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu } 5627541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu } 5637541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu 5647541d468b7d9464008d6186bc7c1bcef1c925782Junda Liu /* 5654baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * Parses the rules from the input string. 5664baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal */ 567277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson private static List<UiccAccessRule> parseRules(String rules) { 568c3ac6ac3d62e0e1637ff8fddf945953dca60eebaJunda Liu log("Got rules: " + rules); 5694baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 570004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu TLV allRefArDo = new TLV(TAG_ALL_REF_AR_DO); //FF40 5714baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal allRefArDo.parse(rules, true); 5724baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 5734baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal String arDos = allRefArDo.value; 574277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson List<UiccAccessRule> accessRules = new ArrayList<>(); 5754baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal while (!arDos.isEmpty()) { 576004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu TLV refArDo = new TLV(TAG_REF_AR_DO); //E2 5774baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal arDos = refArDo.parse(arDos, false); 578277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson UiccAccessRule accessRule = parseRefArdo(refArDo.value); 57932bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu if (accessRule != null) { 58032bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu accessRules.add(accessRule); 58132bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu } else { 582dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie Rlog.e(LOG_TAG, "Skip unrecognized rule." + refArDo.value); 58332bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu } 5844baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 5854baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return accessRules; 5864baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 5874baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 5884baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal /* 5894baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal * Parses a single rule. 5904baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal */ 591277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson private static UiccAccessRule parseRefArdo(String rule) { 592c3ac6ac3d62e0e1637ff8fddf945953dca60eebaJunda Liu log("Got rule: " + rule); 5934baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 5944baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal String certificateHash = null; 5954baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal String packageName = null; 596004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu String tmp = null; 5974baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal long accessType = 0; 5984baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 5994baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal while (!rule.isEmpty()) { 6004baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal if (rule.startsWith(TAG_REF_DO)) { 601004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu TLV refDo = new TLV(TAG_REF_DO); //E1 6024baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal rule = refDo.parse(rule, false); 603fb41d485d74fba0504e24dd13474d4acdd75a5efCassie // Allow 4F tag with a default value "FF FF FF FF FF FF" to be compatible with 604fb41d485d74fba0504e24dd13474d4acdd75a5efCassie // devices having GP access control enforcer: 605fb41d485d74fba0504e24dd13474d4acdd75a5efCassie // - If no 4F tag is present, it's a CP rule. 606fb41d485d74fba0504e24dd13474d4acdd75a5efCassie // - If 4F tag has value "FF FF FF FF FF FF", it's a CP rule. 607fb41d485d74fba0504e24dd13474d4acdd75a5efCassie // - If 4F tag has other values, it's not a CP rule and Android should ignore it. 608fb41d485d74fba0504e24dd13474d4acdd75a5efCassie TLV deviceDo = new TLV(TAG_DEVICE_APP_ID_REF_DO); //C1 609fb41d485d74fba0504e24dd13474d4acdd75a5efCassie if (refDo.value.startsWith(TAG_AID_REF_DO)) { 610fb41d485d74fba0504e24dd13474d4acdd75a5efCassie TLV cpDo = new TLV(TAG_AID_REF_DO); //4F 611fb41d485d74fba0504e24dd13474d4acdd75a5efCassie String remain = cpDo.parse(refDo.value, false); 612fb41d485d74fba0504e24dd13474d4acdd75a5efCassie if (!cpDo.lengthBytes.equals("06") || !cpDo.value.equals(CARRIER_PRIVILEGE_AID) 613fb41d485d74fba0504e24dd13474d4acdd75a5efCassie || remain.isEmpty() || !remain.startsWith(TAG_DEVICE_APP_ID_REF_DO)) { 614fb41d485d74fba0504e24dd13474d4acdd75a5efCassie return null; 615fb41d485d74fba0504e24dd13474d4acdd75a5efCassie } 616fb41d485d74fba0504e24dd13474d4acdd75a5efCassie tmp = deviceDo.parse(remain, false); 617fb41d485d74fba0504e24dd13474d4acdd75a5efCassie certificateHash = deviceDo.value; 618fb41d485d74fba0504e24dd13474d4acdd75a5efCassie } else if (refDo.value.startsWith(TAG_DEVICE_APP_ID_REF_DO)) { 619fb41d485d74fba0504e24dd13474d4acdd75a5efCassie tmp = deviceDo.parse(refDo.value, false); 620fb41d485d74fba0504e24dd13474d4acdd75a5efCassie certificateHash = deviceDo.value; 621fb41d485d74fba0504e24dd13474d4acdd75a5efCassie } else { 62232bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu return null; 62332bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu } 624004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu if (!tmp.isEmpty()) { 625fb41d485d74fba0504e24dd13474d4acdd75a5efCassie if (!tmp.startsWith(TAG_PKG_REF_DO)) { 626fb41d485d74fba0504e24dd13474d4acdd75a5efCassie return null; 627fb41d485d74fba0504e24dd13474d4acdd75a5efCassie } 628fb41d485d74fba0504e24dd13474d4acdd75a5efCassie TLV pkgDo = new TLV(TAG_PKG_REF_DO); //CA 629fb41d485d74fba0504e24dd13474d4acdd75a5efCassie pkgDo.parse(tmp, true); 630fb41d485d74fba0504e24dd13474d4acdd75a5efCassie packageName = new String(IccUtils.hexStringToBytes(pkgDo.value)); 6314baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } else { 632fb41d485d74fba0504e24dd13474d4acdd75a5efCassie packageName = null; 6334baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 6344baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } else if (rule.startsWith(TAG_AR_DO)) { 635004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu TLV arDo = new TLV(TAG_AR_DO); //E3 6364baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal rule = arDo.parse(rule, false); 637fb41d485d74fba0504e24dd13474d4acdd75a5efCassie // Skip all the irrelevant tags (All the optional tags here are two bytes 638fb41d485d74fba0504e24dd13474d4acdd75a5efCassie // according to the spec GlobalPlatform Secure Element Access Control). 639fb41d485d74fba0504e24dd13474d4acdd75a5efCassie String remain = arDo.value; 640fb41d485d74fba0504e24dd13474d4acdd75a5efCassie while (!remain.isEmpty() && !remain.startsWith(TAG_PERM_AR_DO)) { 641fb41d485d74fba0504e24dd13474d4acdd75a5efCassie TLV tmpDo = new TLV(remain.substring(0, 2)); 642fb41d485d74fba0504e24dd13474d4acdd75a5efCassie remain = tmpDo.parse(remain, false); 643fb41d485d74fba0504e24dd13474d4acdd75a5efCassie } 644fb41d485d74fba0504e24dd13474d4acdd75a5efCassie if (remain.isEmpty()) { 64532bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu return null; 64632bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu } 647004868eb3f91b06ef7e86b511bbb7b354036834aJunda Liu TLV permDo = new TLV(TAG_PERM_AR_DO); //DB 648fb41d485d74fba0504e24dd13474d4acdd75a5efCassie permDo.parse(remain, true); 6494baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } else { 65032bbe4213fc554ebf00553cd9935d17fe7530aa1Junda Liu // Spec requires it must be either TAG_REF_DO or TAG_AR_DO. 6514baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal throw new RuntimeException("Invalid Rule type"); 6524baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 6534baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 6544baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 655277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson UiccAccessRule accessRule = new UiccAccessRule( 656277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson IccUtils.hexStringToBytes(certificateHash), packageName, accessType); 6574baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal return accessRule; 6584baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal } 6594baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal 6604baf17fd699249d1b387903b6db7328ad3f7b3e2Shishir Agrawal /* 661c9877fe39ad8f3641d16fd980404916da7f6ce70Shishir Agrawal * Updates the state and notifies the UiccCard that the rules have finished loading. 662c9877fe39ad8f3641d16fd980404916da7f6ce70Shishir Agrawal */ 66338aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal private void updateState(int newState, String statusMessage) { 664c9877fe39ad8f3641d16fd980404916da7f6ce70Shishir Agrawal mState.set(newState); 665c9877fe39ad8f3641d16fd980404916da7f6ce70Shishir Agrawal if (mLoadedCallback != null) { 666c9877fe39ad8f3641d16fd980404916da7f6ce70Shishir Agrawal mLoadedCallback.sendToTarget(); 667c9877fe39ad8f3641d16fd980404916da7f6ce70Shishir Agrawal } 66838aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal 66938aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal mStatusMessage = statusMessage; 670c3ac6ac3d62e0e1637ff8fddf945953dca60eebaJunda Liu } 671c3ac6ac3d62e0e1637ff8fddf945953dca60eebaJunda Liu 672c3ac6ac3d62e0e1637ff8fddf945953dca60eebaJunda Liu private static void log(String msg) { 673c3ac6ac3d62e0e1637ff8fddf945953dca60eebaJunda Liu if (DBG) Rlog.d(LOG_TAG, msg); 67438aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal } 67538aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal 67638aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal /** 67738aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal * Dumps info to Dumpsys - useful for debugging. 67838aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal */ 67938aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 68038aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal pw.println("UiccCarrierPrivilegeRules: " + this); 68138aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal pw.println(" mState=" + getStateString(mState.get())); 68238aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal pw.println(" mStatusMessage='" + mStatusMessage + "'"); 68338aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal if (mAccessRules != null) { 68438aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal pw.println(" mAccessRules: "); 685277a5a2aae73ef0233fffc350f3829aee779899fJeff Davidson for (UiccAccessRule ar : mAccessRules) { 68638aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal pw.println(" rule='" + ar + "'"); 68738aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal } 68838aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal } else { 68938aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal pw.println(" mAccessRules: null"); 69038aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal } 691a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (mUiccPkcs15 != null) { 692a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu pw.println(" mUiccPkcs15: " + mUiccPkcs15); 693a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu mUiccPkcs15.dump(fd, pw, args); 694a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } else { 695a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu pw.println(" mUiccPkcs15: null"); 696a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 69738aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal pw.flush(); 69838aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal } 69938aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal 70038aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal /* 70138aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal * Converts state into human readable format. 70238aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal */ 70338aa6d75f4edfe03a20826952e41572127bcd6c9Shishir Agrawal private String getStateString(int state) { 704dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie switch (state) { 705dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie case STATE_LOADING: 706dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie return "STATE_LOADING"; 707dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie case STATE_LOADED: 708dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie return "STATE_LOADED"; 709dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie case STATE_ERROR: 710dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie return "STATE_ERROR"; 711dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie default: 712dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie return "UNKNOWN"; 713dff5ca22c114b183d8811f2ea2ec5fb6a0b2121fCassie } 714c9877fe39ad8f3641d16fd980404916da7f6ce70Shishir Agrawal } 715b2a8b88ff6ee032bea26eb69cca72e432a7918f9Jeff Davidson} 716