Question

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,

Was it helpful?

Solution

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.

OTHER TIPS

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);
            }
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top