1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
package org.dogtagpki.javacard;
import javacard.framework.*;
/**
* @author Endi Sukma Dewata
*/
public class TestApplet extends Applet implements MultiSelectable, TestShareable {
private final static byte SAY_HELLO_INS = (byte) 0x01;
private final static byte SAY_ECHO2_INS = (byte) 0x03;
private final static byte SAY_IPARAMS_INS = (byte) 0x04;
private final static byte NOP_INS = (byte) 0x02;
private static byte[] helloMessage = new byte[] {
'T', 'e', 's', 't',
'A', 'p', 'p', 'l', 'e', 't'
};
private byte[] echoBytes;
private byte[] initParamsBytes;
private static final short LENGTH_ECHO_BYTES = 256;
protected TestApplet(byte[] bArray, short bOffset, byte bLength) {
echoBytes = new byte[LENGTH_ECHO_BYTES];
if (bLength > 0) {
byte iLen = bArray[bOffset]; // aid length
bOffset = (short) (bOffset + iLen + 1);
byte cLen = bArray[bOffset]; // info length
bOffset = (short) (bOffset + cLen + 1);
byte aLen = bArray[bOffset]; // applet data length
initParamsBytes = new byte[aLen];
Util.arrayCopyNonAtomic(bArray, (short) (bOffset + 1), initParamsBytes, (short) 0, aLen);
}
register();
}
public static void install(byte[] bArray, short bOffset, byte bLength)
throws ISOException {
new TestApplet(bArray, bOffset,bLength);
}
public void process(APDU apdu) {
if(selectingApplet()) return;
byte[] buffer = apdu.getBuffer();
switch (buffer[ISO7816.OFFSET_INS]) {
case SAY_HELLO_INS:
sayHello(apdu);
return;
case SAY_ECHO2_INS:
sayEcho2(apdu);
return;
case SAY_IPARAMS_INS:
sayIParams(apdu);
return;
case NOP_INS:
return;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
return;
}
private void sayHello(APDU apdu) {
byte[] buffer = apdu.getBuffer();
short incomeBytes = apdu.setIncomingAndReceive();
byte[] echo;
if (buffer[ISO7816.OFFSET_P1] == 0x01) {
echo = JCSystem.makeTransientByteArray(incomeBytes, JCSystem.CLEAR_ON_RESET);
Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, echo, (short) 0, incomeBytes);
} else {
echo = JCSystem.makeTransientByteArray((short) helloMessage.length, JCSystem.CLEAR_ON_RESET);
Util.arrayCopyNonAtomic(helloMessage, (short) 0, echo, (short) 0, (short) helloMessage.length);
}
apdu.setOutgoing();
apdu.setOutgoingLength((short) echo.length);
apdu.sendBytesLong(echo, (short) 0, (short) echo.length);
}
private void sayEcho2(APDU apdu) {
byte buffer[] = apdu.getBuffer();
short bytesRead = apdu.setIncomingAndReceive();
short echoOffset = (short) 0;
while (bytesRead > 0) {
Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, echoBytes, echoOffset, bytesRead);
echoOffset += bytesRead;
bytesRead = apdu.receiveBytes(ISO7816.OFFSET_CDATA);
}
apdu.setOutgoing();
apdu.setOutgoingLength((short) (echoOffset + 5));
apdu.sendBytes((short) 0, (short) 5);
apdu.sendBytesLong(echoBytes, (short) 0, echoOffset);
}
public void sayIParams(APDU apdu) {
apdu.setOutgoing();
apdu.setOutgoingLength((short)initParamsBytes.length);
apdu.sendBytesLong(initParamsBytes, (short) 0, (short)initParamsBytes.length);
}
public boolean select(boolean b) {
return true;
}
public void deselect(boolean b) {
}
}
|