Chapter 7. Java Card Applets

Applications running on Java smart cards are called applets. This chapter introduces the framework for writing applets. It is organized into seven sections. The first section provides an overall picture of how applets work within the JCRE. The remaining sections discuss the techniques of applet writing.

Applet features are described in more detail throughout the book. Chapters 8 and 9, for example, discuss APDU command handling and object sharing among applets.

Applet Overview

A Java Card applet is a smart card application written in the Java programming language and conforming to a set of conventions so that it can run within the Java Card runtime environment (JCRE). A running applet in the JCRE is an instance of the applet class that extends from javacard.framework.Applet. As with other persistent objects, an applet created on the card lives on through the entire lifetime of the card.[1] The Java Card platform supports a multiapplication environment. Each applet instance is uniquely identified by an AID (see Chapter 3 for more details on AIDs).

Applet Installation and Execution

After the package(s) defining an applet have been properly loaded on a Java smart card and linked with other packages on the card, an applet's life starts when an instance of the applet is created and registered with the JCRE. The JCRE is a single-thread environment. This means that only one applet is running at a time. When an applet is first installed, it is in an inactive state. The applet becomes active when it is explicitly selected by a host application.

Applets, like any smart card applications, are reactive applications. Once selected, a typical applet waits for an application running on the host side to send a command. The applet then executes the command and returns a response to the host.

This command-and-response dialogue continues until a new applet is selected or the card is removed from the card acceptance device. The applet remains inactive until the next time it is selected. Applet execution states are illustrated in Figure 7.1.

Applet execution states

Figure 7.1. Applet execution states

Applet Communication

The communication between an applet and a host application is achieved through exchanging APDUs, as illustrated in Figure 7.2. An APDU contains either a command or a response message. A host application sends a command to an applet and the applet returns a response. (See chapter 2 for more information on APDUs.)

Applet communication

Figure 7.2. Applet communication

When the host application wants to select an applet to run, it sends an APDU that specifies the SELECT command and the AID of the requested applet. The JCRE searches its internal table for an applet whose AID matches the one specified in the command. If a match is found, the JCRE selects that applet to run. All subsequent APDUs (including the SELECT APDU) are forwarded to the current applet until a new applet is selected.

Class javacard.framework.Applet

Every applet is implemented by creating a subclass of the class javacard.framework.Applet. The JCRE invokes the methods install, select, process, or deselect, which are defined in the base Applet class, when it wants to install, select, or deselect the applet or to ask the applet to process an APDU command.

Methods in Table 7.1 are listed in the order in which they are invoked by the JCRE during applet creation and execution. The JCRE calls the install method to create an applet instance. The applet instance is registered with the JCRE, using one of the two register methods.

Table 7.1. Methods in the class javacard.framework.Applet

public static void

install (byte[] bArray, short bOffset, byte bLength)

The JCRE calls this static method to create an instance of the Applet subclass.

protected final void

register()

This method is used by the applet to register this applet instance with the JCRE and to assign the default AID in the CAP file to the applet instance.

protected final void

register (byte[] bArray, short bOffset, byte bLength)

This method is used by the applet to register this applet instance with the JCRE and to assign to the applet instance the AID specified in the array bArray.

public boolean

select ()

The JCRE calls this method to inform the applet that it has been selected.

public abstract void

process (APDU apdu)

This JCRE calls this method to instruct the applet to process an incoming APDU command.

public void

deselect ()

The JCRE calls this method to inform the currently selected applet that another (or the same) applet will be selected.

When receiving a SELECT APDU, the JCRE first checks whether an applet is already selected. If so, the JCRE deselects the current applet by invoking the deselect method. In the deselect method, the applet performs any cleanup or bookkeeping work before it becomes inactive. Then the JCRE selects the new applet by invoking the select method. The applet performs any initialization necessary in the select method.

After successful selection, each APDU (including the SELECT APDU) is delivered to the active applet via a call to its process method. The process method is an essential method in the applet class. It processes APDU commands and thus provides an applet's functions.

The methods install, select, deselect, and process are applet entry point methods. They are invoked by the JCRE at the appropriate state of applet creation and execution. The base Applet class provides only the default behavior for these methods. An applet needs to override some or all of these methods to implement its functions. The details of each of these methods are specified in the remainder of this chapter.

install Method

The install method is typically called by the JCRE as the last step during applet installation to create an applet instance-a runnable applet (applet installation is discussed in chapter 3). The install method is similar to the main method in a Java application. The arguments to the install method carry the applet installation parameters. They are analogous to command-line arguments supplied to the main method.

