5

I tried to use SIO (Shareable Interface Objects) for two different packages in order to update the business logic of my applet in future. I'm using eclipse, and I start two different JavaCard applications, ClientSIOApplet and ServerSIOApplet. There is a package named appClient in ClientSIOApplet and one named appServer in ServerSIOApplet. Also, ClientApplet.java and ServerAppBankInterface.java are classes in appClient and ServerAppBankInterface.java and ServerApplet.java are in appServer. You can see the source code below:

ClientApplet.java in appClient

package appClient;

import javacard.framework.AID;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.JCSystem;
import javacard.framework.Shareable;
import javacard.framework.Util;

public class ClientApplet extends Applet {

    Shareable  sio;

    byte[] serverAID = {(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x01};

    public ClientApplet() {
        // TODO Auto-generated constructor stub

    }

    public static void install(byte[] bArray, short bOffset, byte bLength) {
        // GP-compliant JavaCard applet registration
        new ClientApplet().register(bArray, (short) (bOffset + 1),
                bArray[bOffset]);       
    }

    public void process(APDU apdu) {
        // Good practice: Return 9000 on SELECT
        if (selectingApplet()) {
            return;
        }
        byte[] buf = apdu.getBuffer();      
        byte cla = buf[ISO7816.OFFSET_CLA];

        if (( cla != ISO7816.CLA_ISO7816) && (cla != (byte) 0x10))
            ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);

        switch (buf[ISO7816.OFFSET_INS]) {
        case (byte) 0x00:


             AID svrAid = JCSystem.lookupAID(serverAID, 
                                     (short)0, 
                                     (byte)serverAID.length);

            if(svrAid == null) {
                // Cannot find the serverAID AID
                ISOException.throwIt((short)0x0010);
            }

            /*sio = JCSystem.getAppletShareableInterfaceObject(svrAid, (byte)0);
            if (sio == null) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
            if (! (sio instanceof SharedArray))
                ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
            SharedArray theSharedArray = (SharedArray) sio;
            final byte[] sa = theSharedArray.getSharedArray();*/

            //ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);

            sio = JCSystem.getAppletShareableInterfaceObject(svrAid, (byte)0);


            if(sio == null){
                ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
            }


            /*if (! (sio instanceof ServerAppBankInterface))
                ISOException.throwIt(ISO7816.SW_FILE_INVALID);*/

            try{
                ServerAppBankInterface bankInterface = (ServerAppBankInterface) sio;
            }catch(Exception ex){
                ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
            }


                        break;
        //default:
            // good practice: If you don't know the INStruction, say so:
            //ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        }
    }

}

ServerAppBankInterface.java in appClient

package appClient;

import javacard.framework.Shareable;

public interface ServerAppBankInterface extends Shareable{
    //public void saveMoneyInBank(short amount);
    public short getSavedMoneyInBank();
}

ServerApplet.java in appServer

package appServer;

import javacard.framework.AID;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.Shareable;


public class ServerApplet extends Applet implements ServerAppBankInterface{



    public ServerApplet(byte[] bArray, short bOffset, byte bLength){

        register(bArray, (short) (bOffset + 1), bArray[bOffset]);

        /*final byte[] sa = new byte[] { 'm' };
        sharedArray = new SharedArrayImpl(sa);*/
    }

    public Shareable getShareableInterfaceObject(AID clientID, byte parameter){

        byte[] tempAID = {(byte)0x05, (byte)0x04, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x01};

        if((clientID.equals(tempAID,
                (short)0,
                (byte)tempAID.length)) == false)
            return  null;
        else
            return this;
            //return sharedArray;
            //return serverAppBankObject;
            //return (ServerAppBankInterface) this;
            //return (Shareable) this;

    }

    public boolean select()
    {
         return true;
    }

    public static void install(byte[] bArray, short bOffset, byte bLength) {
        // GP-compliant JavaCard applet registration
        new ServerApplet(bArray, bOffset, bLength);
    }

    public void process(APDU apdu) {
        // Good practice: Return 9000 on SELECT

        byte[] buf = apdu.getBuffer();
        switch (buf[ISO7816.OFFSET_INS]) {
        case (byte) 0x00:
            break;
        default:
            // good practice: If you don't know the INStruction, say so:
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        }
    }

