1 /* 2 * Copyright (C) 2017 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 * Copyright (c) 2015-2017, The Linux Foundation. 18 */ 19 20 /* 21 * Contributed by: Giesecke & Devrient GmbH. 22 */ 23 24 package com.android.se; 25 26 import android.content.Context; 27 import android.content.pm.PackageInfo; 28 import android.content.pm.PackageManager; 29 import android.content.pm.PackageManager.NameNotFoundException; 30 import android.hardware.secure_element.V1_0.ISecureElement; 31 import android.hardware.secure_element.V1_0.ISecureElementHalCallback; 32 import android.hardware.secure_element.V1_0.LogicalChannelResponse; 33 import android.hardware.secure_element.V1_0.SecureElementStatus; 34 import android.os.Build; 35 import android.os.Handler; 36 import android.os.HwBinder; 37 import android.os.Message; 38 import android.os.RemoteException; 39 import android.os.ServiceSpecificException; 40 import android.se.omapi.ISecureElementListener; 41 import android.se.omapi.ISecureElementReader; 42 import android.se.omapi.ISecureElementSession; 43 import android.se.omapi.SEService; 44 import android.util.Log; 45 import android.util.StatsLog; 46 47 import com.android.se.SecureElementService.SecureElementSession; 48 import com.android.se.internal.ByteArrayConverter; 49 import com.android.se.security.AccessControlEnforcer; 50 import com.android.se.security.ChannelAccess; 51 52 import java.io.IOException; 53 import java.io.PrintWriter; 54 import java.util.ArrayList; 55 import java.util.Arrays; 56 import java.util.Collection; 57 import java.util.HashMap; 58 import java.util.Map; 59 import java.util.MissingResourceException; 60 import java.util.NoSuchElementException; 61 62 /** 63 * Each Terminal represents a Secure Element. 64 * Communicates to the SE via SecureElement HAL. 65 */ 66 public class Terminal { 67 68 private final String mTag; 69 private final Map<Integer, Channel> mChannels = new HashMap<Integer, Channel>(); 70 private final Object mLock = new Object(); 71 private final String mName; 72 public boolean mIsConnected = false; 73 private Context mContext; 74 private boolean mDefaultApplicationSelectedOnBasicChannel = true; 75 76 private static final boolean DEBUG = Build.IS_DEBUGGABLE; 77 private static final int GET_SERVICE_DELAY_MILLIS = 4 * 1000; 78 private static final int EVENT_GET_HAL = 1; 79 80 private final int mMaxGetHalRetryCount = 5; 81 private int mGetHalRetryCount = 0; 82 83 private ISecureElement mSEHal; 84 private android.hardware.secure_element.V1_2.ISecureElement mSEHal12; 85 86 /** For each Terminal there will be one AccessController object. */ 87 private AccessControlEnforcer mAccessControlEnforcer; 88 89 private static final String SECURE_ELEMENT_PRIVILEGED_OPERATION_PERMISSION = 90 "android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION"; 91 92 public static final byte[] ISD_R_AID = 93 new byte[]{ 94 (byte) 0xA0, 95 (byte) 0x00, 96 (byte) 0x00, 97 (byte) 0x05, 98 (byte) 0x59, 99 (byte) 0x10, 100 (byte) 0x10, 101 (byte) 0xFF, 102 (byte) 0xFF, 103 (byte) 0xFF, 104 (byte) 0xFF, 105 (byte) 0x89, 106 (byte) 0x00, 107 (byte) 0x00, 108 (byte) 0x01, 109 (byte) 0x00, 110 }; 111 112 private ISecureElementHalCallback.Stub mHalCallback = new ISecureElementHalCallback.Stub() { 113 @Override 114 public void onStateChange(boolean state) { 115 stateChange(state, ""); 116 } 117 }; 118 119 private android.hardware.secure_element.V1_1.ISecureElementHalCallback.Stub mHalCallback11 = 120 new android.hardware.secure_element.V1_1.ISecureElementHalCallback.Stub() { 121 @Override 122 public void onStateChange_1_1(boolean state, String reason) { 123 stateChange(state, reason); 124 } 125 126 public void onStateChange(boolean state) { 127 return; 128 } 129 }; 130 stateChange(boolean state, String reason)131 private void stateChange(boolean state, String reason) { 132 synchronized (mLock) { 133 Log.i(mTag, "OnStateChange:" + state + " reason:" + reason); 134 mIsConnected = state; 135 if (!state) { 136 if (mAccessControlEnforcer != null) { 137 mAccessControlEnforcer.reset(); 138 } 139 StatsLog.write( 140 StatsLog.SE_STATE_CHANGED, 141 StatsLog.SE_STATE_CHANGED__STATE__DISCONNECTED, 142 reason, 143 mName); 144 } else { 145 // If any logical channel in use is in the channel list, it should be closed 146 // because the access control enfocer allowed to open it by checking the access 147 // rules retrieved before. Now we are going to retrieve the rules again and 148 // the new rules can be different from the previous ones. 149 closeChannels(); 150 try { 151 initializeAccessControl(); 152 } catch (Exception e) { 153 // ignore 154 } 155 mDefaultApplicationSelectedOnBasicChannel = true; 156 StatsLog.write( 157 StatsLog.SE_STATE_CHANGED, 158 StatsLog.SE_STATE_CHANGED__STATE__CONNECTED, 159 reason, 160 mName); 161 } 162 } 163 } 164 165 class SecureElementDeathRecipient implements HwBinder.DeathRecipient { 166 @Override serviceDied(long cookie)167 public void serviceDied(long cookie) { 168 Log.e(mTag, mName + " died"); 169 StatsLog.write( 170 StatsLog.SE_STATE_CHANGED, 171 StatsLog.SE_STATE_CHANGED__STATE__HALCRASH, 172 "HALCRASH", 173 mName); 174 synchronized (mLock) { 175 mIsConnected = false; 176 if (mAccessControlEnforcer != null) { 177 mAccessControlEnforcer.reset(); 178 } 179 } 180 mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_GET_HAL, 0), 181 GET_SERVICE_DELAY_MILLIS); 182 } 183 } 184 185 private HwBinder.DeathRecipient mDeathRecipient = new SecureElementDeathRecipient(); 186 187 private Handler mHandler = new Handler() { 188 @Override 189 public void handleMessage(Message message) { 190 switch (message.what) { 191 case EVENT_GET_HAL: 192 try { 193 if (mName.startsWith(SecureElementService.ESE_TERMINAL)) { 194 initialize(true); 195 } else { 196 initialize(false); 197 } 198 } catch (Exception e) { 199 Log.e(mTag, mName + " could not be initialized again"); 200 if (mGetHalRetryCount < mMaxGetHalRetryCount) { 201 mGetHalRetryCount++; 202 sendMessageDelayed(obtainMessage(EVENT_GET_HAL, 0), 203 GET_SERVICE_DELAY_MILLIS); 204 } else { 205 Log.e(mTag, mName + " reach maximum retry count"); 206 } 207 } 208 break; 209 default: 210 break; 211 } 212 } 213 }; 214 Terminal(String name, Context context)215 public Terminal(String name, Context context) { 216 mContext = context; 217 mName = name; 218 mTag = "SecureElement-Terminal-" + getName(); 219 } 220 221 /** 222 * Initializes the terminal 223 * 224 * @throws NoSuchElementException if there is no HAL implementation for the specified SE name 225 * @throws RemoteException if there is a failure communicating with the remote 226 */ initialize(boolean retryOnFail)227 public void initialize(boolean retryOnFail) throws NoSuchElementException, RemoteException { 228 android.hardware.secure_element.V1_1.ISecureElement mSEHal11 = null; 229 synchronized (mLock) { 230 try { 231 mSEHal = mSEHal11 = mSEHal12 = 232 android.hardware.secure_element.V1_2.ISecureElement.getService(mName, 233 retryOnFail); 234 } catch (Exception e) { 235 Log.d(mTag, "SE Hal V1.2 is not supported"); 236 } 237 if (mSEHal12 == null) { 238 try { 239 mSEHal = mSEHal11 = 240 android.hardware.secure_element.V1_1.ISecureElement.getService(mName, 241 retryOnFail); 242 } catch (Exception e) { 243 Log.d(mTag, "SE Hal V1.1 is not supported"); 244 } 245 246 if (mSEHal11 == null) { 247 mSEHal = ISecureElement.getService(mName, retryOnFail); 248 if (mSEHal == null) { 249 throw new NoSuchElementException("No HAL is provided for " + mName); 250 } 251 } 252 } 253 if (mSEHal11 != null || mSEHal12 != null) { 254 mSEHal11.init_1_1(mHalCallback11); 255 } else { 256 mSEHal.init(mHalCallback); 257 } 258 mSEHal.linkToDeath(mDeathRecipient, 0); 259 } 260 Log.i(mTag, mName + " was initialized"); 261 StatsLog.write( 262 StatsLog.SE_STATE_CHANGED, 263 StatsLog.SE_STATE_CHANGED__STATE__INITIALIZED, 264 "INIT", 265 mName); 266 } 267 byteArrayToArrayList(byte[] array)268 private ArrayList<Byte> byteArrayToArrayList(byte[] array) { 269 ArrayList<Byte> list = new ArrayList<Byte>(); 270 if (array == null) { 271 return list; 272 } 273 274 for (Byte b : array) { 275 list.add(b); 276 } 277 return list; 278 } 279 arrayListToByteArray(ArrayList<Byte> list)280 private byte[] arrayListToByteArray(ArrayList<Byte> list) { 281 Byte[] byteArray = list.toArray(new Byte[list.size()]); 282 int i = 0; 283 byte[] result = new byte[list.size()]; 284 for (Byte b : byteArray) { 285 result[i++] = b.byteValue(); 286 } 287 return result; 288 } 289 290 /** 291 * Closes the given channel 292 */ closeChannel(Channel channel)293 public void closeChannel(Channel channel) { 294 if (channel == null) { 295 return; 296 } 297 synchronized (mLock) { 298 if (mIsConnected) { 299 try { 300 byte status = mSEHal.closeChannel((byte) channel.getChannelNumber()); 301 /* For Basic Channels, errors are expected. 302 * Underlying implementations use this call as an indication when there 303 * aren't any users actively using the channel, and the chip can go 304 * into low power state. 305 */ 306 if (!channel.isBasicChannel() && status != SecureElementStatus.SUCCESS) { 307 Log.e(mTag, "Error closing channel " + channel.getChannelNumber()); 308 } 309 } catch (RemoteException e) { 310 Log.e(mTag, "Exception in closeChannel() " + e); 311 } 312 } 313 mChannels.remove(channel.getChannelNumber(), channel); 314 if (mChannels.get(channel.getChannelNumber()) != null) { 315 Log.e(mTag, "Removing channel failed"); 316 } 317 } 318 } 319 320 /** 321 * Cleans up all the channels in use. 322 */ closeChannels()323 public void closeChannels() { 324 synchronized (mLock) { 325 Collection<Channel> col = mChannels.values(); 326 Channel[] channelList = col.toArray(new Channel[col.size()]); 327 for (Channel channel : channelList) { 328 channel.close(); 329 } 330 } 331 } 332 333 /** 334 * Closes the terminal. 335 */ close()336 public void close() { 337 synchronized (mLock) { 338 if (mSEHal != null) { 339 try { 340 mSEHal.unlinkToDeath(mDeathRecipient); 341 } catch (RemoteException e) { 342 // ignore 343 } 344 } 345 } 346 } 347 getName()348 public String getName() { 349 return mName; 350 } 351 352 /** 353 * Returns the ATR of the Secure Element, or null if not available. 354 */ getAtr()355 public byte[] getAtr() { 356 if (!mIsConnected) { 357 return null; 358 } 359 360 try { 361 ArrayList<Byte> responseList = mSEHal.getAtr(); 362 if (responseList.isEmpty()) { 363 return null; 364 } 365 byte[] atr = arrayListToByteArray(responseList); 366 if (DEBUG) { 367 Log.i(mTag, "ATR : " + ByteArrayConverter.byteArrayToHexString(atr)); 368 } 369 return atr; 370 } catch (RemoteException e) { 371 Log.e(mTag, "Exception in getAtr()" + e); 372 return null; 373 } 374 } 375 376 /** 377 * Selects the default application on the basic channel. 378 * 379 * If there is an exception selecting the default application, select 380 * is performed with the default access control aid. 381 */ selectDefaultApplication()382 public void selectDefaultApplication() { 383 try { 384 select(null); 385 } catch (NoSuchElementException e) { 386 if (getAccessControlEnforcer() != null) { 387 try { 388 select(mAccessControlEnforcer.getDefaultAccessControlAid()); 389 } catch (Exception ignore) { 390 } 391 } 392 } catch (Exception ignore) { 393 } 394 } 395 select(byte[] aid)396 private void select(byte[] aid) throws IOException { 397 int commandSize = (aid == null ? 0 : aid.length) + 5; 398 byte[] selectCommand = new byte[commandSize]; 399 selectCommand[0] = 0x00; 400 selectCommand[1] = (byte) 0xA4; 401 selectCommand[2] = 0x04; 402 selectCommand[3] = 0x00; 403 if (aid != null && aid.length != 0) { 404 selectCommand[4] = (byte) aid.length; 405 System.arraycopy(aid, 0, selectCommand, 5, aid.length); 406 } else { 407 selectCommand[4] = 0x00; 408 } 409 byte[] selectResponse = transmit(selectCommand); 410 if (selectResponse.length < 2) { 411 selectResponse = null; 412 throw new NoSuchElementException("Response length is too small"); 413 } 414 int sw1 = selectResponse[selectResponse.length - 2] & 0xFF; 415 int sw2 = selectResponse[selectResponse.length - 1] & 0xFF; 416 if (sw1 != 0x90 || sw2 != 0x00) { 417 selectResponse = null; 418 throw new NoSuchElementException("Status word is incorrect"); 419 } 420 } 421 422 /** 423 * Opens a Basic Channel with the given AID and P2 paramters 424 */ openBasicChannel(SecureElementSession session, byte[] aid, byte p2, ISecureElementListener listener, String packageName, int pid)425 public Channel openBasicChannel(SecureElementSession session, byte[] aid, byte p2, 426 ISecureElementListener listener, String packageName, int pid) throws IOException, 427 NoSuchElementException { 428 if (aid != null && aid.length == 0) { 429 aid = null; 430 } else if (aid != null && (aid.length < 5 || aid.length > 16)) { 431 throw new IllegalArgumentException("AID out of range"); 432 } else if (!mIsConnected) { 433 throw new IOException("Secure Element is not connected"); 434 } 435 436 ChannelAccess channelAccess = null; 437 if (packageName != null) { 438 Log.w(mTag, "Enable access control on basic channel for " + packageName); 439 StatsLog.write( 440 StatsLog.SE_OMAPI_REPORTED, 441 StatsLog.SE_OMAPI_REPORTED__OPERATION__OPEN_CHANNEL, 442 mName, 443 packageName); 444 try { 445 // For application without privilege permission or carrier privilege, 446 // openBasicChannel with UICC terminals should be rejected. 447 channelAccess = setUpChannelAccess(aid, packageName, pid, true); 448 } catch (MissingResourceException e) { 449 return null; 450 } 451 } 452 453 synchronized (mLock) { 454 if (mChannels.get(0) != null) { 455 Log.e(mTag, "basic channel in use"); 456 return null; 457 } 458 if (aid == null && !mDefaultApplicationSelectedOnBasicChannel) { 459 Log.e(mTag, "default application is not selected"); 460 return null; 461 } 462 463 ArrayList<byte[]> responseList = new ArrayList<byte[]>(); 464 byte[] status = new byte[1]; 465 466 try { 467 mSEHal.openBasicChannel(byteArrayToArrayList(aid), p2, 468 new ISecureElement.openBasicChannelCallback() { 469 @Override 470 public void onValues(ArrayList<Byte> responseObject, byte halStatus) { 471 status[0] = halStatus; 472 responseList.add(arrayListToByteArray(responseObject)); 473 return; 474 } 475 }); 476 } catch (RemoteException e) { 477 throw new IOException(e.getMessage()); 478 } 479 480 byte[] selectResponse = responseList.get(0); 481 if (status[0] == SecureElementStatus.CHANNEL_NOT_AVAILABLE) { 482 return null; 483 } else if (status[0] == SecureElementStatus.UNSUPPORTED_OPERATION) { 484 throw new UnsupportedOperationException("OpenBasicChannel() failed"); 485 } else if (status[0] == SecureElementStatus.IOERROR) { 486 throw new IOException("OpenBasicChannel() failed"); 487 } else if (status[0] == SecureElementStatus.NO_SUCH_ELEMENT_ERROR) { 488 throw new NoSuchElementException("OpenBasicChannel() failed"); 489 } 490 491 Channel basicChannel = new Channel(session, this, 0, selectResponse, aid, 492 listener); 493 basicChannel.setChannelAccess(channelAccess); 494 495 if (aid != null) { 496 mDefaultApplicationSelectedOnBasicChannel = false; 497 } 498 mChannels.put(0, basicChannel); 499 return basicChannel; 500 } 501 } 502 503 /** 504 * Opens a logical Channel without Channel Access initialization. 505 */ openLogicalChannelWithoutChannelAccess(byte[] aid)506 public Channel openLogicalChannelWithoutChannelAccess(byte[] aid) throws IOException, 507 NoSuchElementException { 508 return openLogicalChannel(null, aid, (byte) 0x00, null, null, 0); 509 } 510 511 /** 512 * Opens a logical Channel with AID. 513 */ openLogicalChannel(SecureElementSession session, byte[] aid, byte p2, ISecureElementListener listener, String packageName, int pid)514 public Channel openLogicalChannel(SecureElementSession session, byte[] aid, byte p2, 515 ISecureElementListener listener, String packageName, int pid) throws IOException, 516 NoSuchElementException { 517 if (aid != null && aid.length == 0) { 518 aid = null; 519 } else if (aid != null && (aid.length < 5 || aid.length > 16)) { 520 throw new IllegalArgumentException("AID out of range"); 521 } else if (!mIsConnected) { 522 throw new IOException("Secure Element is not connected"); 523 } 524 525 ChannelAccess channelAccess = null; 526 if (packageName != null) { 527 Log.w(mTag, "Enable access control on logical channel for " + packageName); 528 StatsLog.write( 529 StatsLog.SE_OMAPI_REPORTED, 530 StatsLog.SE_OMAPI_REPORTED__OPERATION__OPEN_CHANNEL, 531 mName, 532 packageName); 533 try { 534 channelAccess = setUpChannelAccess(aid, packageName, pid, false); 535 } catch (MissingResourceException | UnsupportedOperationException e) { 536 return null; 537 } 538 } 539 540 synchronized (mLock) { 541 LogicalChannelResponse[] responseArray = new LogicalChannelResponse[1]; 542 byte[] status = new byte[1]; 543 544 try { 545 mSEHal.openLogicalChannel(byteArrayToArrayList(aid), p2, 546 new ISecureElement.openLogicalChannelCallback() { 547 @Override 548 public void onValues(LogicalChannelResponse response, byte halStatus) { 549 status[0] = halStatus; 550 responseArray[0] = response; 551 return; 552 } 553 }); 554 } catch (RemoteException e) { 555 throw new IOException(e.getMessage()); 556 } 557 558 if (status[0] == SecureElementStatus.CHANNEL_NOT_AVAILABLE) { 559 return null; 560 } else if (status[0] == SecureElementStatus.UNSUPPORTED_OPERATION) { 561 throw new UnsupportedOperationException("OpenLogicalChannel() failed"); 562 } else if (status[0] == SecureElementStatus.IOERROR) { 563 throw new IOException("OpenLogicalChannel() failed"); 564 } else if (status[0] == SecureElementStatus.NO_SUCH_ELEMENT_ERROR) { 565 throw new NoSuchElementException("OpenLogicalChannel() failed"); 566 } 567 if (responseArray[0].channelNumber <= 0 || status[0] != SecureElementStatus.SUCCESS) { 568 return null; 569 } 570 int channelNumber = responseArray[0].channelNumber; 571 byte[] selectResponse = arrayListToByteArray(responseArray[0].selectResponse); 572 Channel logicalChannel = new Channel(session, this, channelNumber, 573 selectResponse, aid, listener); 574 logicalChannel.setChannelAccess(channelAccess); 575 576 mChannels.put(channelNumber, logicalChannel); 577 return logicalChannel; 578 } 579 } 580 581 /** 582 * Returns true if the given AID can be selected on the Terminal 583 */ isAidSelectable(byte[] aid)584 public boolean isAidSelectable(byte[] aid) { 585 if (aid == null) { 586 throw new NullPointerException("aid must not be null"); 587 } else if (!mIsConnected) { 588 Log.e(mTag, "Secure Element is not connected"); 589 return false; 590 } 591 592 synchronized (mLock) { 593 LogicalChannelResponse[] responseArray = new LogicalChannelResponse[1]; 594 byte[] status = new byte[1]; 595 try { 596 mSEHal.openLogicalChannel(byteArrayToArrayList(aid), (byte) 0x00, 597 new ISecureElement.openLogicalChannelCallback() { 598 @Override 599 public void onValues(LogicalChannelResponse response, byte halStatus) { 600 status[0] = halStatus; 601 responseArray[0] = response; 602 return; 603 } 604 }); 605 if (status[0] == SecureElementStatus.SUCCESS) { 606 mSEHal.closeChannel(responseArray[0].channelNumber); 607 return true; 608 } 609 return false; 610 } catch (RemoteException e) { 611 Log.e(mTag, "Error in isAidSelectable() returning false" + e); 612 return false; 613 } 614 } 615 } 616 617 /** 618 * Transmits the specified command and returns the response. 619 * 620 * @param cmd the command APDU to be transmitted. 621 * @return the response received. 622 */ transmit(byte[] cmd)623 public byte[] transmit(byte[] cmd) throws IOException { 624 if (!mIsConnected) { 625 Log.e(mTag, "Secure Element is not connected"); 626 throw new IOException("Secure Element is not connected"); 627 } 628 629 byte[] rsp = transmitInternal(cmd); 630 int sw1 = rsp[rsp.length - 2] & 0xFF; 631 int sw2 = rsp[rsp.length - 1] & 0xFF; 632 633 if (sw1 == 0x6C) { 634 cmd[cmd.length - 1] = rsp[rsp.length - 1]; 635 rsp = transmit(cmd); 636 } else if (sw1 == 0x61) { 637 do { 638 byte[] getResponseCmd = new byte[]{ 639 cmd[0], (byte) 0xC0, 0x00, 0x00, (byte) sw2 640 }; 641 byte[] tmp = transmitInternal(getResponseCmd); 642 byte[] aux = rsp; 643 rsp = new byte[aux.length + tmp.length - 2]; 644 System.arraycopy(aux, 0, rsp, 0, aux.length - 2); 645 System.arraycopy(tmp, 0, rsp, aux.length - 2, tmp.length); 646 sw1 = rsp[rsp.length - 2] & 0xFF; 647 sw2 = rsp[rsp.length - 1] & 0xFF; 648 } while (sw1 == 0x61); 649 } 650 return rsp; 651 } 652 transmitInternal(byte[] cmd)653 private byte[] transmitInternal(byte[] cmd) throws IOException { 654 ArrayList<Byte> response; 655 try { 656 response = mSEHal.transmit(byteArrayToArrayList(cmd)); 657 } catch (RemoteException e) { 658 throw new IOException(e.getMessage()); 659 } 660 if (response.isEmpty()) { 661 throw new IOException("Error in transmit()"); 662 } 663 byte[] rsp = arrayListToByteArray(response); 664 if (DEBUG) { 665 Log.i(mTag, "Sent : " + ByteArrayConverter.byteArrayToHexString(cmd)); 666 Log.i(mTag, "Received : " + ByteArrayConverter.byteArrayToHexString(rsp)); 667 } 668 return rsp; 669 } 670 671 /** 672 * Checks if the application is authorized to receive the transaction event. 673 */ isNfcEventAllowed(PackageManager packageManager, byte[] aid, String[] packageNames)674 public boolean[] isNfcEventAllowed(PackageManager packageManager, byte[] aid, 675 String[] packageNames) { 676 // Attempt to initialize the access control enforcer if it failed in the previous attempt 677 // due to a kind of temporary failure or no rule was found. 678 if (mAccessControlEnforcer == null || mAccessControlEnforcer.isNoRuleFound()) { 679 try { 680 initializeAccessControl(); 681 // Just finished to initialize the access control enforcer. 682 // It is too much to check the refresh tag in this case. 683 } catch (Exception e) { 684 Log.i(mTag, "isNfcEventAllowed Exception: " + e.getMessage()); 685 return null; 686 } 687 } 688 mAccessControlEnforcer.setPackageManager(packageManager); 689 690 synchronized (mLock) { 691 try { 692 return mAccessControlEnforcer.isNfcEventAllowed(aid, packageNames); 693 } catch (Exception e) { 694 Log.i(mTag, "isNfcEventAllowed Exception: " + e.getMessage()); 695 return null; 696 } 697 } 698 } 699 700 /** 701 * Returns true if the Secure Element is present 702 */ isSecureElementPresent()703 public boolean isSecureElementPresent() { 704 try { 705 return mSEHal.isCardPresent(); 706 } catch (RemoteException e) { 707 Log.e(mTag, "Error in isSecureElementPresent() " + e); 708 return false; 709 } 710 } 711 712 /** 713 * Reset the Secure Element. Return true if success, false otherwise. 714 */ reset()715 public boolean reset() { 716 if (mSEHal12 == null) { 717 return false; 718 } 719 mContext.enforceCallingOrSelfPermission( 720 android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION, 721 "Need SECURE_ELEMENT_PRIVILEGED_OPERATION permission"); 722 723 try { 724 byte status = mSEHal12.reset(); 725 // Successfully trigger reset. HAL service should send onStateChange 726 // after secure element reset and initialization process complete 727 if (status == SecureElementStatus.SUCCESS) { 728 return true; 729 } 730 Log.e(mTag, "Error reseting terminal " + mName); 731 } catch (RemoteException e) { 732 Log.e(mTag, "Exception in reset()" + e); 733 } 734 return false; 735 } 736 737 /** 738 * Initialize the Access Control and set up the channel access. 739 */ setUpChannelAccess(byte[] aid, String packageName, int pid, boolean isBasicChannel)740 private ChannelAccess setUpChannelAccess(byte[] aid, String packageName, int pid, 741 boolean isBasicChannel) throws IOException, MissingResourceException { 742 boolean checkRefreshTag = true; 743 if (isPrivilegedApplication(packageName)) { 744 return ChannelAccess.getPrivilegeAccess(packageName, pid); 745 } 746 // Attempt to initialize the access control enforcer if it failed 747 // due to a kind of temporary failure or no rule was found in the previous attempt. 748 // For privilege access, do not attempt to initialize the access control enforcer 749 // if no rule was found in the previous attempt. 750 if (mAccessControlEnforcer == null || mAccessControlEnforcer.isNoRuleFound()) { 751 initializeAccessControl(); 752 // Just finished to initialize the access control enforcer. 753 // It is too much to check the refresh tag in this case. 754 checkRefreshTag = false; 755 } 756 mAccessControlEnforcer.setPackageManager(mContext.getPackageManager()); 757 758 // Check carrier privilege when AID is not ISD-R 759 if (getName().startsWith(SecureElementService.UICC_TERMINAL) 760 && !Arrays.equals(aid, ISD_R_AID)) { 761 try { 762 PackageManager pm = mContext.getPackageManager(); 763 if (pm != null) { 764 PackageInfo pkgInfo = 765 pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); 766 // Do not check the refresh tag for carrier privilege 767 if (mAccessControlEnforcer.checkCarrierPrivilege(pkgInfo, false)) { 768 Log.i(mTag, "setUp PrivilegeAccess for CarrierPrivilegeApplication. "); 769 return ChannelAccess.getCarrierPrivilegeAccess(packageName, pid); 770 } 771 } 772 } catch (NameNotFoundException ne) { 773 Log.e(mTag, "checkCarrierPrivilege(): packageInfo is not found. "); 774 } catch (Exception e) { 775 Log.e(mTag, "checkCarrierPrivilege() Exception: " + e.getMessage()); 776 } 777 if (isBasicChannel) { 778 throw new MissingResourceException("openBasicChannel is not allowed.", "", ""); 779 } else if (aid == null) { 780 // openLogicalChannel with null aid is only allowed for privilege applications 781 throw new UnsupportedOperationException( 782 "null aid is not accepted in UICC terminal."); 783 } 784 } 785 786 synchronized (mLock) { 787 try { 788 ChannelAccess channelAccess = 789 mAccessControlEnforcer.setUpChannelAccess(aid, packageName, 790 checkRefreshTag); 791 channelAccess.setCallingPid(pid); 792 return channelAccess; 793 } catch (IOException | MissingResourceException e) { 794 throw e; 795 } catch (Exception e) { 796 throw new SecurityException("Exception in setUpChannelAccess()" + e); 797 } 798 } 799 } 800 801 /** 802 * Initializes the Access Control for this Terminal 803 */ initializeAccessControl()804 private synchronized void initializeAccessControl() throws IOException, 805 MissingResourceException { 806 synchronized (mLock) { 807 if (mAccessControlEnforcer == null) { 808 mAccessControlEnforcer = new AccessControlEnforcer(this); 809 } 810 try { 811 mAccessControlEnforcer.initialize(); 812 } catch (IOException | MissingResourceException e) { 813 // Retrieving access rules failed because of an IO error happened between 814 // the terminal and the secure element or the lack of a logical channel available. 815 // It might be a temporary failure, so the terminal shall attempt to cache 816 // the access rules again later. 817 mAccessControlEnforcer = null; 818 throw e; 819 } 820 } 821 } 822 823 /** 824 * Checks if Secure Element Privilege permission exists for the given package 825 */ isPrivilegedApplication(String packageName)826 private boolean isPrivilegedApplication(String packageName) { 827 PackageManager pm = mContext.getPackageManager(); 828 if (pm != null) { 829 return (pm.checkPermission(SECURE_ELEMENT_PRIVILEGED_OPERATION_PERMISSION, 830 packageName) == PackageManager.PERMISSION_GRANTED); 831 } 832 return false; 833 } 834 getAccessControlEnforcer()835 public AccessControlEnforcer getAccessControlEnforcer() { 836 return mAccessControlEnforcer; 837 } 838 getContext()839 public Context getContext() { 840 return mContext; 841 } 842 843 /** 844 * Checks if Carrier Privilege exists for the given package 845 */ checkCarrierPrivilegeRules(PackageInfo pInfo)846 public boolean checkCarrierPrivilegeRules(PackageInfo pInfo) { 847 boolean checkRefreshTag = true; 848 if (mAccessControlEnforcer == null || mAccessControlEnforcer.isNoRuleFound()) { 849 try { 850 initializeAccessControl(); 851 } catch (IOException e) { 852 return false; 853 } 854 checkRefreshTag = false; 855 } 856 mAccessControlEnforcer.setPackageManager(mContext.getPackageManager()); 857 858 synchronized (mLock) { 859 try { 860 return mAccessControlEnforcer.checkCarrierPrivilege(pInfo, checkRefreshTag); 861 } catch (Exception e) { 862 Log.i(mTag, "checkCarrierPrivilege() Exception: " + e.getMessage()); 863 return false; 864 } 865 } 866 } 867 868 /** Dump data for debug purpose . */ dump(PrintWriter writer)869 public void dump(PrintWriter writer) { 870 writer.println("SECURE ELEMENT SERVICE TERMINAL: " + mName); 871 writer.println(); 872 873 writer.println("mIsConnected:" + mIsConnected); 874 writer.println(); 875 876 /* Dump the list of currunlty openned channels */ 877 writer.println("List of open channels:"); 878 879 for (Channel channel : mChannels.values()) { 880 writer.println("channel " + channel.getChannelNumber() + ": "); 881 writer.println("package: " + channel.getChannelAccess().getPackageName()); 882 writer.println("pid: " + channel.getChannelAccess().getCallingPid()); 883 writer.println("aid selected: " + channel.hasSelectedAid()); 884 writer.println("basic channel: " + channel.isBasicChannel()); 885 writer.println(); 886 } 887 writer.println(); 888 889 /* Dump ACE data */ 890 if (mAccessControlEnforcer != null) { 891 mAccessControlEnforcer.dump(writer); 892 } 893 } 894 895 // Implementation of the SecureElement Reader interface according to OMAPI. 896 final class SecureElementReader extends ISecureElementReader.Stub { 897 898 private final SecureElementService mService; 899 private final ArrayList<SecureElementSession> mSessions = 900 new ArrayList<SecureElementSession>(); 901 SecureElementReader(SecureElementService service)902 SecureElementReader(SecureElementService service) { 903 mService = service; 904 } 905 getAtr()906 public byte[] getAtr() { 907 return Terminal.this.getAtr(); 908 } 909 910 @Override isSecureElementPresent()911 public boolean isSecureElementPresent() throws RemoteException { 912 return Terminal.this.isSecureElementPresent(); 913 } 914 915 @Override closeSessions()916 public void closeSessions() { 917 synchronized (mLock) { 918 while (mSessions.size() > 0) { 919 try { 920 mSessions.get(0).close(); 921 } catch (Exception ignore) { 922 } 923 } 924 mSessions.clear(); 925 } 926 } 927 removeSession(SecureElementSession session)928 public void removeSession(SecureElementSession session) { 929 if (session == null) { 930 throw new NullPointerException("session is null"); 931 } 932 933 synchronized (mLock) { 934 mSessions.remove(session); 935 if (mSessions.size() == 0) { 936 mDefaultApplicationSelectedOnBasicChannel = true; 937 } 938 } 939 } 940 941 @Override openSession()942 public ISecureElementSession openSession() throws RemoteException { 943 if (!isSecureElementPresent()) { 944 throw new ServiceSpecificException(SEService.IO_ERROR, 945 "Secure Element is not present."); 946 } 947 948 synchronized (mLock) { 949 SecureElementSession session = mService.new SecureElementSession(this); 950 mSessions.add(session); 951 return session; 952 } 953 } 954 getTerminal()955 Terminal getTerminal() { 956 return Terminal.this; 957 } 958 959 @Override reset()960 public boolean reset() { 961 return Terminal.this.reset(); 962 } 963 } 964 } 965