The install method creates an applet instance by using the new operator followed by a call to the applet's constructor. In the constructor, an applet typically performs the following tasks:

  • Creates objects that the applet needs during its lifetime

  • Initializes objects and the applet's internal variables

  • Registeres the applet instance with the JCRE by calling one of the two register methods defined in the base Applet class

Applet registration marks the beginning of the applet's lifetime. An applet must register with the JCRE so that it can be selected and set to run by the JCRE.

The following code shows an example of creating a wallet applet by using the default constructor.

public class WalletApp extends Applet{

   private Log transaction_log;
   private byte[] wallet_id;
   private byte wallet_balance;

   public static void install
          (byte[] bArray, short bOffset, byte bLength) {

      new WalletApp();
   }

private WalletApp() {

    // create a transaction log with the specified number
    // of transaction records
    transaction_log = new Log(TRAN_RECORD_NUM);

    // create a byte array to store the wallet ID
    wallet_id = new byte[ID_LENGTH];

    // initialize the wallet balance
    wallet_balance = INITIAL_BALANCE;

    // register the applet instance with the JCRE
register();
   }
}

Alternatively, an applet can define a constructor that takes the installation parameters.

public walletApp(byte[] bArray, short bOffset, byte bLength) {...}

The installation parameters provide additional data for initializing and personalizing the applet. Processing the installation parameters is explained in Section 7.3.3.

On successful return from the install method, the applet is ready to be selected and to process the upcoming APDU commands. Only one instance of an applet can be successfully created and registered from one invocation of the install method. If the JCRE wants to create multiple instances of the same applet, each instance is created with a separate invocation of the install method.

If a failure occurs during the install method and prior to the successful invocation of the register method, the JCRE will perform necessary cleanup to reclaim the card resources when it gets back control. The JCRE deletes the applet instance as well as the other objects created during the install method and recovers the previous JCRE state. It is not necessary to set up a transaction in the install method, since the JCRE ensures that the install method is transactional. Applet registration signals the successful end of the transaction. Therefore, it is important to register the applet as the last step during applet creation. If any error occurs after the register method, the applet will remain registered but might be left in a crippled state.

Notice that the install method in the base Applet class is simply a prototype. An applet must define an install method of the same prototype.

Creating Objects in the Applet's Constructor

Although objects and arrays can be created at any point in the execution of an applet, it is recommended that, when possible, such allocations occur only during the initialization of the applet. Any objects that might be required during execution of an applet should be preallocated in the constructor, to ensure that the applet will never fail due to lack of memory.

The constructor is invoked inside the install method. Thus, if the JCRE detects resource shortage and is unable to allocate memory space for the applet during object creation or during some other resource allocation processing, the JCRE will delete the applet and reclaim all memory space. In this way, no partially created applet will be left behind in an unrunnable state.

However, an applet should not create more objects than it needs, since the memory occupied by unused objects cannot be reused or shared by other applets or the JCRE.

Registering the Applet Instance with the JCRE

To register an applet with the JCRE, you use one of the two register methods provided in the base Applet class.

protected final void register()

or

protected final void register
          (byte[] bArray, short bOffset, byte bLength)

The register method has two functions. First, it stores a reference to the applet instance with the JCRE. Second, it assigns an AID to the applet instance. Recall from Chapter 3 that each applet instance on the card is uniquely identified by an AID. The CAP file that defines the applet classes contains a default AID. However, an applet may choose to have an AID different from the default one. The default AID can be supplied in the installation parameters.

The first register method (the one with no arguments) registers the applet with the JCRE using the default AID from the CAP file. The second register method (with arguments) registers the applet instance with the JCRE using the AID specified in the argument bArray. The argument bOffset specifies the starting offset in bArray, and bLength specifies the AID length in bytes.

Processing the Installation Parameters

Typically, during applet installation, the installation parameters are sent to the card along with the CAP files that define an applet. The JCRE then provides the installation parameters to the applet via the arguments to the install method. The install method accepts three arguments:

  • byte[] bArray—. Array containing installation parameters

  • short bOffset—. Starting offset in bArray

  • byte bLength—. Length in bytes of the parameter data in bArray

The content and format of the installation parameters are defined by the applet designers or the card issuers. Often, they contain applet configuration parameters and applet initialization values. Configuration parameters can be used to specify the size of an internal file, an array, and so on. In this way, the applet can allocate adequate memory to support anticipated processing while avoiding memory waste. Applet initialization values, for example, can specify the initial balance, the card holder's ID, and the account number in an electronic wallet. Another common use of the installation parameters is to supply an AID other than the default one in the CAP file. For example, suppose that two wallet applet instances are needed: one for personal use and the other for business. In such a case, the JCRE must invoke the applet's install method twice. Each time, a wallet applet instance is created with a unique AID.

