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