Chapter 2
Working with Logical Channels
Version 2.2.1 of the Java Card platform has the ability to support up to four logical channels. This gives an ISO-7816-4-compliant terminal the ability to open up to four sessions into the smart card, one session per logical channel. Logical channels allow the concurrent execution of multiple applications on the card, allowing a terminal to handle different tasks at the same time.
Applets written for version 2.1 of the Java Card platform will still work correctly, but they will not be aware of logical channel support. In contrast, applets written for version 2.2.1 can take advantage of this feature.
For example, you could write an applet for version 2.2.1 of the Java Card platform which is capable of handling security on one channel, while another applet attempts to access user personal information on another channel, using security information on the first. By following this design, it is possible to access information owned by a different applet without having to deselect the currently selected applet which is handling session information. Thus, you avoid losing your session-specific security data, which is usually stored in CLEAR_ON_DESELECT
RAM memory.
Applets and Logical Channels
In version 2.2.1 of the Java Card platform, you can work with applets that are aware of multiple channels and applets that are not aware of multiple channels.
The logical channel implementation in version 2.2.1 of the Java Card platform preserves backward compatibility with applets written for the Java Card platform version 2.1. It also allows you the option of writing your applets to use the logical channel feature or of writing the applets to work independently on any channel without using the logical channels at all.
Non-multiselectable Applets
In version 2.2.1 of the Java Card platform, you have the option of writing applets that can operate in a multiple channel environment, or you can write applets that do not take advantage of this feature. Applets written for the Java Card platform that do not take advantage of the multiple channel environment are similar to applets written for the version 2.1 Java Card specification. An applet written for the Java Card platform that was not designed to be aware of multiple channels cannot be selected more than once nor can any other applet inside the package be selected concurrently on a different channel.
You can have several non-multiselectable applets operating simultaneously on different channels, as long as they do not interfere with each other’s data while they are active. For example, you can open up to 4 channels and run a distinct applet on each as long as they do not inter-operate with each other. You can control their operation by multiplexing commands into the APDU communications channel. If the applets are independent of each other, then the results will be the same as if each of these applets were running one at a time, each in a separate session.
Multiselectable Applets
If you design your applets to take advantage of multi-session functionality, they will be able to inter-operate with each other from different channels and have the ability to be selected multiple times in different channels. For example, the card might be handling security information on one channel, while data is being accessed on a second channel, while the third channel takes care of data encoding operations.
Understanding the MultiSelectable Interface
For an applet to be selectable on multiple channels at the same time, or to have another applet belonging to the same package selected simultaneously, it must implement the javacard.framework.MultiSelectable
interface. Implementing this interface allows the applet to be informed when it has been selected more than once or when applets in the same package are already selected during applet activation.
If an applet that does not implement MultiSelectable
is selected more than once on different channels, or selected concurrently with applets in the same package, then an error is returned to the terminal.
Note – If an applet in any package implements the
MultiSelectable
interface, then all applets in the package must also implement the
MultiSelectable
interface. It is not possible to have multiselectable and non-multiselectable applets in the same package.
The MultiSelectable
interface contains a select
and a deselect
method to help manage multiselectable applets.
Applet Selection for MultiSelectable Applets
The MultiSelectable.select(boolean)
method informs the applet instance if it has been selected more than once on different channels, or if another applet in the same package has been selected on another channel. The parameter appInstAlreadySelected
is true
if the applet has already been selected on a different channel. It is false
if it has not been previously selected. The method can return either true
or false
to accept or reject applet selection.
This method can be called as a result of a SELECT FILE
or MANAGE CHANNEL
OPEN
APDU command being issued to select an applet. If the applet has not been previously selected, then the appInstAlreadySelected
parameter is passed as false
to signal an applet activation event. If the applet is subsequently selected on another channel, MultiSelectable.select(boolean)
is called again, but this time, the appInstAlreadySelected
parameter is passed as true
, to indicate that the applet is already active.
Applet Deselection for MultiSelectable Applets
The MultiSelectable.deselect(boolean)
method informs the applet instance if it is being deselected on the logical channel while the same applet instance or another applet in the same package is still active on another channel. The parameter appInstStillSelected
is true
if the applet remains active on a different channel. It is false
if it is not active on another channel. A value of false
indicates that this is the last remaining active instance of the applet.
This method can be called as the result of a MANAGE CHANNEL CLOSE
or SELECT FILE
APDU command. If the applet still remains active on a different channel, then the appInstStillSelected
parameter is passed as true
. Note that if the MultiSelectable.deselect(boolean)
method is called it basically means that either an instance of this applet or another applet from the same package remains active on another channel; therefore, CLEAR_ON_DESELECT
transients are not cleared. Only when the last applet instance from the entire package has been deselected, a call to Applet.deselect()
results instead, resulting in CLEAR_ON_DESELECT
transients being erased.
Writing Multiselectable Applets
This section describes how to write a multiselectable applet which will perform various tasks based on whether it is selected. The code samples in this section provide examples of extending the applet to implement the MultiSelectable
interface, and of implementing the MultiSelectable.select(boolean)
and deselect(boolean)
methods. The code samples also provide examples of how the Applet.select()
and deselect()
methods can be used to work with multiselectable applets.
To take advantage of multiple channel operation, an applet must implement the javacard.framework.MultiSelectable
interface. For example:
The new applet needs to provide implementation for the MultiSelectable.select(boolean)
and MultiSelectable.deselect(boolean)
methods. These methods are responsible for encoding the behavior that the applet should have during a selection event if either of the following situations occurs:
- the applet is already selected on a different channel
- one or more applets from the same package are also selected on different channels
The behavior to be encoded might include initializing applet state, accepting or rejecting the selection request, or clearing data structures in case of deselection.
Note that the applet is still required to implement the Applet.select()
and Applet.deselect()
methods in addition to the MultiSelectable
interface. These methods would handle applet selection and deselection behavior when a multiselection situation does not happen.
A MultiSelectable Applet Example
In this example, assume that the multiselectable applet, SampleApplet
, must initialize the following two arrays of data when it is selected:
- an array of package data that will be initialized when the first applet in the package becomes active
- an array of private applet data that will be initialized upon applet instance activation
You can make these distinctions in your code because the MultiSelectable
interface allows the applet to recognize the circumstances under which it was selected.
Also, assume that the applet requires you to:
- clear the package data once no applet in the package is active
- clear the applet private data when the applet instance is deselected
and that the following methods are responsible for clearing and setting the data:
To achieve the behavior specified above, you will need to modify the selection and deselection methods in your sample applet.
The code for Applet.select()
, which is invoked when this applet is the first to become active in the package, could be implemented like this:
Likewise, the implementation of the method MultiSelectable.select(boolean)
would need to determine whether the applet is already active. According to its definition, this method is called when there is another applet within this package that is active. MultiSelectable.select(boolean)
could be implemented such that if appInstAlreadySelected
is false
, then the applet private data could be initialized. For example:
In the case of deselection, the applet data needs to be cleared. The method MultiSelectable.deselect(boolean)
could be implemented so that it would clear applet data only if the applet is no longer active. For example:
If this applet is the last one to be deactivated from the package, it would also need to clear package data. This situation would result in a call to Applet.deselect()
. This method could be implemented like this:
Handling Channel Information on APDU Commands
Only specific APDU commands can contain encoded logical channel information. These are the commands whose CLA byte contains the bytes 0x0X, 0x8X, 0x9X, and 0xAX.
The X nibble is responsible for logical channels and secure message encoding; only the two least significant bits of the nibble are used for channel encoding, which ranges from 0 to 3. When an APDU command is received, the card processes it and determines whether the command has logical channel information encoding. If logical channel information is encoded, then the card sends the APDU command to the respective channel. All other APDU commands are forwarded to the card’s basic channel (0). For example, the command 0xB1 forwards the command to the card’s basic channel (0), since the CLA byte with the nibble 0xBX does not contain logical channel information.
This also means, that all applets willing to use the logical channel capabilities must comply with the ISO 7816-4 CLA byte encoding specification, and choose APDU commands accordingly.
Just as the deselection and selection mechanisms need to be written to take into consideration a multiple-channel environment, it is important to write the Applet.process()
method in such a way that it handles channel information correctly. Due to the fact that some APDUs could be digitally signed, the APDU command is passed to the applet’s process
method as it is sent by the terminal. That means, any logical channel information is not cleared, and passed intact to the applet. The applet must deal with this situation.
Note that in the following example, a bit mask, CHANNEL_FILTER
, is used to filter out logical channel information from the APDU command, so that the applet can correctly interpret it. The task of correctly interpreting CLA
byte channel information is the responsibility of the applet developer.
Writing ISO 7816-4-compliant Applets
If your applets must be compliant with the ISO 7816-4 specification, then you must track the applet security state on each channel where it is active. Additionally, in the case of multiselectable applets, you must copy the state (including its security configuration) when you perform MANAGE
CHANNEL
commands from a channel other than the basic channel.
For example, applets might need to perform some sort of initialization upon activation, as well as cleanup procedures during deactivation. To do these tasks, a multiselectable applet might need to keep track of which channels it is being selected on during a card session.
To track this information, you need to know the channel on which the task is being performed. Tracking is done by two methods in the Java Card API:
- In the
APDU
class: public static byte getCLAChannel();
This method returns the origin channel where the command was issued. In case of MANAGE
CHANNEL
or SELECT
FILE
commands, if this method is called within the Applet.select()
, MultiSelectable.select(boolean)
, Applet.deselect()
, or MultiSelectable.deselect(boolean)
method, it returns the APDU command logical channel as specified in the CLA byte.
- In the
JCSystem
class: public static byte getAssignedChannel();
This method returns the channel of the currently selected applet. In case of a MANAGE
CHANNEL
command, if this method is invoked inside the Applet.select()
, MultiSelectable.select(boolean)
, Applet.deselect()
, or MultiSelectable.deselect(boolean)
method, it returns the channel where the applet to be selected or deselected is assigned to run.
An ISO 7816-4-compliant Applet Example
In case of a MANAGE
CHANNEL
command from a non-zero channel to another non-zero channel, the ISO 7816-4 specification requires that the security state from the applet selected in the origin channel must be copied into the new channel. In the example presented in this section, assume that the state information is stored in the array appState
inside the applet:
You can use the APDU.getCLAChannel()
and JCSystem.getAssignedChannel()
methods to identify if the applet selection case corresponds to an ISO 7816-4 case where the security state needs to be copied. Note that if such an event occurs, it will also be a multiselection situation, where the applet is also selected on the newly opened channel.
In this example, the code to identify the applet selection case is included in the implementation of the MultiSelectable.select(boolean)
method:
Applet Firewall Operation Requirements
To ensure proper operation and protection, a number of applet firewall checks have been added to the virtual machine for the Java Card platform (“Java Card virtual machine” or “Java Card VM”) regarding security checks on method invocations.
Applets that implement MultiSelectable
are designed to handle calls to Shareable objects across packages when several applets are active on different logical channels. In contrast, an applet written for version 2.1 of the Java Card platform, or an applet written for version 2.2.1 that does not implement MultiSelectable
has exclusive control over any changes to its internal objects or data when it is selected. Only when the non-multiselectable applet is in a deselected state can other applets modify its internal data structures. Therefore, if an applet is non-multiselectable, no calls to its Shareable objects should be made when it is selected.
Working with Non-multiselectable Applets
Applets written for version 2.2.1 of the Java Card platform do not have to implement the MultiSelectable
interface. In this case, the applet will assume that it is uniquely selected and its owned objects will not be modified via Shareable interface objects while it is selected. The following points describe the limitations that are imposed when you interact with applets that do not implement MultiSelectable
:
- It is not possible to select more than one applet simultaneously from a package if any of the applets you want to select does not implement the
MultiSelectable
interface.
- It is not possible to invoke methods of a Shareable object belonging to a non-multiselectable applet when an applet, belonging to the same group context, is active.
ISO 7816-4 Specific APDU Commands for Logical Channel Management
There are two ISO-specific APDU commands that you can use to work with logical channels in a smart card:
SELECT FILE
—This command selects the specified applet on the specified channel number. The channel number can be from 0 to 3 and is specified in the lower two bits of the CLA byte. If the channel is closed, it will be opened and the specified applet will be selected on the channel. SELECT FILE
commands are forwarded to the newly selected applet.
MANAGE CHANNEL
—This command can be used to open a new channel from another channel, or close it. It provides the flexibility to allow you to specify the channel to be used or to allow the smart card to select the channel. Like SELECT FILE
, this command uses the lower two bits of the CLA byte to specify the channel number. MANAGE CHANNEL
commands are not forwarded to the applet.
When you work with these commands, keep in mind that:
- Origin logical channel values are encoded in the two least significant bits of the CLA byte.
- Logical channel values can be 0, 1, 2, or 3 only.
- Logical channel 0 is known as the basic channel, and it cannot be closed.
- At card reset, the basic channel (channel 0) is open. All other channels (1, 2, and 3) are closed.
The MANAGE CHANNEL
and SELECT FILE
commands are read by the Java Card RE dispatcher, which performs the functions specified by the commands. These functions include:
MANAGE CHANNEL OPEN
In response to the MANAGE CHANNEL OPEN
command, the Dispatcher will follow this procedure:
- If the origin channel is not open, an error is returned.
- Determines whether the channel is open or closed. If the channel is open, an error is returned.
- Opens the channel.
- If the origin channel is 0, then the default applet (if there is one) is selected in the new channel.
- If the origin channel is not 0, then the selected applet on the origin channel becomes the selected applet in new channel.
This MANAGE CHANNEL OPEN
command opens a new channel from channel Q:
CLA
|
INS
|
P1
|
P2
|
Lc
|
Data
|
Le
|
Data
|
SW1
|
SW2
|
0x0Q
|
0x70
|
00
|
00
|
0
|
-
|
1
|
0x0R
|
0x90
|
00
|
|
This command will produce the following results:
- the new open channel will be R. The card will select this channel automatically.
- if channel Q is the basic channel (channel 0), the card’s default applet will be selected on channel R. No applet will be selected if no default applet is defined.
- if channel Q is other than the basic channel (channels 1, 2 or 3), the selected applet on channel Q will become the current applet selected on channel R.
- applet on channel R can either accept or reject selection.
This command can return an error if:
- the applet does not implement the
javacard.framework.MultiSelectable
interface, when an attempt to select the applet in more than one channel takes place.
- the applet rejects selection or throws exception.
- no channel available.
- channel Q is not open.
This MANAGE CHANNEL OPEN
command opens channel R from channel Q:
CLA
|
INS
|
P1
|
P2
|
Lc
|
Data
|
Le
|
SW1
|
SW2
|
0x0Q
|
0x70
|
00
|
0x0R
|
0
|
-
|
0
|
0x90
|
00
|
|
This command will produce the following results:
- if channel Q is the basic channel (channel 0), then the card’s default applet will be selected on channel R. No applet will be selected if no default applet is defined.
- if channel Q is other than the basic channel (channels 1, 2 or 3), then the selected applet on channel Q will become the current applet selected on channel R.
- the applet on channel R can either accept or reject selection.
This command will return an error if:
- the applet does not implement the
javacard.framework.MultiSelectable
interface and you attempt to select it in more than one channel.
- the applet rejects selection or throws an exception.
- channel Q is not open.
MANAGE CHANNEL CLOSE
In response to the MANAGE CHANNEL CLOSE
command, the Dispatcher will follow this procedure:
- If the origin channel is not open, an error is returned.
- If the channel to be closed is 0, an error is returned.
- If the channel to be closed is not open or not available, a warning will be thrown.
- Deselects the applet in the channel to be closed.
- Closes the logical channel.
This MANAGE CHANNEL CLOSE
command closes channel R from channel Q:
CLA
|
INS
|
P1
|
P2
|
Lc
|
Data
|
Le
|
SW1
|
SW2
|
0x0Q
|
0x70
|
0x80
|
0x0R
|
0
|
-
|
0
|
0x90
|
00
|
|
This command will close channel R. Channel R must not be the basic channel (it can be channel 1, 2 or 3 only).
This command will return an error if:
It can return a warning if channel R is not open.
SELECT FILE
In response to the SELECT FILE
command, the Dispatcher will follow this procedure:
- If the specified channel is closed, open the channel.
- Deselect currently selected applet in channel if needed.
- Select specified applet in the channel.
This SELECT FILE
command selects an applet on channel R:
CLA
|
INS
|
P1
|
P2
|
Lc
|
Data
|
Le
|
SW1
|
SW2
|
0x0R
|
0xA4
|
0x04
|
0x00
|
(AID len)
|
(AID)
|
0
|
0x90
|
00
|
|
This command will produce the following results:
- channel R can be any (opened or unopened) channel, including the basic channel.
- the applet identified in the Data section will become the selected applet on channel R.
- if channel R is not open, this command will open channel R.
- if channel R is open, this command will change the selected applet in the channel to the one specified.
This command can return an error if:
- the applet could not be found or is not available. The current applet is left selected and an error is returned.
- an active applet belonging to the same package does not implement the
javacard.framework.MultiSelectable
interface, or if the applet to be selected does not implement this interface.
- channel R not available.