CAP转换器失败,带有不支持的int类型的中间值,必须将值转换为short或byte'

时间:2017-04-09 17:12:02

标签: java applet smartcard javacard apdu

我非常接近最终使用命令行为JCDK 2.2.2创建CAP文件。我首先将源文件Transfer.java编译成类文件Transfer.class,然后尝试生成CAP文件。一切都很好,除了我得到错误

  

错误:第56行:smartTransfer.Transfer:不支持int类型的中间值,必须将中间值转换为short或byte类型。

尝试从类文件构建Java Card小程序时,从CAP转换器工具

。我不知道这个错误来自何处,因此无法将值分配给字节或短。

我记得当我使用JCDK 3.0.5安装Eclipse Neon时,有一个未知位置的int错误,但applet仍在运行。我想由于我的系统上的JRE。

这是我的applet代码:

package smartTransfer;
import javacard.framework.*;

public class Transfer extends Applet {
final static byte CLASS = (byte) 0x80;
final static byte WRITE_USER_INFO_INS = 0x07;
final static byte WRITEIT_USER_INFO_INS = 0x08;
final static byte READ_USER_INFO_INS = 0x09;
final static byte READIT_USER_INFO_INS = 0x06;
final static byte SIZE_MEMORY = (short) 127;
static byte[] memory;
static byte[] memoryy;

public static void install(byte[] bArray, short bOffset, byte bLength) throws ISOException {
    new Transfer().register();
    memory = new byte[SIZE_MEMORY];
    memoryy = new byte[SIZE_MEMORY];
}

public void process(APDU apdu)
throws ISOException {
    if (selectingApplet()) return;
    byte[] buffer = apdu.getBuffer();
    if (buffer[ISO7816.OFFSET_CLA] !=CLASS) {
        ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
    }
    byte ins = buffer[ISO7816.OFFSET_INS];
    switch (ins) {
    case READ_USER_INFO_INS:
        readUserInfo(apdu);
        break;
    case READIT_USER_INFO_INS:
        readitUserInfo(apdu);
        break;
    case WRITE_USER_INFO_INS:
        writeUserInfo(apdu);
        break;
    case WRITEIT_USER_INFO_INS:
        writeitUserInfo(apdu);
    default:
        ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
    }
}

private void writeUserInfo(APDU apdu) {
    byte[] cmd_apdu = apdu.getBuffer();
    if (cmd_apdu[ISO7816.OFFSET_P1] != 0x00) 
        ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
    short offset = (short) (cmd_apdu[ISO7816.OFFSET_P2] & 0x00FF);
    if (offset >= SIZE_MEMORY) 
        ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
    short lc = (short)(cmd_apdu[ISO7816.OFFSET_LC] & 0x00FF);
    if ((offset + lc) > SIZE_MEMORY) 
        ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
    if (lc == 0x00) 
        ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
    getAPDUBody(apdu);    
        Util.arrayCopy(cmd_apdu, (short)((ISO7816.OFFSET_CDATA) & 0x00FF), 
                memory, offset, lc);
        ISOException.throwIt(ISO7816.SW_NO_ERROR); 
     }

public void getAPDUBody(APDU apdu) {
    byte[] buffer = apdu.getBuffer();
    short lc = (short)(buffer[ISO7816.OFFSET_LC] & 0x00FF); 
    if (lc != apdu.setIncomingAndReceive()) 
        ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}  

private void readUserInfo(APDU apdu) {
    byte[] cmd_apdu = apdu.getBuffer();
    if (cmd_apdu[ISO7816.OFFSET_P1] != 0x00) ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
    short offset = (short) (cmd_apdu[ISO7816.OFFSET_P2] & 0x00FF); 
    if (offset >= SIZE_MEMORY) ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
    short le = (short)(cmd_apdu[ISO7816.OFFSET_LC] & 0x00FF);
    if (le == 0x00) le = (short)(SIZE_MEMORY - offset);
    if ((offset + le) > SIZE_MEMORY) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
    apdu.setOutgoing(); 
    apdu.setOutgoingLength((short)le);  
    apdu.sendBytesLong(memory, (short)offset, (short)le); 

}

private void writeitUserInfo(APDU apdu) {
    byte[] cmd_apdu = apdu.getBuffer();
    if (cmd_apdu[ISO7816.OFFSET_P1] != 0) 
        ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
    short offset = (short) (cmd_apdu[ISO7816.OFFSET_P2] & 0x00FF); 
    if (offset >= SIZE_MEMORY) 
        ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
    short lc = (short)(cmd_apdu[ISO7816.OFFSET_LC] & 0x00FF);
    if ((offset + lc) > SIZE_MEMORY) 
        ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
    if (lc == 0x00) 
        ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
    getAPDUBody(apdu);    
        Util.arrayCopy(cmd_apdu, (short)((ISO7816.OFFSET_CDATA) & 0x00FF), 
                memoryy, offset, lc); 
        ISOException.throwIt(ISO7816.SW_NO_ERROR); 
     }

private void readitUserInfo(APDU apdu) {
    byte[] cmd_apdu = apdu.getBuffer();
    if (cmd_apdu[ISO7816.OFFSET_P1] != 0x00) ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
    short offset = (short) (cmd_apdu[ISO7816.OFFSET_P2] & 0x00FF); 
    if (offset >= SIZE_MEMORY) ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
    short le = (short)(cmd_apdu[ISO7816.OFFSET_LC] & 0x00FF); 
    if (le == 0x00) le = (short)(SIZE_MEMORY - offset);
    if ((offset + le) > SIZE_MEMORY) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
    apdu.setOutgoing(); 
    apdu.setOutgoingLength((short)le);  
    apdu.sendBytesLong(memoryy, (short)offset, (short)le); 

  }
}

我知道错误是在第56行,但我想这将来自Transfer.class文件(我无法打开阅读),而不是源代码。但是,当读取传入的APDU报头时,我能想到的唯一未分配的中间值将是指令情况。

这个错误可能来自哪里?

1 个答案:

答案 0 :(得分:3)

错误已经清楚地告诉您源文件中包含有问题代码的行。在您的情况下,错误是由if语句

的所有行引起的
if ((offset + lc) > SIZE_MEMORY) 

在这种情况下,整数类型的中间值为offset + lc。虽然plus运算符的两个操作数都是short,但是plus运算符的结果是int。因此,您需要将此值明确地转换为简短的:

if ((short)(offset + lc) > SIZE_MEMORY) 

另请注意,常量SIZE_MEMORY应该是short类型而不是byte:

final static short SIZE_MEMORY = (short) 127;