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,
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
.