Suppose that the designer of the wallet applet specifies that the installation parameter byte array consist of the following fields:

  1. A 1-byte binary value specifying the number of records in the transaction log.

  2. A fixed-size array of 4 bytes specifying the wallet ID.

  3. One byte containing the initial wallet balance.

  4. One byte specifying the size of the next subarray.

  5. A variable-size array of bytes specifying the AID for this applet instance. If this array is empty, the applet uses the default AID from the CAP file.

To create a wallet applet for personal use with the default AID, the installation parameters might be the bytes [0×10, 0×1, 0×2, 0×3, 0×4, 0×32, 0], which would be interpreted by the applet as

  • number of transactions in the transaction log = 0×10 = 16

  • wallet ID = [0×1, 0×2, 0×3, 04]

  • initial balance = 0×32 = 50

  • AID = the default AID from the CAP file

To create a wallet instance to handle business expense with an AID other than the default one, the installation parameters might be the bytes [0×10, 0×4, 0×3, 0×2, 0×1, 0×64, 0×F, 'B', 'A', 'N', 'K', '_', 'w', 'a', 'l', 'l', 'e', 't', '_', 'B', 'I', 'S'], which would be interpreted by the applet as

  • number of transactions in the transaction log = 0×10 = 16

  • wallet ID = [0×4, 0×3, 0×2, 0×1]

  • initial balance = 0×64 = 100

  • AID = ['B', 'A', 'N', 'K', '_', 'w', 'a', 'l', 'l', 'e', 't', '_', 'B', 'I', 'S']

The following code demonstrates how the wallet applet processes the installation parameters in the constructor:

private WalletApp(byte[] bArray, short bOffset, byte bLength) {

   // create a transaction log and specify the maximum number
   // of log records
   // max_record_num = bArray[bOffset]
   transaction_log = new Log(bArray[bOffset++]);

   // set the wallet ID
   wallet_id = new byte[ID_LENGTH];
   Util.arrayCopy(bArray, bOffset, wallet_id, (byte)0, ID_LENGTH]);
   // advance bOffset by ID_LENGTH of bytes
   bOffset += ID_LENGTH;

   // initialize the wallet balance
   wallet_balance = bArray[bOffset++];

   // check the AID
   byte AID_len = bArray[bOffset++];
   if (AID_len == 0) {
      // register the applet instance with the JCRE
      // using the default AID
   this.register();
   } else {
      // register the applet instance with the JCRE
      // using the AID specified in the installation parameters.
      // AID bytes in the bArray start from the index bOffset
      // and consist of the AID_len number of bytes
      this.register(bArray, bOffset, AID_len);
   }
}

The content of bArray does not belong to the applet. For security reasons, the JCRE clears the array on return from the install method. If the applet desires to preserve any of these data, it should copy the data into its own object. In the example, the wallet ID bytes in bArray are copied into the field wallet_id.

The Java Card platform supports installation parameters of up to 32 bytes. Thus, the maximum value of bLength is 32. In chapter 8 you will see that the JCRE employs a buffer to transmit APDUs. The minimum size of the APDU buffer is 37, including 5 bytes of header and 32 bytes of data. The number 32 is chosen as the maximum size of the installation parameters so that they can be transported in the buffer with one APDU I/O.

Further Applet Initialization

After a successful return from the install method, simple applets might be fully ready to function in their normal role. More complex applets might need further personalization information before they are ready to execute normally. Such information might not all be available at applet creation time or might exceed the capacity of the installation parameters (32 bytes). In this case, a separate scheme (specified by applet designers or issuers) might be required to allow an applet to complete personalization in the process method. In such a scheme, the applet needs to set internal state variables and is responsible for keeping track of these state transitions. To receive personalization information, the applet exchanges APDUs with the host.

select Method

An applet remains in a suspended state until it is explicitly selected. Applet selection occurs when the JCRE receives a SELECT APDU whose data match the AID of the applet. The JCRE informs the applet of its selection by invoking its select method.

In the select method, the applet can check whether its conditions for selection have been met, and if so, it can set internal variables and states necessary to handle subsequent APDUs. The applet returns true from the call to the select method if it is ready to accept incoming APDUs via its process method, or it can decline to be selected by returning false or by throwing an exception.

