laforge has submitted this change. ( 
https://gerrit.osmocom.org/c/android-apdu-proxy/+/41806?usp=email )

Change subject: OmapiCallbackHandlerVpcd: simplify/fix SELECT by DF-Name (aid)
......................................................................

OmapiCallbackHandlerVpcd: simplify/fix SELECT by DF-Name (aid)

When a TPDU with a SELECT by DF-Name is received from the VPCD end,
it cannot be transparently passed through the OMAPI channel as OMAPI
will block those TDPUs for security reasons. To overcome this, we
close the current OMAPI channel and re-open a new one under the new
DF-Name (AID).

To reduce the likelyhood for unexpected behaviour and possible loss
of state we have replaced the SELECT by DF-Name with a SELECT to
7fff (alias for the currently selected application), in case the
SELECT by DF-Name would target the currently selected application.

This workaround requires preceise tracking of which application is
currently selected. Unfortunately this has proven as difficult and
error prone.

After looking closer at the problem we noticed that we do not even
need the aforementioned workaround. The opening and closing of the
OMAPI channel just opens and closes logical channels on the card.
It does not perform a reset. This in particular means that the ADM
or PIN verification state is retained. (states like the currently
selected file, the current tag and the current record are reset by
SELECT anyway).

So let's remove the workaround and re-open the OMAPI channel each
time a SELECT by DF-Name is received.

Related: OS#6836
Change-Id: Ib4873b18d233e549e075b9384906a536907c6260
---
M app/src/main/java/org/osmocom/androidApduProxy/OmapiCallbackHandlerVpcd.java
1 file changed, 24 insertions(+), 44 deletions(-)

Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, approved




diff --git 
a/app/src/main/java/org/osmocom/androidApduProxy/OmapiCallbackHandlerVpcd.java 
b/app/src/main/java/org/osmocom/androidApduProxy/OmapiCallbackHandlerVpcd.java
index e2bd359..f341b09 100644
--- 
a/app/src/main/java/org/osmocom/androidApduProxy/OmapiCallbackHandlerVpcd.java
+++ 
b/app/src/main/java/org/osmocom/androidApduProxy/OmapiCallbackHandlerVpcd.java
@@ -17,7 +17,6 @@
     private int remotePort = 0;
     private Handler uiHandler = null;
     private int omapiChannel = -1;
-    private byte[] omapiAid = null;

     //When we open the OMPI channel the first time, we must provide an AID. 
The following AID is
     //the prefix (RID) of 3GPP (see also ETSI TS 101 220, section 4.1) This 
prefix should select
@@ -74,7 +73,6 @@
                     sendErrorMessage(e);
                     return;
                 }
-                omapiAid = DEFAULT_AID;
                 sendMessageInd(MainActivity.IND_CHANNEL_OPEN);
             }
             @Override
@@ -89,14 +87,12 @@
                     return;
                 }
                 sendMessageInd(MainActivity.IND_CHANNEL_OPEN);
