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