1a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu/* 2a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * Copyright (C) 2016 The Android Open Source Project 3a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * 4a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * Licensed under the Apache License, Version 2.0 (the "License"); 5a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * you may not use this file except in compliance with the License. 6a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * You may obtain a copy of the License at 7a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * 8a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * http://www.apache.org/licenses/LICENSE-2.0 9a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * 10a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * Unless required by applicable law or agreed to in writing, software 11a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * distributed under the License is distributed on an "AS IS" BASIS, 12a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * See the License for the specific language governing permissions and 14a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * limitations under the License. 15a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu */ 16a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 17a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liupackage com.android.internal.telephony.uicc; 18a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 19a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liuimport android.os.AsyncResult; 20a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liuimport android.os.Handler; 21a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liuimport android.os.Message; 22a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liuimport android.telephony.Rlog; 23a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 24a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liuimport com.android.internal.telephony.uicc.UiccCarrierPrivilegeRules.TLV; 25a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 26a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liuimport java.io.FileDescriptor; 27a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liuimport java.io.PrintWriter; 28a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liuimport java.util.ArrayList; 29a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liuimport java.util.List; 306ecde9339aae07c53148d6785c3d3c36eec501b1Junda Liuimport java.util.Locale; 31a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 32a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu/** 33a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * Class that reads PKCS15-based rules for carrier privileges. 34a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * 35a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * The spec for the rules: 36a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * GP Secure Element Access Control: 37a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * https://www.globalplatform.org/specificationsdevice.asp 38a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * 39a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * The UiccPkcs15 class handles overall flow of finding/selecting PKCS15 applet 40a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * and reading/parsing each file. Because PKCS15 can be selected in 2 different ways: 41a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * via logical channel or EF_DIR, PKCS15Selector is a handler to encapsulate the flow. 42a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * Similarly, FileHandler is used for selecting/reading each file, so common codes are 43a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * all in same place. 44a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * 45a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * {@hide} 46a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu */ 47a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liupublic class UiccPkcs15 extends Handler { 48a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static final String LOG_TAG = "UiccPkcs15"; 49a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static final boolean DBG = true; 50a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 51a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // File handler for PKCS15 files, select file and read binary, 52a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // convert to String then send to callback message. 53a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private class FileHandler extends Handler { 54a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // EF path for PKCS15 root, eg. "3F007F50" 55a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // null if logical channel is used for PKCS15 access. 56a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private final String mPkcs15Path; 57a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // Message to send when file has been parsed. 58a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private Message mCallback; 59a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // File id to read data from, eg. "5031" 60a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private String mFileId; 61a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 62a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // async events for the sequence of select and read 63a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu static protected final int EVENT_SELECT_FILE_DONE = 101; 64a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu static protected final int EVENT_READ_BINARY_DONE = 102; 65a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 66a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // pkcs15Path is nullable when using logical channel 67a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu public FileHandler(String pkcs15Path) { 68a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("Creating FileHandler, pkcs15Path: " + pkcs15Path); 69a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu mPkcs15Path = pkcs15Path; 70a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 71a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 72a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu public boolean loadFile(String fileId, Message callBack) { 73a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("loadFile: " + fileId); 74a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (fileId == null || callBack == null) return false; 75a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu mFileId = fileId; 76a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu mCallback = callBack; 77a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu selectFile(); 78a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu return true; 79a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 80a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 81a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private void selectFile() { 82a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (mChannelId >= 0) { 835b07a62f59800c985a89045fbdb7b91f80b6fb18Amit Mahajan mUiccProfile.iccTransmitApduLogicalChannel(mChannelId, 0x00, 0xA4, 0x00, 0x04, 0x02, 84a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu mFileId, obtainMessage(EVENT_SELECT_FILE_DONE)); 85a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } else { 86a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("EF based"); 87a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 88a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 89a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 90a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private void readBinary() { 91a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (mChannelId >=0 ) { 925b07a62f59800c985a89045fbdb7b91f80b6fb18Amit Mahajan mUiccProfile.iccTransmitApduLogicalChannel(mChannelId, 0x00, 0xB0, 0x00, 0x00, 0x00, 93a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu "", obtainMessage(EVENT_READ_BINARY_DONE)); 94a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } else { 95a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("EF based"); 96a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 97a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 98a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 99a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu @Override 100a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu public void handleMessage(Message msg) { 101a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("handleMessage: " + msg.what); 102a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu AsyncResult ar = (AsyncResult) msg.obj; 103a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (ar.exception != null || ar.result == null) { 104a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("Error: " + ar.exception); 105a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu AsyncResult.forMessage(mCallback, null, ar.exception); 106a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu mCallback.sendToTarget(); 107a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu return; 108a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 109a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 110a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu switch (msg.what) { 111a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu case EVENT_SELECT_FILE_DONE: 112a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu readBinary(); 113a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu break; 114a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 115a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu case EVENT_READ_BINARY_DONE: 116a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu IccIoResult response = (IccIoResult) ar.result; 1176ecde9339aae07c53148d6785c3d3c36eec501b1Junda Liu String result = IccUtils.bytesToHexString(response.payload) 1186ecde9339aae07c53148d6785c3d3c36eec501b1Junda Liu .toUpperCase(Locale.US); 119a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("IccIoResult: " + response + " payload: " + result); 120a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu AsyncResult.forMessage(mCallback, result, (result == null) ? 121a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu new IccException("Error: null response for " + mFileId) : null); 122a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu mCallback.sendToTarget(); 123a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu break; 124a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 125a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu default: 126a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("Unknown event" + msg.what); 127a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 128a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 129a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 130a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 131a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private class Pkcs15Selector extends Handler { 132a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static final String PKCS15_AID = "A000000063504B43532D3135"; 133a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private Message mCallback; 134a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static final int EVENT_OPEN_LOGICAL_CHANNEL_DONE = 201; 135a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 136a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu public Pkcs15Selector(Message callBack) { 137a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu mCallback = callBack; 13810d75a759b897da1077e3aa21ced4c46698c5552Ajay Nambi // Specified in ISO 7816-4 clause 7.1.1 0x04 means that FCP template is requested. 13910d75a759b897da1077e3aa21ced4c46698c5552Ajay Nambi int p2 = 0x04; 1405b07a62f59800c985a89045fbdb7b91f80b6fb18Amit Mahajan mUiccProfile.iccOpenLogicalChannel(PKCS15_AID, p2, /* supported P2 value */ 141a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu obtainMessage(EVENT_OPEN_LOGICAL_CHANNEL_DONE)); 142a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 143a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 144a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu @Override 145a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu public void handleMessage(Message msg) { 146a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("handleMessage: " + msg.what); 147a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu AsyncResult ar; 148a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 149a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu switch (msg.what) { 150a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu case EVENT_OPEN_LOGICAL_CHANNEL_DONE: 151a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu ar = (AsyncResult) msg.obj; 152a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (ar.exception == null && ar.result != null) { 153a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu mChannelId = ((int[]) ar.result)[0]; 154a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("mChannelId: " + mChannelId); 155a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu AsyncResult.forMessage(mCallback, null, null); 156a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } else { 157a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("error: " + ar.exception); 158a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu AsyncResult.forMessage(mCallback, null, ar.exception); 159a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // TODO: don't sendToTarget and read EF_DIR to find PKCS15 160a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 161a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu mCallback.sendToTarget(); 162a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu break; 163a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 164a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu default: 165a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("Unknown event" + msg.what); 166a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 167a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 168a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 169a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 1705b07a62f59800c985a89045fbdb7b91f80b6fb18Amit Mahajan private UiccProfile mUiccProfile; // Parent 171a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private Message mLoadedCallback; 172a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private int mChannelId = -1; // Channel Id for communicating with UICC. 173a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private List<String> mRules = new ArrayList<String>(); 174a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private Pkcs15Selector mPkcs15Selector; 175a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private FileHandler mFh; 176a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 177a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static final int EVENT_SELECT_PKCS15_DONE = 1; 178a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static final int EVENT_LOAD_ODF_DONE = 2; 179a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static final int EVENT_LOAD_DODF_DONE = 3; 180a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static final int EVENT_LOAD_ACMF_DONE = 4; 181a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static final int EVENT_LOAD_ACRF_DONE = 5; 182a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static final int EVENT_LOAD_ACCF_DONE = 6; 183a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static final int EVENT_CLOSE_LOGICAL_CHANNEL_DONE = 7; 184a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 1855b07a62f59800c985a89045fbdb7b91f80b6fb18Amit Mahajan public UiccPkcs15(UiccProfile uiccProfile, Message loadedCallback) { 186a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("Creating UiccPkcs15"); 1875b07a62f59800c985a89045fbdb7b91f80b6fb18Amit Mahajan mUiccProfile = uiccProfile; 188a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu mLoadedCallback = loadedCallback; 189a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu mPkcs15Selector = new Pkcs15Selector(obtainMessage(EVENT_SELECT_PKCS15_DONE)); 190a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 191a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 192a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu @Override 193a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu public void handleMessage(Message msg) { 194a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("handleMessage: " + msg.what); 195a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu AsyncResult ar = (AsyncResult) msg.obj; 196a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 197a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu switch (msg.what) { 198a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu case EVENT_SELECT_PKCS15_DONE: 199a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (ar.exception == null) { 200a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // ar.result is null if using logical channel, 201a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // or string for pkcs15 path if using file access. 202a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu mFh = new FileHandler((String)ar.result); 203a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (!mFh.loadFile(ID_ACRF, obtainMessage(EVENT_LOAD_ACRF_DONE))) { 204a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu cleanUp(); 205a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 206a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } else { 207a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("select pkcs15 failed: " + ar.exception); 208a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // select PKCS15 failed, notify uiccCarrierPrivilegeRules 209a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu mLoadedCallback.sendToTarget(); 210a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 211a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu break; 212a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 213a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu case EVENT_LOAD_ACRF_DONE: 214a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (ar.exception == null && ar.result != null) { 215a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu String idAccf = parseAcrf((String)ar.result); 216a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (!mFh.loadFile(idAccf, obtainMessage(EVENT_LOAD_ACCF_DONE))) { 217a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu cleanUp(); 218a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 219df3c262824b7e791027d2ec24c4f5d3040d21286fionaxu } else { 220df3c262824b7e791027d2ec24c4f5d3040d21286fionaxu cleanUp(); 221a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 222a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu break; 223a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 224a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu case EVENT_LOAD_ACCF_DONE: 225a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (ar.exception == null && ar.result != null) { 226a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu parseAccf((String)ar.result); 227a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 228a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // We are done here, no more file to read 229a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu cleanUp(); 230a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu break; 231a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 232a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu case EVENT_CLOSE_LOGICAL_CHANNEL_DONE: 233a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu break; 234a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 235a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu default: 236a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu Rlog.e(LOG_TAG, "Unknown event " + msg.what); 237a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 238a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 239a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 240a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private void cleanUp() { 241a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("cleanUp"); 242a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (mChannelId >= 0) { 2435b07a62f59800c985a89045fbdb7b91f80b6fb18Amit Mahajan mUiccProfile.iccCloseLogicalChannel(mChannelId, obtainMessage( 244a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu EVENT_CLOSE_LOGICAL_CHANNEL_DONE)); 245a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu mChannelId = -1; 246a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 247a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu mLoadedCallback.sendToTarget(); 248a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 249a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 250a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // Constants defined in specs, needed for parsing 251a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static final String CARRIER_RULE_AID = "FFFFFFFFFFFF"; // AID for carrier privilege rule 252a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static final String ID_ACRF = "4300"; 253a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static final String TAG_ASN_SEQUENCE = "30"; 254a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static final String TAG_ASN_OCTET_STRING = "04"; 255a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static final String TAG_TARGET_AID = "A0"; 256a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 257a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // parse ACRF file to get file id for ACCF file 258a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // data is hex string, return file id if parse success, null otherwise 259a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private String parseAcrf(String data) { 260a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu String ret = null; 261a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 262a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu String acRules = data; 263a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu while (!acRules.isEmpty()) { 264a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu TLV tlvRule = new TLV(TAG_ASN_SEQUENCE); 265a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu try { 266a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu acRules = tlvRule.parse(acRules, false); 267a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu String ruleString = tlvRule.getValue(); 268a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (ruleString.startsWith(TAG_TARGET_AID)) { 269a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // rule string consists of target AID + path, example: 270a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // [A0] 08 [04] 06 FF FF FF FF FF FF [30] 04 [04] 02 43 10 271a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // bytes in [] are tags for the data 272a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu TLV tlvTarget = new TLV(TAG_TARGET_AID); // A0 273a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu TLV tlvAid = new TLV(TAG_ASN_OCTET_STRING); // 04 274a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu TLV tlvAsnPath = new TLV(TAG_ASN_SEQUENCE); // 30 275a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu TLV tlvPath = new TLV(TAG_ASN_OCTET_STRING); // 04 276a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 277a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // populate tlvTarget.value with aid data, 278a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // ruleString has remaining data for path 279a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu ruleString = tlvTarget.parse(ruleString, false); 280a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // parse tlvTarget.value to get actual strings for AID. 281a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // no other tags expected so shouldConsumeAll is true. 282a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu tlvAid.parse(tlvTarget.getValue(), true); 283a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 284a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (CARRIER_RULE_AID.equals(tlvAid.getValue())) { 285a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu tlvAsnPath.parse(ruleString, true); 286a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu tlvPath.parse(tlvAsnPath.getValue(), true); 287a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu ret = tlvPath.getValue(); 288a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 289a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 290a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu continue; // skip current rule as it doesn't have expected TAG 291a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } catch (IllegalArgumentException|IndexOutOfBoundsException ex) { 292a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("Error: " + ex); 293a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu break; // Bad data, ignore all remaining ACRules 294a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 295a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 296a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu return ret; 297a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 298a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 299a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu // parse ACCF and add to mRules 300a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private void parseAccf(String data) { 301a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu String acCondition = data; 302a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu while (!acCondition.isEmpty()) { 303a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu TLV tlvCondition = new TLV(TAG_ASN_SEQUENCE); 304a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu TLV tlvCert = new TLV(TAG_ASN_OCTET_STRING); 305a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu try { 306a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu acCondition = tlvCondition.parse(acCondition, false); 307a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu tlvCert.parse(tlvCondition.getValue(), true); 308a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (!tlvCert.getValue().isEmpty()) { 309a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu mRules.add(tlvCert.getValue()); 310a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 311a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } catch (IllegalArgumentException|IndexOutOfBoundsException ex) { 312a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu log("Error: " + ex); 313a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu break; // Bad data, ignore all remaining acCondition data 314a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 315a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 316a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 317a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 318a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu public List<String> getRules() { 319a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu return mRules; 320a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 321a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 322a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu private static void log(String msg) { 323a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (DBG) Rlog.d(LOG_TAG, msg); 324a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 325a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu 326a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu /** 327a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu * Dumps info to Dumpsys - useful for debugging. 328a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu */ 329a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 330a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu if (mRules != null) { 331a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu pw.println(" mRules:"); 332a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu for (String cert : mRules) { 333a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu pw.println(" " + cert); 334a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 335a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 336a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu } 337a4113cd06d2932658ee9e38500a84c1459e27cb8Junda Liu} 338