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