-                omapiAid = DEFAULT_AID;
             }
             @Override
             public void vpcdPwrOff() {
                 Log.i("PROXY", "Closing OMAPI channel as an alternative to 
power-off...\n");
                 omapi.close(omapiChannel);
                 sendMessageInd(MainActivity.IND_CHANNEL_CLOSE);
-                omapiAid = null;
             }
             @Override
             public byte[] vpcdTransact(byte[] tpdu) {
@@ -111,14 +107,11 @@
                     return (Utils.h2b("6700"));
                 }

-                //In case the TPDU contains a SELECT by DF-Name, which is 
forbidden by OMAPI by design, we must
-                //find an alternative solution: In case the SELECT targets the 
currently selected application,
-                //we just use the FID 7FFF, which is an alias for the 
currently selected application. In case the
-                //AID is different, we close the OMAPI channel and re-open it 
with the new AID. If this fails, we
-                //we just pretend that we haven't found the file.
+                //In case the TPDU contains a SELECT by DF-Name (AID), we 
cannot transparently pass on the TPDU through
+                //the OMAPI channel since OMAPI will block such TPDUs for 
security reasons. The only way to archive a
+                //similar result is to close the existing OMAPI channel to and 
re-open a new OMAPI channel under the
+                //DF-Name (AID) given in in the TPDU.
                 if (Arrays.equals(Arrays.copyOf(tpdu, 3), 
Utils.h2b("00A404"))) {
-                    int compareLength = 0;
-
                     //Make sure that the Lc field of the TPDU does not exceed 
the TPDU length
                     if (tpdu[4] > tpdu.length - 5) {
                         Log.e("PROXY", String.format("SELECT by DF-Name with 
invalid length field, rejecting TPDU (%s)...\n",
@@ -142,39 +135,26 @@
                         aidReq = new byte[0];
                     }

-                    if (omapiAid != null) {
-                        if (aidReq.length < omapiAid.length)
-                            compareLength = aidReq.length;
-                        else
-                            compareLength = omapiAid.length;
-                    }
-                    if (omapiAid != null && 
Arrays.equals(Arrays.copyOf(omapiAid, compareLength), Arrays.copyOf(aidReq, 
compareLength))) {
-                        Log.i("PROXY", String.format("Selecting the currently 
selected ADF (%s->7fff), as a replacement for SELECT by DF-Name...\n",
-                                Utils.b2h(aidReq)));
-                        try {
-                            return omapi.transact(omapiChannel, 
Utils.h2b("00a40004027fff"));
-                        } catch (Exception e) {
-                            sendErrorMessage(e);
-                        }
-                    } else {
-                        Log.i("PROXY", String.format("Opening new channel for 
AID (%s) as a replacement for SELECT by DF-Name...\n",
-                                Utils.b2h(aidReq)));
-                        try {
-                            int newOmapiChannel;
-                            byte[] response;
-                            newOmapiChannel = omapi.open(omapiReader, aidReq, 
tpdu[3]);
-                            response = omapi.getSelRes(newOmapiChannel);
-                            Log.i("PROXY", String.format("Opening new channel 
(%d) for AID (%s) was successful, now closing the old channel (%d)...\n",
-                                    newOmapiChannel, Utils.b2h(aidReq), 
omapiChannel));
-                            omapi.close(omapiChannel);
-                            omapiAid = aidReq;
-                            omapiChannel = newOmapiChannel;
-                            return response;
-                        } catch (Exception e) {
-                            Log.i("PROXY", String.format("Opening new channel 
for new AID (%s) was not successful, pretending that the file was not 
found...\n",
-                                    Utils.b2h(aidReq)));
-                            return (Utils.h2b("6A82"));
-                        }
+                    //Compare the given DF-Name to the AID of the current 
OMAPI channel. If the DF-Name still matches
+                    //the AID of the current OMAPI channel, we stay on the 
current OMAPI channel. If the DF-Name
+                    //references the AID of a different application, we will 
close the current OMAPI channel and open a
+                    //new one.
+                    Log.i("PROXY", String.format("Opening new channel for AID 
(%s) as a replacement for SELECT by DF-Name...\n",
+                        Utils.b2h(aidReq)));
+                    try {
+                        int newOmapiChannel;
+                        byte[] response;
+                        newOmapiChannel = omapi.open(omapiReader, aidReq, 
tpdu[3]);
+                        response = omapi.getSelRes(newOmapiChannel);
+                        Log.i("PROXY", String.format("Opening new channel (%d) 
for AID (%s) was successful, now closing the old channel (%d)...\n",
+                            newOmapiChannel, Utils.b2h(aidReq), omapiChannel));
+                        omapi.close(omapiChannel);
+                        omapiChannel = newOmapiChannel;
+                        return response;
+                    } catch (Exception e) {
+                        Log.i("PROXY", String.format("Opening new channel for 
new AID (%s) was not successful, pretending that the file was not found...\n",
+                            Utils.b2h(aidReq)));
+                        return (Utils.h2b("6A82"));
                     }
                 }


--
To view, visit https://gerrit.osmocom.org/c/android-apdu-proxy/+/41806?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: android-apdu-proxy
Gerrit-Branch: master
Gerrit-Change-Id: Ib4873b18d233e549e075b9384906a536907c6260
Gerrit-Change-Number: 41806
Gerrit-PatchSet: 2
Gerrit-Owner: dexter <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <[email protected]>

Reply via email to