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