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

Java Card Accessing Objects over Shareable Interface

我正在尝试通过两个小程序之间的 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);
        }
    }
}

每当我 select 客户端小程序调用服务器小程序的 getArray 接口方法时,我都会从服务器小程序端收到 SecurityException。当它访问 buf1 时,我将其追溯到服务器端的 Util.arrayFillNonAtomic() 方法。我如何让 Util.arrayFillNonAtomic() 执行,因为我有兴趣在代码的后面部分将填充的 buf1 复制到 getArraybuf

I am getting SecurityException from the Server Applet side

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

在可共享接口对象的实现过程中上下文切换的概念,你可以阅读JCRE规范。

一般来说,一个对象只能被它拥有的上下文访问,也就是说,当拥有的上下文是 当前活动的上下文。防火墙防止一个对象被另一个小程序访问 不同的语境。在实现方面,每次访问对象时,都会将对象的所有者上下文(调用小程序)与 当前活动的上下文(称为小程序)。如果这些不匹配,则不执行访问并抛出 SecurityException

特别是你的情况,

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

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