If the selection fails, the JCRE returns the status word 0×6999 to the host. If the select method returns true, the SELECT APDU command is then supplied to the applet in the subsequent call to its process method so that the applet can respond to the host with applet-related information. For example, the wallet applet might return the wallet issuer's identification number, currency conversion information, or other parameters. The host might need this information to start DEBIT or CREDIT transactions. Applet designers or issuers are free to define the content and the format of the response data.

The select method in the base Applet class simply returns true. An applet can override this method and define the actions required during selection.

SELECT APDU Format and Processing

The SELECT APDU command is the only APDU command that is standardized on the Java Card platform. It ensures interoperable applet selection on various Java Card platform implementations. The APDU format is depicted in Table 7.2. The data portion of the SELECT APDU contains an applet AID, which is between 5 and 16 bytes in length. For an applet to be selected, the entire data field of the APDU must match the AID of the applet.

On receiving an APDU, the JCRE decodes its header (CLA, INS, P1, and P2) to determine whether it is an applet selection command, and if so, whether the AID in the APDU data matches that of an applet on the card. A successful applet selection involves deselecting the current applet, selecting the new applet, and sending the SELECT APDU to the new applet's process method. If the APDU is not for applet selection, the JCRE delivers it to the current applet for processing. In any case, if an error occurs during selection, the JCRE flags the error by returning the status word 0×6999 to the host, and no applet becomes selected on the card. Processing the SELECT APDU is illustrated in Figure 7.3.

APDU command processing

Figure 7.3. APDU command processing

Table 7.2. Applet SELECT command

CLA INS P1 P2 Lc Data Field
0×0 0×A4 0×4 0×0 Length of AID AID bytes

Default Applet

Normally, applets become selected only via a successful SELECT command. However, some smart card systems require a default applet that is implicitly selected after every card reset.

To select a default applet, the JCRE calls the default applet's select method and marks it as the currently selected applet. Because no SELECT APDU is required, the applet's process method is not called subsequently during selection. If the default applet's select method throws an exception or returns false, no applet is selected until the next SELECT APDU is processed.

Default applet selection is an optional JCRE feature. When supported, a JCRE implementation should devise a mechanism for specifying the default applet.

deselect Method

Before a new applet is selected, the JCRE deactivates the current applet by calling its deselect method. It is possible that the newly selected applet is the same as the current applet. In this case, the JCRE deselects it anyway and then reselects it.

The deselect method allows the applet to perform any cleanup operations to prepare itself to go “off stage” and to enable another applet to execute. The default implementation in the class Applet is an empty method. An applet should override this method for any required cleanup operations. For example, the wallet might need to reset the security condition or the transaction state, which is valid only during one selection period.

The deselect method might fail. Even so, the current applet is deselected and a new applet is selected despite the result of executing the deselect method. The JCRE also ignores any exceptions thrown from the deselect method.

Furthermore, on reset or power loss, the applet is automatically deselected by the JCRE without its deselect method being called. Therefore, an applet cannot always rely on the cleanup operations in the deselect method.

process Method

When receiving an APDU command, the JCRE calls the current applet's process method. In the process method, an applet is expected to perform a function requested in the APDU. The process method in the base Applet class is an abstract method. An applet must directly or indirectly override this method. Usually the process method is implemented as a dispatcher. On receiving an APDU command, the method decodes the APDU header and calls a service method to execute the requested function.

The JCRE encapsulates the APDU in the argument to the process method, apdu (an instance of the class APDU). The applet invokes methods on the apdu object to receive and to return the APDU data. Handling APDU commands in an applet is covered thoroughly in Chapter 8.

Other Methods in the Class javacard.framework.Applet

There are two other methods in the Applet class: selectingApplet and getShareableInterfaceObject.

The traditional smart card system is file system oriented. Application data are stored in files. A file must be selected before any action is performed on the data in the file. Readers who are familiar with ISO 7816 commands will recognize that the SELECT APDU in Table 7.2 is the ISO command select DF (dedicated file) by name. The JCRE can determine whether the command is for applet selection by matching the data in the command with the AID of any applet on the card (see Figure 7.3).[2] Because all APDUs are forwarded to the currently selected applet's process method, the applet calls the selectingApplet method to distinguish whether the SELECT APDU command is used to select this applet itself or whether it is attempting to select a DF of this applet. The selectingApplet method returns true if the APDU selects this applet. Otherwise, it returns false.

The getShareableInterfaceObject method is intended for object sharing among applets. It is invoked by the JCRE when another applet requests a shareable interface object from this applet. This method is further described in chapter 9 in the coverage of the applet firewall and object sharing.



[1] Some Java smart cards also support applet deletion.

[2] It is possible that the JCRE might mistakenly select an applet if the encoding of a DF name is identical to the AID of an applet on the card.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.123.120