1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.internal.telephony.uicc; 18 19import android.annotation.Nullable; 20import android.content.Intent; 21import android.content.pm.PackageInfo; 22import android.content.pm.PackageManager; 23import android.content.pm.ResolveInfo; 24import android.content.pm.Signature; 25import android.os.AsyncResult; 26import android.os.Binder; 27import android.os.Handler; 28import android.os.Message; 29import android.telephony.Rlog; 30import android.telephony.TelephonyManager; 31import android.telephony.UiccAccessRule; 32import android.text.TextUtils; 33 34import com.android.internal.telephony.CommandException; 35 36import java.io.FileDescriptor; 37import java.io.PrintWriter; 38import java.util.ArrayList; 39import java.util.Collections; 40import java.util.List; 41import java.util.Locale; 42import java.util.concurrent.atomic.AtomicInteger; 43 44/** 45 * Class that reads and stores the carrier privileged rules from the UICC. 46 * 47 * The rules are read when the class is created, hence it should only be created 48 * after the UICC can be read. And it should be deleted when a UICC is changed. 49 * 50 * Document: https://source.android.com/devices/tech/config/uicc.html 51 * 52 * {@hide} 53 */ 54public class UiccCarrierPrivilegeRules extends Handler { 55 private static final String LOG_TAG = "UiccCarrierPrivilegeRules"; 56 private static final boolean DBG = false; 57 58 private static final String ARAM_AID = "A00000015141434C00"; 59 private static final String ARAD_AID = "A00000015144414300"; 60 private static final int ARAM = 1; 61 private static final int ARAD = 0; 62 private static final int CLA = 0x80; 63 private static final int COMMAND = 0xCA; 64 private static final int P1 = 0xFF; 65 private static final int P2 = 0x40; 66 private static final int P2_EXTENDED_DATA = 0x60; 67 private static final int P3 = 0x00; 68 private static final String DATA = ""; 69 70 /* 71 * Rules format: 72 * ALL_REF_AR_DO = TAG_ALL_REF_AR_DO + len + [REF_AR_DO]*n 73 * REF_AR_DO = TAG_REF_AR_DO + len + REF-DO + AR-DO 74 * 75 * REF_DO = TAG_REF_DO + len + DEVICE_APP_ID_REF_DO + (optional) PKG_REF_DO 76 * AR_DO = TAG_AR_DO + len + PERM_AR_DO 77 * 78 * DEVICE_APP_ID_REF_DO = TAG_DEVICE_APP_ID_REF_DO + len + sha256 hexstring of cert 79 * PKG_REF_DO = TAG_PKG_REF_DO + len + package name 80 * PERM_AR_DO = TAG_PERM_AR_DO + len + detailed permission (8 bytes) 81 * 82 * Data objects hierarchy by TAG: 83 * FF40 84 * E2 85 * E1 86 * C1 87 * CA 88 * E3 89 * DB 90 */ 91 // Values from the data standard. 92 private static final String TAG_ALL_REF_AR_DO = "FF40"; 93 private static final String TAG_REF_AR_DO = "E2"; 94 private static final String TAG_REF_DO = "E1"; 95 private static final String TAG_DEVICE_APP_ID_REF_DO = "C1"; 96 private static final String TAG_PKG_REF_DO = "CA"; 97 private static final String TAG_AR_DO = "E3"; 98 private static final String TAG_PERM_AR_DO = "DB"; 99 private static final String TAG_AID_REF_DO = "4F"; 100 private static final String CARRIER_PRIVILEGE_AID = "FFFFFFFFFFFF"; 101 102 private static final int EVENT_OPEN_LOGICAL_CHANNEL_DONE = 1; 103 private static final int EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE = 2; 104 private static final int EVENT_CLOSE_LOGICAL_CHANNEL_DONE = 3; 105 private static final int EVENT_PKCS15_READ_DONE = 4; 106 107 // State of the object. 108 private static final int STATE_LOADING = 0; 109 private static final int STATE_LOADED = 1; 110 private static final int STATE_ERROR = 2; 111 112 // Max number of retries for open logical channel, interval is 10s. 113 private static final int MAX_RETRY = 1; 114 private static final int RETRY_INTERVAL_MS = 10000; 115 116 // Used for parsing the data from the UICC. 117 public static class TLV { 118 private static final int SINGLE_BYTE_MAX_LENGTH = 0x80; 119 private String tag; 120 // Length encoding is in GPC_Specification_2.2.1: 11.1.5 APDU Message and Data Length. 121 // Length field could be either 1 byte if length < 128, or multiple bytes with first byte 122 // specifying how many bytes are used for length, followed by length bytes. 123 // Bytes for the length field, in ASCII HEX string form. 124 private String lengthBytes; 125 // Decoded length as integer. 126 private Integer length; 127 private String value; 128 129 public TLV(String tag) { 130 this.tag = tag; 131 } 132 133 public String getValue() { 134 if (value == null) return ""; 135 return value; 136 } 137 138 public String parseLength(String data) { 139 int offset = tag.length(); 140 int firstByte = Integer.parseInt(data.substring(offset, offset + 2), 16); 141 if (firstByte < SINGLE_BYTE_MAX_LENGTH) { 142 length = firstByte * 2; 143 lengthBytes = data.substring(offset, offset + 2); 144 } else { 145 int numBytes = firstByte - SINGLE_BYTE_MAX_LENGTH; 146 length = Integer.parseInt(data.substring(offset + 2, offset + 2 + numBytes * 2), 16) * 2; 147 lengthBytes = data.substring(offset, offset + 2 + numBytes * 2); 148 } 149 log("TLV parseLength length=" + length + "lenghtBytes: " + lengthBytes); 150 return lengthBytes; 151 } 152 153 public String parse(String data, boolean shouldConsumeAll) { 154 log("Parse TLV: " + tag); 155 if (!data.startsWith(tag)) { 156 throw new IllegalArgumentException("Tags don't match."); 157 } 158 int index = tag.length(); 159 if (index + 2 > data.length()) { 160 throw new IllegalArgumentException("No length."); 161 } 162 163 parseLength(data); 164 index += lengthBytes.length(); 165 166 log("index="+index+" length="+length+"data.length="+data.length()); 167 int remainingLength = data.length() - (index + length); 168 if (remainingLength < 0) { 169 throw new IllegalArgumentException("Not enough data."); 170 } 171 if (shouldConsumeAll && (remainingLength != 0)) { 172 throw new IllegalArgumentException("Did not consume all."); 173 } 174 value = data.substring(index, index + length); 175 176 log("Got TLV: " + tag + "," + length + "," + value); 177 178 return data.substring(index + length); 179 } 180 } 181 182 private UiccProfile mUiccProfile; // Parent 183 private UiccPkcs15 mUiccPkcs15; // ARF fallback 184 private AtomicInteger mState; 185 private List<UiccAccessRule> mAccessRules; 186 private String mRules; 187 private Message mLoadedCallback; 188 private String mStatusMessage; // Only used for debugging. 189 private int mChannelId; // Channel Id for communicating with UICC. 190 private int mRetryCount; // Number of retries for open logical channel. 191 private boolean mCheckedRules = false; // Flag that used to mark whether get rules from ARA-D. 192 private int mAIDInUse; // Message component to identify which AID is currently in-use. 193 private final Runnable mRetryRunnable = new Runnable() { 194 @Override 195 public void run() { 196 openChannel(mAIDInUse); 197 } 198 }; 199 200 private void openChannel(int aidId) { 201 // Send open logical channel request. 202 String aid = (aidId == ARAD) ? ARAD_AID : ARAM_AID; 203 int p2 = 0x00; 204 mUiccProfile.iccOpenLogicalChannel(aid, p2, /* supported p2 value */ 205 obtainMessage(EVENT_OPEN_LOGICAL_CHANNEL_DONE, 0, aidId, null)); 206 } 207 208 public UiccCarrierPrivilegeRules(UiccProfile uiccProfile, Message loadedCallback) { 209 log("Creating UiccCarrierPrivilegeRules"); 210 mUiccProfile = uiccProfile; 211 mState = new AtomicInteger(STATE_LOADING); 212 mStatusMessage = "Not loaded."; 213 mLoadedCallback = loadedCallback; 214 mRules = ""; 215 mAccessRules = new ArrayList<>(); 216 217 // Open logical channel with ARA_D. 218 mAIDInUse = ARAD; 219 openChannel(mAIDInUse); 220 } 221 222 /** 223 * Returns true if the carrier privilege rules have finished loading. 224 */ 225 public boolean areCarrierPriviligeRulesLoaded() { 226 return mState.get() != STATE_LOADING; 227 } 228 229 /** 230 * Returns true if the carrier privilege rules have finished loading and some rules were 231 * specified. 232 */ 233 public boolean hasCarrierPrivilegeRules() { 234 return mState.get() != STATE_LOADING && mAccessRules != null && mAccessRules.size() > 0; 235 } 236 237 /** 238 * Returns package names for privilege rules. 239 * Return empty list if no rules defined or package name is empty string. 240 */ 241 public List<String> getPackageNames() { 242 List<String> pkgNames = new ArrayList<String>(); 243 if (mAccessRules != null) { 244 for (UiccAccessRule ar : mAccessRules) { 245 if (!TextUtils.isEmpty(ar.getPackageName())) { 246 pkgNames.add(ar.getPackageName()); 247 } 248 } 249 } 250 return pkgNames; 251 } 252 253 /** 254 * Returns list of access rules. 255 */ 256 public List<UiccAccessRule> getAccessRules() { 257 if (mAccessRules == null) { 258 return Collections.emptyList(); 259 } 260 return Collections.unmodifiableList(mAccessRules); 261 } 262 263 /** 264 * Returns the status of the carrier privileges for the input certificate and package name. 265 * 266 * @param signature The signature of the certificate. 267 * @param packageName name of the package. 268 * @return Access status. 269 */ 270 public int getCarrierPrivilegeStatus(Signature signature, String packageName) { 271 int state = mState.get(); 272 if (state == STATE_LOADING) { 273 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 274 } else if (state == STATE_ERROR) { 275 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES; 276 } 277 278 for (UiccAccessRule ar : mAccessRules) { 279 int accessStatus = ar.getCarrierPrivilegeStatus(signature, packageName); 280 if (accessStatus != TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS) { 281 return accessStatus; 282 } 283 } 284 285 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 286 } 287 288 /** 289 * Returns the status of the carrier privileges for the input package name. 290 * 291 * @param packageManager PackageManager for getting signatures. 292 * @param packageName name of the package. 293 * @return Access status. 294 */ 295 public int getCarrierPrivilegeStatus(PackageManager packageManager, String packageName) { 296 try { 297 // Short-circuit if there are no rules to check against, so we don't need to fetch 298 // the package info with signatures. 299 if (!hasCarrierPrivilegeRules()) { 300 int state = mState.get(); 301 if (state == STATE_LOADING) { 302 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 303 } else if (state == STATE_ERROR) { 304 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES; 305 } 306 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 307 } 308 // Include DISABLED_UNTIL_USED components. This facilitates cases where a carrier app 309 // is disabled by default, and some other component wants to enable it when it has 310 // gained carrier privileges (as an indication that a matching SIM has been inserted). 311 PackageInfo pInfo = packageManager.getPackageInfo(packageName, 312 PackageManager.GET_SIGNATURES 313 | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS); 314 return getCarrierPrivilegeStatus(pInfo); 315 } catch (PackageManager.NameNotFoundException ex) { 316 log("Package " + packageName + " not found for carrier privilege status check"); 317 } 318 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 319 } 320 321 /** 322 * Returns the status of the carrier privileges for the input package info. 323 * 324 * @param packageInfo PackageInfo for the package, containing the package signatures. 325 * @return Access status. 326 */ 327 public int getCarrierPrivilegeStatus(PackageInfo packageInfo) { 328 int state = mState.get(); 329 if (state == STATE_LOADING) { 330 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 331 } else if (state == STATE_ERROR) { 332 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES; 333 } 334 335 for (UiccAccessRule ar : mAccessRules) { 336 int accessStatus = ar.getCarrierPrivilegeStatus(packageInfo); 337 if (accessStatus != TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS) { 338 return accessStatus; 339 } 340 } 341 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 342 } 343 344 /** 345 * Returns the status of the carrier privileges for the caller of the current transaction. 346 * 347 * @param packageManager PackageManager for getting signatures and package names. 348 * @return Access status. 349 */ 350 public int getCarrierPrivilegeStatusForCurrentTransaction(PackageManager packageManager) { 351 return getCarrierPrivilegeStatusForUid(packageManager, Binder.getCallingUid()); 352 } 353 354 /** 355 * Returns the status of the carrier privileges for the caller of the current transaction. 356 * 357 * @param packageManager PackageManager for getting signatures and package names. 358 * @return Access status. 359 */ 360 public int getCarrierPrivilegeStatusForUid( 361 PackageManager packageManager, int uid) { 362 String[] packages = packageManager.getPackagesForUid(uid); 363 364 for (String pkg : packages) { 365 int accessStatus = getCarrierPrivilegeStatus(packageManager, pkg); 366 if (accessStatus != TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS) { 367 return accessStatus; 368 } 369 } 370 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 371 } 372 373 /** 374 * Returns the package name of the carrier app that should handle the input intent. 375 * 376 * @param packageManager PackageManager for getting receivers. 377 * @param intent Intent that will be sent. 378 * @return list of carrier app package names that can handle the intent. 379 * Returns null if there is an error and an empty list if there 380 * are no matching packages. 381 */ 382 public List<String> getCarrierPackageNamesForIntent( 383 PackageManager packageManager, Intent intent) { 384 List<String> packages = new ArrayList<String>(); 385 List<ResolveInfo> receivers = new ArrayList<ResolveInfo>(); 386 receivers.addAll(packageManager.queryBroadcastReceivers(intent, 0)); 387 receivers.addAll(packageManager.queryIntentContentProviders(intent, 0)); 388 receivers.addAll(packageManager.queryIntentActivities(intent, 0)); 389 receivers.addAll(packageManager.queryIntentServices(intent, 0)); 390 391 for (ResolveInfo resolveInfo : receivers) { 392 String packageName = getPackageName(resolveInfo); 393 if (packageName == null) { 394 continue; 395 } 396 397 int status = getCarrierPrivilegeStatus(packageManager, packageName); 398 if (status == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 399 packages.add(packageName); 400 } else if (status != TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS) { 401 // Any status apart from HAS_ACCESS and NO_ACCESS is considered an error. 402 return null; 403 } 404 } 405 406 return packages; 407 } 408 409 @Nullable 410 private String getPackageName(ResolveInfo resolveInfo) { 411 if (resolveInfo.activityInfo != null) { 412 return resolveInfo.activityInfo.packageName; 413 } else if (resolveInfo.serviceInfo != null) { 414 return resolveInfo.serviceInfo.packageName; 415 } else if (resolveInfo.providerInfo != null) { 416 return resolveInfo.providerInfo.packageName; 417 } 418 return null; 419 } 420 421 @Override 422 public void handleMessage(Message msg) { 423 AsyncResult ar; 424 mAIDInUse = msg.arg2; // 0 means ARA-D and 1 means ARA-M. 425 426 switch (msg.what) { 427 428 case EVENT_OPEN_LOGICAL_CHANNEL_DONE: 429 log("EVENT_OPEN_LOGICAL_CHANNEL_DONE"); 430 ar = (AsyncResult) msg.obj; 431 if (ar.exception == null && ar.result != null) { 432 mChannelId = ((int[]) ar.result)[0]; 433 mUiccProfile.iccTransmitApduLogicalChannel(mChannelId, CLA, COMMAND, P1, P2, P3, 434 DATA, obtainMessage(EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE, mChannelId, 435 mAIDInUse)); 436 } else { 437 // MISSING_RESOURCE could be due to logical channels temporarily unavailable, 438 // so we retry up to MAX_RETRY times, with an interval of RETRY_INTERVAL_MS. 439 if (ar.exception instanceof CommandException && mRetryCount < MAX_RETRY 440 && ((CommandException) (ar.exception)).getCommandError() 441 == CommandException.Error.MISSING_RESOURCE) { 442 mRetryCount++; 443 removeCallbacks(mRetryRunnable); 444 postDelayed(mRetryRunnable, RETRY_INTERVAL_MS); 445 } else { 446 if (mAIDInUse == ARAD) { 447 // Open logical channel with ARA_M. 448 mRules = ""; 449 openChannel(1); 450 } 451 if (mAIDInUse == ARAM) { 452 if (mCheckedRules) { 453 updateState(STATE_LOADED, "Success!"); 454 } else { 455 // if rules cannot be read from both ARA_D and ARA_M applet, 456 // fallback to PKCS15-based ARF. 457 log("No ARA, try ARF next."); 458 mUiccPkcs15 = new UiccPkcs15(mUiccProfile, 459 obtainMessage(EVENT_PKCS15_READ_DONE)); 460 } 461 } 462 } 463 } 464 break; 465 466 case EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE: 467 log("EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE"); 468 ar = (AsyncResult) msg.obj; 469 if (ar.exception == null && ar.result != null) { 470 IccIoResult response = (IccIoResult) ar.result; 471 if (response.sw1 == 0x90 && response.sw2 == 0x00 472 && response.payload != null && response.payload.length > 0) { 473 try { 474 mRules += IccUtils.bytesToHexString(response.payload) 475 .toUpperCase(Locale.US); 476 if (isDataComplete()) { 477 mAccessRules.addAll(parseRules(mRules)); 478 if (mAIDInUse == ARAD) { 479 mCheckedRules = true; 480 } else { 481 updateState(STATE_LOADED, "Success!"); 482 } 483 } else { 484 mUiccProfile.iccTransmitApduLogicalChannel(mChannelId, CLA, COMMAND, 485 P1, P2_EXTENDED_DATA, P3, DATA, 486 obtainMessage(EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE, 487 mChannelId, mAIDInUse)); 488 break; 489 } 490 } catch (IllegalArgumentException | IndexOutOfBoundsException ex) { 491 if (mAIDInUse == ARAM) { 492 updateState(STATE_ERROR, "Error parsing rules: " + ex); 493 } 494 } 495 } else { 496 if (mAIDInUse == ARAM) { 497 String errorMsg = "Invalid response: payload=" + response.payload 498 + " sw1=" + response.sw1 + " sw2=" + response.sw2; 499 updateState(STATE_ERROR, errorMsg); 500 } 501 } 502 } else { 503 if (mAIDInUse == ARAM) { 504 updateState(STATE_ERROR, "Error reading value from SIM."); 505 } 506 } 507 508 mUiccProfile.iccCloseLogicalChannel(mChannelId, obtainMessage( 509 EVENT_CLOSE_LOGICAL_CHANNEL_DONE, 0, mAIDInUse)); 510 mChannelId = -1; 511 break; 512 513 case EVENT_CLOSE_LOGICAL_CHANNEL_DONE: 514 log("EVENT_CLOSE_LOGICAL_CHANNEL_DONE"); 515 if (mAIDInUse == ARAD) { 516 // Close logical channel with ARA_D and then open logical channel with ARA_M. 517 mRules = ""; 518 openChannel(1); 519 } 520 break; 521 522 case EVENT_PKCS15_READ_DONE: 523 log("EVENT_PKCS15_READ_DONE"); 524 if (mUiccPkcs15 == null || mUiccPkcs15.getRules() == null) { 525 updateState(STATE_ERROR, "No ARA or ARF."); 526 } else { 527 for (String cert : mUiccPkcs15.getRules()) { 528 UiccAccessRule accessRule = new UiccAccessRule( 529 IccUtils.hexStringToBytes(cert), "", 0x00); 530 mAccessRules.add(accessRule); 531 } 532 updateState(STATE_LOADED, "Success!"); 533 } 534 break; 535 536 default: 537 Rlog.e(LOG_TAG, "Unknown event " + msg.what); 538 } 539 } 540 541 /* 542 * Check if all rule bytes have been read from UICC. 543 * For long payload, we need to fetch it repeatly before start parsing it. 544 */ 545 private boolean isDataComplete() { 546 log("isDataComplete mRules:" + mRules); 547 if (mRules.startsWith(TAG_ALL_REF_AR_DO)) { 548 TLV allRules = new TLV(TAG_ALL_REF_AR_DO); 549 String lengthBytes = allRules.parseLength(mRules); 550 log("isDataComplete lengthBytes: " + lengthBytes); 551 if (mRules.length() == TAG_ALL_REF_AR_DO.length() + lengthBytes.length() + 552 allRules.length) { 553 log("isDataComplete yes"); 554 return true; 555 } else { 556 log("isDataComplete no"); 557 return false; 558 } 559 } else { 560 throw new IllegalArgumentException("Tags don't match."); 561 } 562 } 563 564 /* 565 * Parses the rules from the input string. 566 */ 567 private static List<UiccAccessRule> parseRules(String rules) { 568 log("Got rules: " + rules); 569 570 TLV allRefArDo = new TLV(TAG_ALL_REF_AR_DO); //FF40 571 allRefArDo.parse(rules, true); 572 573 String arDos = allRefArDo.value; 574 List<UiccAccessRule> accessRules = new ArrayList<>(); 575 while (!arDos.isEmpty()) { 576 TLV refArDo = new TLV(TAG_REF_AR_DO); //E2 577 arDos = refArDo.parse(arDos, false); 578 UiccAccessRule accessRule = parseRefArdo(refArDo.value); 579 if (accessRule != null) { 580 accessRules.add(accessRule); 581 } else { 582 Rlog.e(LOG_TAG, "Skip unrecognized rule." + refArDo.value); 583 } 584 } 585 return accessRules; 586 } 587 588 /* 589 * Parses a single rule. 590 */ 591 private static UiccAccessRule parseRefArdo(String rule) { 592 log("Got rule: " + rule); 593 594 String certificateHash = null; 595 String packageName = null; 596 String tmp = null; 597 long accessType = 0; 598 599 while (!rule.isEmpty()) { 600 if (rule.startsWith(TAG_REF_DO)) { 601 TLV refDo = new TLV(TAG_REF_DO); //E1 602 rule = refDo.parse(rule, false); 603 // Allow 4F tag with a default value "FF FF FF FF FF FF" to be compatible with 604 // devices having GP access control enforcer: 605 // - If no 4F tag is present, it's a CP rule. 606 // - If 4F tag has value "FF FF FF FF FF FF", it's a CP rule. 607 // - If 4F tag has other values, it's not a CP rule and Android should ignore it. 608 TLV deviceDo = new TLV(TAG_DEVICE_APP_ID_REF_DO); //C1 609 if (refDo.value.startsWith(TAG_AID_REF_DO)) { 610 TLV cpDo = new TLV(TAG_AID_REF_DO); //4F 611 String remain = cpDo.parse(refDo.value, false); 612 if (!cpDo.lengthBytes.equals("06") || !cpDo.value.equals(CARRIER_PRIVILEGE_AID) 613 || remain.isEmpty() || !remain.startsWith(TAG_DEVICE_APP_ID_REF_DO)) { 614 return null; 615 } 616 tmp = deviceDo.parse(remain, false); 617 certificateHash = deviceDo.value; 618 } else if (refDo.value.startsWith(TAG_DEVICE_APP_ID_REF_DO)) { 619 tmp = deviceDo.parse(refDo.value, false); 620 certificateHash = deviceDo.value; 621 } else { 622 return null; 623 } 624 if (!tmp.isEmpty()) { 625 if (!tmp.startsWith(TAG_PKG_REF_DO)) { 626 return null; 627 } 628 TLV pkgDo = new TLV(TAG_PKG_REF_DO); //CA 629 pkgDo.parse(tmp, true); 630 packageName = new String(IccUtils.hexStringToBytes(pkgDo.value)); 631 } else { 632 packageName = null; 633 } 634 } else if (rule.startsWith(TAG_AR_DO)) { 635 TLV arDo = new TLV(TAG_AR_DO); //E3 636 rule = arDo.parse(rule, false); 637 // Skip all the irrelevant tags (All the optional tags here are two bytes 638 // according to the spec GlobalPlatform Secure Element Access Control). 639 String remain = arDo.value; 640 while (!remain.isEmpty() && !remain.startsWith(TAG_PERM_AR_DO)) { 641 TLV tmpDo = new TLV(remain.substring(0, 2)); 642 remain = tmpDo.parse(remain, false); 643 } 644 if (remain.isEmpty()) { 645 return null; 646 } 647 TLV permDo = new TLV(TAG_PERM_AR_DO); //DB 648 permDo.parse(remain, true); 649 } else { 650 // Spec requires it must be either TAG_REF_DO or TAG_AR_DO. 651 throw new RuntimeException("Invalid Rule type"); 652 } 653 } 654 655 UiccAccessRule accessRule = new UiccAccessRule( 656 IccUtils.hexStringToBytes(certificateHash), packageName, accessType); 657 return accessRule; 658 } 659 660 /* 661 * Updates the state and notifies the UiccCard that the rules have finished loading. 662 */ 663 private void updateState(int newState, String statusMessage) { 664 mState.set(newState); 665 if (mLoadedCallback != null) { 666 mLoadedCallback.sendToTarget(); 667 } 668 669 mStatusMessage = statusMessage; 670 } 671 672 private static void log(String msg) { 673 if (DBG) Rlog.d(LOG_TAG, msg); 674 } 675 676 /** 677 * Dumps info to Dumpsys - useful for debugging. 678 */ 679 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 680 pw.println("UiccCarrierPrivilegeRules: " + this); 681 pw.println(" mState=" + getStateString(mState.get())); 682 pw.println(" mStatusMessage='" + mStatusMessage + "'"); 683 if (mAccessRules != null) { 684 pw.println(" mAccessRules: "); 685 for (UiccAccessRule ar : mAccessRules) { 686 pw.println(" rule='" + ar + "'"); 687 } 688 } else { 689 pw.println(" mAccessRules: null"); 690 } 691 if (mUiccPkcs15 != null) { 692 pw.println(" mUiccPkcs15: " + mUiccPkcs15); 693 mUiccPkcs15.dump(fd, pw, args); 694 } else { 695 pw.println(" mUiccPkcs15: null"); 696 } 697 pw.flush(); 698 } 699 700 /* 701 * Converts state into human readable format. 702 */ 703 private String getStateString(int state) { 704 switch (state) { 705 case STATE_LOADING: 706 return "STATE_LOADING"; 707 case STATE_LOADED: 708 return "STATE_LOADED"; 709 case STATE_ERROR: 710 return "STATE_ERROR"; 711 default: 712 return "UNKNOWN"; 713 } 714 } 715} 716