问题
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