The exclusive promotional activities on JCOP J3H145 card and Feitian R301 Smartcard Reader are in full swing. Please check this page for details.

How to get object working over Shareable Interface

JavaCard Applet Development Related Questions and Answers.
tay00000
Posts: 141
Joined: Tue Sep 27, 2016 10:58 am
Points :1888
Contact:

How to get object working over Shareable Interface

Post by tay00000 » Mon Apr 29, 2019 4:51 am

We have the classical setup of two applets and a Shareable Interface used by both of them.

Shareable Inteface:

Code: Select all

package API;

import javacard.framework.Shareable;

public interface API extends Shareable {

    public void getArray(byte[] output, short off, short len);

}
Server Applet:

Code: Select all

package ShareableSampleApplet;

import javacard.framework.*;
import API.API;

public class ShareableSampleApplet extends Applet {

    public AID apiAID = new AID(
            new byte[]{
                (byte) 0x4B, (byte) 0x4D, (byte) 0x31, (byte) 0x30, (byte) 0x31, (byte) 0x00
            },
            (short) 0,
            (byte) 6);
    public API api = null;
    public byte[] b0 = JCSystem.makeTransientByteArray((short) 258, JCSystem.CLEAR_ON_RESET);
    public short[] sb = JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET);

    public static void install(byte[] bArray, short bOffset, byte bLength) {
        new ShareableSampleApplet();
    }

    protected ShareableSampleApplet() {
        register();
    }

    public void process(APDU apdu) {
        if (selectingApplet()) {
            return;
        }

        byte[] buffer = apdu.getBuffer();

        if ((buffer[ISO7816.OFFSET_CLA] == (byte) 0xB0) && (buffer[ISO7816.OFFSET_INS] == (byte) 0x00)) {
            if (api == null) {
                api = (API) JCSystem.getAppletShareableInterfaceObject(apiAID, (byte) 0);
            }
        } else if ((buffer[ISO7816.OFFSET_CLA] == (byte) 0xB0) && (buffer[ISO7816.OFFSET_INS] == (byte) 0x10)) {
            if (api != null) {
                try {
                    api.getArray(b0, (short) 0, (short) 5);
                    apdu.setOutgoing();
                    apdu.setOutgoingLength((short) 5);
                    apdu.sendBytesLong(b0, (short) 0, (short) 5);
                } catch (Exception e) {
                    if (e instanceof NullPointerException) {
                        ISOException.throwIt(Util.makeShort((byte) 0x6f, (byte) 0x21));
                    } else if (e instanceof SecurityException) {
                        ISOException.throwIt(Util.makeShort((byte) 0x6f, (byte) 0x22));
                    } else if (e instanceof ArrayIndexOutOfBoundsException) {
                        ISOException.throwIt(Util.makeShort((byte) 0x6f, (byte) 0x23));
                    } else if (e instanceof UserException) {
                        ISOException.throwIt(Util.makeShort((byte) 0x6f, (byte) 0x24));
                    } else if (e instanceof SystemException) {
                        ISOException.throwIt(Util.makeShort((byte) 0x6f, (byte) 0x25));
                    } else if (e instanceof CardRuntimeException) {
                        ISOException.throwIt(Util.makeShort((byte) 0x6f, (byte) 0x26));
                    } else if (e instanceof ClassCastException) {
                        ISOException.throwIt(Util.makeShort((byte) 0x6f, (byte) 0x27));
                    } else {
                        ISOException.throwIt(Util.makeShort((byte) 0x6f, (byte) 0x2F));
                    }
                }
            } else {
                ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
            }
        } else {
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        }
    }
}
Client Code:

Code: Select all

package ShareableSampleClient;

import javacard.framework.*;
import API.API;

public class ShareableSampleClient extends Applet {

