• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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