Default selected applet doesn't return right value

血红的双手。 提交于 2020-01-07 08:47:06

问题


I wanted to answer this question so I wrote the below program:

package test;

import javacard.framework.APDU;
import javacard.framework.ISO7816;
import javacard.framework.Applet;
import javacard.framework.ISOException;
import javacard.framework.Util;

public class Test extends Applet {

    public static final byte[] res = { (byte) 0x00, (byte) 0x00, (byte) 0x3B,
            (byte) 0xAD, (byte) 0x3F, (byte) 0x00, (byte) 0x01, (byte) 0x00,
            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x16,
            (byte) 0xB3, (byte) 0x03, (byte) 0x06, (byte) 0x04, (byte) 0x00,
            (byte) 0x83, (byte) 0x8A, (byte) 0x83, (byte) 0x8A, (byte) 0x00,
            (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x3B, (byte) 0xAD,
            (byte) 0x00, (byte) 0x00, (byte) 0x3B, (byte) 0xAD, (byte) 0x2F,
            (byte) 0x06, (byte) 0x02 };

    public static void install(byte[] bArray, short bOffset, byte bLength) {
        new test.Test()
                .register(bArray, (short) (bOffset + 1), bArray[bOffset]);
    }

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

        byte[] buf = apdu.getBuffer();

        if (buf[ISO7816.OFFSET_CLA] == 0xA0 && buf[ISO7816.OFFSET_INS] == 0xA4 && buf[ISO7816.OFFSET_P1] == 0x00 && buf[ISO7816.OFFSET_P2] == 0x00
                && buf[ISO7816.OFFSET_LC] == 0x02 && buf[ISO7816.OFFSET_LC+1] == 0x7F && buf[ISO7816.OFFSET_LC+2] == 0x20) {
            ISOException.throwIt((short) 0x9F23);
        } else if (buf[ISO7816.OFFSET_CLA] == 0xA0 && buf[ISO7816.OFFSET_INS] == 0xC0 && buf[ISO7816.OFFSET_P1] == 0x00
                && buf[ISO7816.OFFSET_P2] == 0x00 && buf[ISO7816.OFFSET_EXT_CDATA] == 0x23) {
            Util.arrayCopyNonAtomic(res, (short)0, buf, (short)0, (short)35);
            apdu.setOutgoingAndSend((short)0, (short)35);

        }
                else
                    ISOException.throwIt((short)0x9090);
    }
}

And install it as default selected using GlobalPlatformPro tool:

CMD> gp -install e:\soq.cap -default

CMD>

Well, now, I expect to have the following communication :

>> in: 0xA0 A4 00 00 02 7F 20 
<< out: 0x9F 23 
>> in : 0xA0 C0 00 00 23 
<< out: 0x00 00 3B AD 3F 00 01 00 00 00 00 00 16 B3 03 06 04 00 83 8A 83 8A 00 03 00 00 3B AD 00 00 3B AD 2F 06 02

But in real, I have the below communication using OpenSC :

CMD> OSC.exe -s A0A40000027F20 -s a0c0000023
Using reader with a card: ACS CCID USB Reader 0
Sending: A0 A4 00 00 02 7F 20
Received (SW1=0x90, SW2=0x90)
Sending: A0 C0 00 00 23
Received (SW1=0x90, SW2=0x90)

Update:

As dear @Vojta said in his answer, I cast the constants to bytes as below :

//.
//. These parts didn't changed
//.

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

    byte[] buf = apdu.getBuffer();

    if (buf[ISO7816.OFFSET_CLA] == (byte)0xA0 && buf[ISO7816.OFFSET_INS] == (byte) 0xA4 && buf[ISO7816.OFFSET_P1] == (byte) 0x00&& buf[ISO7816.OFFSET_P2] == (byte) 0x00 
            && buf[ISO7816.OFFSET_LC] == (byte) 0x02 && buf[ISO7816.OFFSET_LC + 1] == (byte) 0x7F  && buf[ISO7816.OFFSET_LC + 2] == (byte) 0x20) {
        ISOException.throwIt((short) 0x9F23);
    } else if (buf[ISO7816.OFFSET_CLA] == (byte) 0xA0 && buf[ISO7816.OFFSET_INS] == (byte) 0xC0  && buf[ISO7816.OFFSET_P1] == (byte) 0x00 
            && buf[ISO7816.OFFSET_P2] == (byte) 0x00  && buf[ISO7816.OFFSET_EXT_CDATA] == (byte) 0x23 ) {
        Util.arrayCopyNonAtomic(res, (short) 0, buf, (short) 0, (short) 35);
        apdu.setOutgoingAndSend((short) 0, (short) 35);

    } else {
        ISOException.throwIt((short) 0x9090);
    }

//.
//. These parts didn't changed
//.

After installing the above applet as default selected applet, I receive the following reslts:

CommandLine> OSC.exe -s A0A40000027F20 -s a0c0000023
Using reader with a card: ACS CCID USB Reader 0
Sending: A0 A4 00 00 02 7F 20
Received (SW1=0x9F, SW2=0x23)
Sending: A0 C0 00 00 23
Received (SW1=0x90, SW2=0x90)

Well, as you see above, I receive the correct answer for first APDU command, but the answer of second APDU command is not as we expected.

I modify the second comparison section as below :

//.
//. These parts didn't changed
//.

else if (buf[ISO7816.OFFSET_CLA] == (byte) 0xA0 && buf[ISO7816.OFFSET_INS] == (byte) 0xC0  && buf[ISO7816.OFFSET_P1] == (byte) 0x00 
                && buf[ISO7816.OFFSET_P2] == (byte) 0x00  && buf[ISO7816.OFFSET_P2+1] == (byte) 0x23 ) { 

//.
//. These parts didn't changed
//.

Well, as you see I replaced buf[ISO7816.OFFSET_EXT_CDATA] with buf[ISO7816.OFFSET_P2+1], and now it works as I wanted:

CommandLine> OSC.exe -s A0A40000027F20 -s a0c0000023
Using reader with a card: ACS CCID USB Reader 0
Sending: A0 A4 00 00 02 7F 20
Received (SW1=0x9F, SW2=0x23)
Sending: A0 C0 00 00 23
Received (SW1=0x90, SW2=0x00):
00 00 3B AD 3F 00 01 00 00 00 00 00 16 B3 03 06 ..;.?...........
04 00 83 8A 83 8A 00 03 00 00 3B AD 00 00 3B AD ..........;...;.
2F 06 02                                        /..

I don't have any idea why I must use ISO7816.OFFSET_P2+1 instead of ISO7816.OFFSET_EXT_CDATA! I was thought 0x23 in the A0C0000023 APDU command, must consider as Le!(And not Lc).


回答1:


A0 and A4 are values greater than 128. Java Card bytes are signed, unfortunately. You have to cast your short constants to bytes before comparison.



来源:https://stackoverflow.com/questions/31424648/default-selected-applet-doesnt-return-right-value

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!