    public AID apiAID = new AID(
            new byte[]{
                (byte) 0x4B, (byte) 0x4D, (byte) 0x31, (byte) 0x30, (byte) 0x31, (byte) 0x00
            },
            (short) 0,
            (byte) 6);
    public API api = null;
    public byte[] b0 = JCSystem.makeTransientByteArray((short) 258, JCSystem.CLEAR_ON_RESET);
    public short[] sb = JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET);

    public static void install(byte[] bArray, short bOffset, byte bLength) {
        new ShareableSampleClient();
    }

    protected ShareableSampleClient() {
        register();
    }

    public void process(APDU apdu) {
        if (selectingApplet()) {
            return;
        }

        byte[] buffer = apdu.getBuffer();

        if ((buffer[ISO7816.OFFSET_CLA] == (byte) 0xB0) && (buffer[ISO7816.OFFSET_INS] == (byte) 0x00)) {
            if (api == null) {
                api = (API) JCSystem.getAppletShareableInterfaceObject(apiAID, (byte) 0);
            }
        } else if ((buffer[ISO7816.OFFSET_CLA] == (byte) 0xB0) && (buffer[ISO7816.OFFSET_INS] == (byte) 0x10)) {
            if (api != null) {
                try {
                    api.getArray(b0, (short) 0, (short) 5);
                    apdu.setOutgoing();
                    apdu.setOutgoingLength((short) 5);
                    apdu.sendBytesLong(b0, (short) 0, (short) 5);
                } catch (Exception e) {
                    if (e instanceof NullPointerException) {
                        ISOException.throwIt(Util.makeShort((byte) 0x6f, (byte) 0x21));
                    } else if (e instanceof SecurityException) {
                        ISOException.throwIt(Util.makeShort((byte) 0x6f, (byte) 0x22));
                    } else if (e instanceof ArrayIndexOutOfBoundsException) {
                        ISOException.throwIt(Util.makeShort((byte) 0x6f, (byte) 0x23));
                    } else if (e instanceof UserException) {
                        ISOException.throwIt(Util.makeShort((byte) 0x6f, (byte) 0x24));
                    } else if (e instanceof SystemException) {
                        ISOException.throwIt(Util.makeShort((byte) 0x6f, (byte) 0x25));
                    } else if (e instanceof CardRuntimeException) {
                        ISOException.throwIt(Util.makeShort((byte) 0x6f, (byte) 0x26));
                    } else if (e instanceof ClassCastException) {
                        ISOException.throwIt(Util.makeShort((byte) 0x6f, (byte) 0x27));
                    } else {
                        ISOException.throwIt(Util.makeShort((byte) 0x6f, (byte) 0x2F));
                    }
                }
            } else {
                ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
            }
        } else {
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        }
    }
}
I tried the above demo codes on A40CR and the APDU results:

Code: Select all

>>> 00 A4 04 00 05 73 68 61 72 31
<<< 90 00
>>> B0 00 00 00 00
<<< 90 00
>>> B0 10 00 00 00
<<< 6F 22 (SecurityException)
Any ideas how to resolve the SecurityException ?

tay00000
Posts: 141
Joined: Tue Sep 27, 2016 10:58 am
Points :1888
Contact:

Re: How to get object working over Shareable Interface

Post by tay00000 » Tue Apr 30, 2019 2:54 am

Solved by passing the output byte array using the APDU buffer.

Why does the APDU buffer work ? Because it is the default global byte array buffer that is allowed to cross between the applet firewall by the JCRE and thus is a natural candidate. APDU buffer also has the advantage of the JCRE automatically clearing it's memory to prevent "data leakages" during applet selects and APDU command handling since the APDU buffer might contain sensitive PIN or key material while being used to transport data between the applet firewall. The automated memory clearing feature done by the JCRE on the APDU buffer makes it a primary choice not just security wise to lessen data leakages but also as a simple way of communicating via Shareable and between firewalled applets.

Post Reply Previous topicNext topic

Who is online

Users browsing this forum: No registered users and 5 guests

JavaCard OS : Disclaimer