    public short getSavedMoneyInBank() {
        // TODO Auto-generated method stub
        return 0;
    }



}

ServerAppBankInterface.java in appServer

package appServer;

import javacard.framework.Shareable;

public interface ServerAppBankInterface extends Shareable{
    //public void saveMoneyInBank(short amount);
    public short getSavedMoneyInBank();
}

The Problem is:

I have problem casting interface in line :

ServerAppBankInterface bankInterface = (ServerAppBankInterface) sio;

in ClientApplet.java

If I delete Try-Catch in that line I receive 0x6F00 error,

Ebrahim Ghasemi
  • 5,850
  • 10
  • 52
  • 113
Hana Bzh
  • 2,212
  • 3
  • 18
  • 38

2 Answers2

3

The server applet provides a shareable interface of the type

appServer.ServerApplet <- appServer.ServerAppBankInterface <- javacard.framework.Shareable

but when you receive this shareable interface object in your client applet, you are trying to cast it to

appClient.ServerAppBankInterface <- javacard.framework.Shareable

While the interfaces appServer.ServerAppBankInterface and appClient.ServerAppBankInterface have a similar name and expose methods with the same names, these two interface are neither the same nor do they inherit from each other. THerefore you can't cast between them.

So you are trying to cast the received shareable object instance to an unrelated type. Thus the cast fails and the (unhandled) exception is raised.

In order to solve the problem, you need to cast the received shareable object in your client applet to appServer.ServerAppBankInterface.

Michael Roland
  • 39,663
  • 10
  • 99
  • 206
  • you mean that I should have both applet in one package and also one project? If so, then does the data in server applet delete after deletion of client applet? means that, does the context of different applets in one package differ or not? – Hana Bzh Mar 02 '14 at 06:43
  • No, only your shareable interface needs to be in the scope of the `appServer` package. – Michael Roland Mar 02 '14 at 12:44
  • I couldn't get the best result with two applications. So I tried one javacard application and a package named pkgSIO with two applets named APPClient and AppServer and an Interface named ServerAppBankInterface, which APPServer implements it. Now I get the result I want. After deletion of AppClient and installing that again in the preinstalled package, I could reach the data which saved before. Thanks a lot for your help. – Hana Bzh Mar 02 '14 at 16:13
  • one another question, If I have two applications with 2 packages with the same name, then what should I define for applet AID and package AIDs? app1-->pkg (AID = 0102030405)-->AppletClient (AID = 010203040501) app2-->pkg (AID = 010203040506)-->AppletServer (AID = 01020304050601) – Hana Bzh Mar 04 '14 at 18:05
3

Here is the updated code.

It is working fine at my end on JCIDE.

package appServer

  1. ServerApplet.java
    package appServer;

    import javacard.framework.AID;
    import javacard.framework.APDU;
    import javacard.framework.Applet;
    import javacard.framework.ISO7816;
    import javacard.framework.ISOException;
    import javacard.framework.Shareable;
    
    public class ServerApplet extends Applet implements ServerAppBankInterface
    {
        public ServerApplet(byte[] bArray, short bOffset, byte bLength) {
            register(bArray, (short) (bOffset + 1), bArray[bOffset]);
        }
    
        public Shareable getShareableInterfaceObject(AID clientID, byte parameter) {
            byte[] tempAID = {(byte)0xA0, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01,(byte)0xAA};
    
            if ((clientID.equals(tempAID,
                    (short)0,
                    (byte)tempAID.length)) == false)
                return null;
            else
                return this;
        }
    
        public boolean select() {
             return true;
        }
    
        public static void install(byte[] bArray, short bOffset, byte bLength) {
            // GP-compliant JavaCard applet registration
            new ServerApplet(bArray, bOffset, bLength);
        }
    
        public void process(APDU apdu) {
            // Good practice: Return 9000 on SELECT
            byte[] buf = apdu.getBuffer();
            switch (buf[ISO7816.OFFSET_INS]) {
            case (byte) 0x00:
                break;
            default:
                // good practice: If you don't know the INStruction, say so:
                ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
            }
        }
    
        public short getSavedMoneyInBank() {
            // TODO Auto-generated method stub
            return 0;
        }
    }
  1. ServerAppBankInterface.java
    package appServer;
    
    import javacard.framework.Shareable;
    
    public interface ServerAppBankInterface extends Shareable {
        //public void saveMoneyInBank(short amount);
        public short getSavedMoneyInBank();
    }

package appClient

1.Client Applet

    package appClient ;
    
    import appServer.*;
    import javacard.framework.AID;
    import javacard.framework.APDU;
    import javacard.framework.Applet;
    import javacard.framework.ISO7816;
    import javacard.framework.ISOException;
    import javacard.framework.JCSystem;
    import javacard.framework.Shareable;
    import javacard.framework.Util;
    
    public class ClientApplet extends Applet 
    {
        ServerAppBankInterface  sio;
    
        byte[] serverAID = {(byte)0xA0, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02,(byte)0xBB};
    
        public ClientApplet() {
            // TODO Auto-generated constructor stub
        }
    
        public static void install(byte[] bArray, short bOffset, byte bLength) {
            // GP-compliant JavaCard applet registration
            new ClientApplet().register(bArray, (short) (bOffset + 1),
                    bArray[bOffset]);       
        }
    
        public void process(APDU apdu) {
            // Good practice: Return 9000 on SELECT
            if (selectingApplet()) {
                return;
            }
            byte[] buf = apdu.getBuffer();      
            byte cla = buf[ISO7816.OFFSET_CLA];
    
            if ((cla != ISO7816.CLA_ISO7816) && (cla != (byte) 0x10))
                ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
    
            switch (buf[ISO7816.OFFSET_INS]) {
            case (byte) 0x00:
                AID svrAid = JCSystem.lookupAID(serverAID, 
                                         (short)0, 
                                         (byte)serverAID.length);
    
                if (svrAid == null) {
                    // Cannot find the serverAID AID
                    ISOException.throwIt((short)0x0010);
                }

                sio = (ServerAppBankInterface)JCSystem.getAppletShareableInterfaceObject(svrAid, (byte)0);
    
                if (sio == null){
                    ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
                }
    
                ServerAppBankInterface bankInterface = (ServerAppBankInterface) sio;
                bankInterface.getSavedMoneyInBank();
    
                break;
            default:
                // Good practice: If you don't know the INStruction, say so:
                ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
            }
        }
    }
Sergei Danielian
  • 4,938
  • 4
  • 36
  • 58
Ujjwal Roy
  • 500
  • 6
  • 9