APDU Data Packets
This chapter describes the methods of working with application protocol data blocks (application protocol data block, APDU) in applets. APDS are data packets. They provide an application layer communication protocol for data exchange between client applications that run on the card and host system applications. Readers who are unfamiliar with the storage protocol and the smart card communication system are advised to read Chapter 2 first, and only then proceed to study this chapter.
the mechanism of communication of applets with the Java host Card is implemented, the mechanism of communication of applets with the host system is implemented, which differs from the communication technologies of traditional Java platforms. Most of these differences are explained by the nature of the APDU protocol. Java Card technology has a javacard class.framework.APDU, which provides a powerful but simple interface for processing APDU commands by applets.
This chapter begins with an overview of the APDU class. encapsulates the contents of the command, just as JCRE encapsulates the contents of the APDU command into an object of the APDU type and passes it to the applet. Then the methodology of processing RF commands by an applet using the warehouse class will be considered: receiving a command, interpreting and executing it, and finally sending a response message to the host system. In conclusion, a brief summary of the methods for processing all four types of ADF commands using the ADF class will be given.
APDU
defined in the APDU programming interfaces, provides a powerful and flexible package processing mechanism Java Card, provides a powerful and flexible package processing mechanism APDU. The structure of the AIU AIU command and response is defined in the ISO 7816-4 specification. The host system and the card exchange disk packets using a low-level transport protocol. Two transport protocols are most often used: protocol T=0 and protocol T=1.
In most legacy smart card systems, there is no clear separation of functions between the card’s operating system and client applications. Applications need to know the protocol that is used in the system where they are installed. But the Java card technology defines the APDU class, which allows you to reliably hide from applet developers the details of the implementation of the T=0 and T=1 protocols, as well as the differences between them. In other words, if you use the warehouse class of applets during development, they will work correctly, regardless of which transport protocol the system uses – T=0 or T=1.
oriented command processing tools APDU also provides object-oriented command processing tools APDU. The applets receive and send the APDU packets using calls to the methods of the APDU class. Therefore, applet developers can focus on organizing the processing of the contents of the ADF messages and not think about the intricacies of their structure and transmission.
APDU Object
As discussed in the previous chapter, applets do not communicate directly with host applications. which organizes communication with the JCRE host, which organizes communication with the host system via a serial I/O interface. JCRE creates an APDU object, an instance of the APDU class. This object has an internal byte array in which the APDU, in which JCRE puts the APDU message.
Java card object An APDU object can be considered a communication object. from the host APDU from the host- writes its header to the buffer, JCRE writes its header to the APDU buffer. Then it calls the method in the process of the currently active applet and passes it the warehouse object via the method parameter. In the header method, the process is analyzed by the warehouse. If the received command contains data, the applet can use the methods of the object today to get them. If, after processing the command, the applet has to send data to the host application, it again uses the methods of the APDU object for this. The response data is also written to the APDU buffer. The JCRE system sends an APDU response to the host system.
APDU buffer size
To ensure compatibility between different implementations of the Java card platform, the minimum length of the APDU buffer is 37 bytes. This is the sum of the header length (5 bytes) and the minimum length of the data field for the card (the size of the information field on the card, IFSC). Smart cards that have a larger amount of memory can work with a larger disk buffer.
The COMFU value is defined in the ISO 7816-3 specification for the T=1 protocol. But why does the minimum disk buffer size depend on the default RAM size? when we discuss the processing of 8.4 packets, when we discuss the processing of APDU packets from the point of view of protocols.
The ISO7816 interface is defined in the Java card platform API. It contains a set of common constants relevant to the ISO 7816-3 and ISO 7816-4 specifications. The ISO7816 interface constants can be divided into three groups:
- Constants that determine the offset of various fields of the command header relative to the beginning of the APDU buffer. Such constants begin with the OFFSET prefix. constant, the OFFSET_CLA constant defines the offset of the CLA byte relative to the beginning of the APDU buffer. Applets use these constants to access the APDU command header.
- Status response words defined in the ISO 7816-4 specification. These constants start with the prefix SW. The list of these constants contains the most commonly used state words defined in the ISO 7816-4 specification. The status word is a mandatory field of the APDU response. All constants corresponding to the state words are of type short (2 bytes).
- ENTRANCES TO THE CLASSROOM. The ISO7816 interface also has byte constants that define the encoding of CIA bytes and modules in the commands for selecting disks and external disks, as well as authentication in accordance with the ISO 7816-4 specification.
The “APDU” process. The step-by-step processing sequence is described below. When discussing each step, the methods of the APDU class and how to use them will be considered.
Getting a reference to the APDU buffer
Before processing the APDU command, the applet receives a reference to the APDU buffer using the GetBuffer method. this is an APDU byte array – this is a byte array whose length is contained in the apdu_buffer field.length.
public cancellation Process (APDU apdu) {
// Getting a reference to the APDU
byte buffer[] apdu_buffer = apdu.GetBuffer();
}
Note that, in accordance with JCRE requirements, references to the warehouse object or references to the warehouse buffer cannot be stored in class variables, instance variables, or array elements. The applet should store these references only in local variables and method parameters, which are temporary data in the scope of the method. This requirement is caused by security reasons, because it is necessary to ensure the unavailability of these disks as well as for other applets. Global arrays are considered there, as well as temporary objects that are entry points to JCRE.
Checking the APDU command header
When calling the applet method, only the first 5 bytes of the APDU buffer are available to the process. and the fifth byte is the APDU header (fields CLA, INS, P1, P2), and the fifth byte (P3) is the length of the additional data field. The value of P3 depends on the type of command:
· For type 1, P3 = 0.
· For type 2 P3 = Le, i.e. the length of the data field of the outgoing response message.
· For types 3 and 4, P3 = Lc, i.e. the length of the data field of the incoming command.
The remaining bytes of the buffer are undefined and should not be read or written by the applet.
When the applet receives a reference to the RF buffer, it must first analyze the command header to check the correctness of its format and determine whether it can be executed:
· The command format is correct – all header bytes are encoded correctly.
· The command can be executed – the command is supported by the applet, the internal state of the applet and the security conditions meet the requirements of the command.
If during the check it turns out that the necessary criteria are not met, the applet must interrupt processing and raise an ISOException exception.
The constants defined in the iso7816 interface should be used as
indexes in the storage buffer to access the header bytes (Table 8.1). the next code fragment checks the byte, the next code fragment checks the CLA byte:
if (apdu_buffer[ISO7816.OFFSET_CLA] != EXPECTED VALUE) {
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
The use of constant names makes the applet code more readable.
Extracting data from the APDU command
The APDU contains not only the instructions [CLA, INS, P1, P2] that the applet must execute. It also defines the structure (type) of the RF block – both the command and the response. If the command is of type 3 or 4, then in addition to the instructions, it contains input data. The Lc field (the fifth byte of the APDU buffer) stores the length of the data block.
short data length = (short)(apdu_buffer[ISO7816.OFFSET_LC] & 0xFF);
Integer data types in the Java language and have a sign that is stored in the highest digit. However, the value of the LNR field must be interpreted as an unsigned number, since the length cannot be negative. In the above code fragment, the Lc byte is logically multiplied bitwise by the constant 0xFF in order to convert a signed value to an unsigned value.
To read data into the APDU buffer, the applet calls the Set incoming and receiving method of the APDU class:
public short setIncomingAndReceive() throws an APDUException
APDU
(5)
The APDU buffer after executing the setIncomingAndReceive method
As the name suggests, the setIncomingAndReceive method is designed to perform two tasks: first, it puts JCRE into data reception mode. Data exchange between the host system and the smart card takes place in half-duplex mode. This means that at any given time, data is transmitted either from the host system to the card, or from the card to the host system. Simultaneous transmission in both directions is not possible. At the first stage of execution, the method informs JCRE that the Lc field should be regarded as the length of the expected data, and JCRE goes into receive mode. Then the setIncomingAndReceive method requests JCRE to receive incoming data into the APDU buffer, starting from the offset ISO7816.OFFSET_DATA (=5), i.e. immediately after the header
The setIncomingAndReceive method returns the number of bytes received. If the return value is 0, then the data is unavailable. If, when calling the setIncomingAndReceive method, JCRE is already in the receiving state as a result of a previous call to the same method, an exception is raised with the cause code APDUException.ILLEGAL_USE.
Getting large blocks of data
In most cases, the number of bytes specified in the Lc field does not exceed the length of the APDU buffer, so it is enough to call the setIncomingAndReceive method to receive. But there are APDU commands that contain more data than can fit into the APDU buffer. In such cases, after calling the setIncomingAndReceive method, it is necessary to call the receiveBytes method one or more times:
public short receiveBytes(short bOff) throws APDUException
If the APDU command contains a large amount of data, the applet can process this data in parts. To load the next portions of data into the APDU buffer, the receiveBytes method is used. The argument of the receiveBytes method is the offset in the APDU buffer, starting from which data will be written. This feature allows the applet to determine which buffer area incoming data should be loaded into. For example, as shown in Figure 8.2, an applet can buffer data from a previous call to the setIncomingAndReceive method and load a new portion of data using the receiveBytes method – with the exception of a few bytes.
The applet can move these bytes to the beginning of the buffer, and then read the next group in such a way that it is added to the bytes that are already in the buffer. This feature is very useful in situations where data read by two different methods must be processed as a whole.
Similar to the setIncomingAndReceive method, the receiveBytes method always loads as much data into the buffer as possible. However, depending on the number of bytes sent by the host system in a single packet, as well as depending on the JCRE implementation, both methods may read fewer bytes than are available in the APDU buffer.
Usually the setIncomingAndReceive and receiveBytes methods are optimized. If the data from the command is placed in the APDU buffer starting from the offset ISO7816.OFFSET_CDATA (=5), one call of the setIncomingAndReceive method is enough to read all the data. In this case, no additional calls to the receiveBytes method are needed. Most APDU teams fall into this category.
If it is necessary to read more data than the APDU buffer size allows, the applet must call the receiveBytes method. If the free buffer space, starting from the specified offset, is sufficient to receive the remaining bytes, the receiveBytes method is guaranteed to count all remaining data. Otherwise, the method reads as much data as it can fit into the buffer, or less. The applet must repeatedly call receiveBytes, process the received bytes, or transfer them from the APDU buffer after each call until all data from the command is read. In this example, the receiveBytes method is called in a while loop:
public void process(APDU apdu) {
byte[] apdu_buffer = apdu.GetBuffer();
short total_bytes = (short)(apdu_buffer[ISO7816.OFFSET_LC] & 0xFF);
// reading data to the APDU buffer
short read_count = apdu.setIncomingAndReceive();
// calculate the number of remaining bytes
short bytes_left = (short) (total_bytes read_count); while (true) {
// processing data in the buffer or copying data
// to the internal buffer
// …
// is all data accepted?
// if yes, exit the loop
if (bytes_left <= 0) break;
// if not all data is received, the next portion is read
read_count = apdu.receiveBytes((short)0);
bytes_left -= read_count;
}
// performing other tasks and forming a response to the host application
// …
}