Java卡通过共享接口访问对象

时间:2018-12-21 09:25:10

标签: javacard

我试图通过两个小程序之间的Java卡中的可共享接口访问对象。

服务器小程序代码:

package Wallet;

public class Wallet extends Applet implements IShareable {

    public static byte[] buf1 = JCSystem.makeTransientByteArray((short) 258, JCSystem.CLEAR_ON_DESELECT);

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

    protected Wallet() {
        register();
    }

    public Shareable getShareableInterfaceObject(AID clientAID, byte parameter) {
        return this;
    }

    public short getArray(byte[] buf, short off, short len) {
        Util.arrayCopyNonAtomic(testArray, (short)0, buf, off, (short) 5);
        Util.arrayFillNonAtomic(buf1, (short) 0, (short) buf1.length, (byte) 0xAA); // <---- This is causing SecurityException
        return len;
    }

    public void process(APDU apdu) { ...... }

}

界面:

package Wallet;

import javacard.framework.*;

public interface IShareable extends Shareable {

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

}

客户端小程序代码:

package Test222;

import Wallet.IShareable;
import javacard.framework.*;

public class Test222 extends Applet {

    public AID appID = new AID(
            new byte[]{
                (byte) 0x54, (byte) 0x54, (byte) 0x54, (byte) 0x54, (byte) 0x54, (byte) 0x00
            },
            (short) 0,
            (byte) 6);
    public IShareable shared = null;
    public short[] sb1 = JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_DESELECT);

    /**
     * Installs this applet.
     *
     * @param bArray
     * the array containing installation parameters
     * @param bOffset
     * the starting offset in bArray
     * @param bLength
     * the length in bytes of the parameter data in bArray
     */
    public static void install(byte[] bArray, short bOffset, byte bLength) {
        new Test222();
    }

    /**
     * Only this class's install method should create the applet object.
     */
    protected Test222() {
        register();
    }

    /**
     * Processes an incoming APDU.
     *
     * @see APDU
     * @param apdu
     * the incoming APDU
     */
    public void process(APDU apdu) {
        if (selectingApplet()) {
            return;
        }

        byte[] buffer = apdu.getBuffer();

        if ((buffer[ISO7816.OFFSET_CLA] == (byte) 0xB0) && (buffer[ISO7816.OFFSET_INS] == (byte) 0x10)) {
            try {
                shared = (IShareable) JCSystem.getAppletShareableInterfaceObject(appAID, (byte) 0);
                if (shared != null) {
                    sb1[0] = shared.getArray(buffer, (short) 0, (short) 5);
                    apdu.setOutgoing();
                    apdu.setOutgoingLength(sb1[0]);
                    apdu.sendBytesLong(buffer, (short) 0, sb1[0]);
                } else {
                    ISOException.throwIt(ISO7816.SW_APPLET_SELECT_FAILED);
                }
            } catch (ClassCastException e) {
                ISOException.throwIt(ISO7816.SW_DATA_INVALID);
            }
        } else {
            ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
        }
    }
}

每当我选择客户端小程序来调用服务器小程序的getArray接口方法时,都会从服务器小程序一侧获取SecurityException。当它访问Util.arrayFillNonAtomic()时,我将其追溯到服务器端的buf1方法。我有兴趣在代码的后半部分将填充的Util.arrayFillNonAtomic()复制到buf1的{​​{1}}的情况下,如何执行getArray

1 个答案:

答案 0 :(得分:4)

  

我从服务器Applet端收到SecurityException

由于调用上下文(服务器小程序)或活动上下文对对象的无效访问(SecurityException),引发了buf1。这是根据JCRE规范中定义的防火墙强制执行的对象访问规则进行的。 https://docs.oracle.com/javacard/3.0.5/JCCRE/JCCRE.pdf

您可以阅读JCRE规范,了解在实现可共享接口对象期间进行上下文切换的概念。

通常,对象只能由其拥有的上下文访问,即,当拥有的上下文是 当前活动的上下文。防火墙可防止对象被另一个小程序访问。 不同的上下文。用实现的术语来说,每次访问对象时,都会将该对象的所有者上下文(称为applet)与 当前活动的上下文(称为applet)。如果这些不匹配,则不执行访问,并引发SecurityException

特别是在您的情况下,

CLEAR_ON_DESELECT类型的瞬态对象只能在当前 活动上下文是当前所选小程序的上下文。这里不是这种情况,因为活动上下文是服务器小程序的上下文,而当前选择的小程序是客户端小程序

但是,您可以将buf1更改为CLEAR_ON_RESET类型的瞬态数组,因为它们在某种意义上可以像持久对象一样工作 当当前活动上下文(客户端小程序)是对象拥有的上下文(客户端小程序)时访问。