byte
has an extensive use in applet development for Java Card. Because cards have limited resources every bit of memory is precious. By the way card processors have limitations in processing of integer values. int
type support is optional and java.lang.String
is not supported so all integer operation and data storage is done by byte
and short
variables and arrays. As integer literals are of int
type, they should be explicitly cast to byte
or short
in whole code. Communication with card goes through APDU commands that is handed to applet as an array of byte
s that should be decomposed to byte
s to decode command class, instruction and parameters. Looking at the following code you see how much byte
and short
types are important to Java Card development:
package somepackage.SomeApplet;
import javacard.framework.*;
import org.globalplatform.GPSystem;
import org.globalplatform.SecureChannel;
public class SomeApplet extends Applet {
// Card status
private final static byte ST_UNINITIALIZED = (byte) 0x01;
private final static byte ST_INITIALIZED = (byte) 0x02;
// Instructions & Classes
private final static byte PROP_CLASS = (byte) 0x80;
private final static byte INS_INIT_UPDATE = (byte) 0x50;
private final static byte INS_EXT_AUTH = (byte) 0x82;
private final static byte INS_PUT_DATA = (byte) 0xDA;
private final static byte INS_GET_RESPONSE = (byte) 0xC0;
private final static byte INS_GET_DATA = (byte) 0xCA;
private final static short SW_CARD_NOT_INITIALIZED = (short) 0x9101;
private final static short SW_CARD_ALREADY_INITIALIZED = (short) 0x9102;
private final static byte OFFSET_SENT = 0x00;
private final static byte OFFSET_RECV = 0x01;
private static short[] offset;
private static byte[] fileBuffer;
private static short fileSize = 0;
public static void install(byte[] bArray, short bOffset, byte bLength) {
new SomeApplet( bArray, bOffset, bLength);
}
public RECSApplet(byte[] bArray, short bOffset, byte bLength) {
offset = JCSystem.makeTransientShortArray((short) 2, JCSystem.CLEAR_ON_RESET);
fileBuffer = new byte[FILE_SIZE];
byte aidLen = bArray[bOffset];
if (aidLen== (byte)0){
register();
} else {
register(bArray, (short)(bOffset+1), aidLen);
}
}
public void process(APDU apdu) {
if (selectingApplet()) {
return;
}
byte[] buffer = apdu.getBuffer();
short len = apdu.setIncomingAndReceive();
byte cla = buffer[ISO7816.OFFSET_CLA];
byte ins = buffer[ISO7816.OFFSET_INS];
short lc = (short) (buffer[ISO7816.OFFSET_LC] & 0x00ff);
while (len < lc) {
len += apdu.receiveBytes(len);
}
SecureChannel sc = GPSystem.getSecureChannel();
if ((short)(cla & (short)0x80) == ISO7816.CLA_ISO7816) {
switch (ins) {
case INS_PUT_DATA:
putData(buffer, ISO7816.OFFSET_CDATA, offset[OFFSET_RECV], len);
if ((cla & 0x10) != 0x00) {
offset[OFFSET_RECV] += len;
} else {
fileSize = (short) (offset[OFFSET_RECV] + len);
offset[OFFSET_RECV] = 0;
}
return;
case INS_GET_DATA:
case INS_GET_RESPONSE:
sendData(apdu);
return;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
else if ((byte) (cla & PROP_CLASS) == PROP_CLASS) {
switch (ins) {
case INS_INIT_UPDATE:
case INS_EXT_AUTH:
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, sc.processSecurity(apdu));
return;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
} else
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
// Some code omitted
}