C H A P T E R   15

Working with APDU I/O

This chapter describes the APDU I/O API, which is a library used by many Java Card development kit components, such as apdutool , and the RMI client framework, see Chapter 14.

The APDU I/O library can also be used by developers to develop Java Card client applications and Java Card platform simulators. It provides the means to exchange APDUs by using the T=0 protocol over TLP224, by using T=1, and by using the PC/SC API. (However, note that PC/SC is unsupported and may not work on all platforms with all card readers).

The library is located in the file lib/tools.jar .


The APDU I/O API

The following sections describe the APDU I/O API. All publicly available APDU I/O client classes are located in the package com.sun.javacard.apduio .

Javadoc tool files for the APDU I/O APIs are also in a PDF file located in this bundle at JC_CONNECTED_HOME\docs\apduiojavadocs.pdf .

APDU I/O Classes and Interfaces

The APDU I/O classes and interfaces are described in this section.

Represents a pair of APDUs (both C-APDU and R-APDU). Contains various helper methods to access APDU contents and constants providing standard offsets within the APDU.

Represents an interface from the client to the card reader or a simulator. Includes methods for powering up, powering down and exchanging APDUs.

Exchanges a single APDU with the card. Note that the APDU object contains both incoming and outgoing APDUs.

Powers up the card and returns ATR (Answer-To-Reset) bytes.

Powers down the card. The parameter, applicable only to communications with a simulator, means “close the socket”. Normally, it is true for contacted connection, false for contactless. See Two-interface Card Simulation for more details.

Equivalent to powerDown(true) .

Factory and a base class for all CadClientInterface implementations included with the APDU I/O library. Includes constants for the T=0, T=1 and PC/SC (unsupported) clients.

The factory method static CadClientInterface getCadClientInstance(byte protocolType, InputStream in, OutputStream out) returns a new instance of CadClientInterface . The in and out streams correspond to a socket connection to a simulator. Protocol type can be one of:

The parameters, InputStream and OutputStream , are not used for PC/SC (unsupported).

Exceptions

Various exceptions may be thrown in case of system malfunction or protocol violations. In all cases, their toString() method returns the cause of failure. In addition, java.io.IOException may be thrown at any time if the underlying socket connection is terminated or could not be established.


Two-interface Card Simulation

To simulate dual-interface cards with the RI the following model is used:


Examples of Use

The following sections give examples of how to use the APDU I/O API.

To Connect To a Simulator

To establish a connection to a simulator such as cjcre.exe , use the following code.

CadClientInterface cad;
Socket sock;
sock = new Socket(“localhost”, 9025);
InputStream is = sock.getInputStream();
OutputStream os = sock.getOutputStream();
cad=CadDevice.getCadClientInstance(CadDevice.PROTOCOL_T0, is, os);

This code establishes a T=0 connection to a simulator listening to port 9025 on localhost . To open a T=1 connection instead, in the last line replace PROTOCOL_T0 with PROTOCOL_T1 .



Note - For dual-interface simulation, open two T=1 connections on ports (n) and (n+1), as described in Two-interface Card Simulation.


To Establish a T=0 Connection To a Card

To establish a T=0 connection to a card inserted in a TLP224 card reader, which is connected to a serial port, use the following code.

String port = “com1”; // serial port's name
CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier(port);
String appname = “Name of your application”;
int timeout =  30000;
CommPort commPort = portId.open(appname, timeout);
InputStream is = commPort.getInputStream();
OutputStream os = commPort.getOutputStream();
cad=CadDevice.getCadClientInstance(CadDevice.PROTOCOL_T0, is, os);


Note - For this code to work, you need a TLP224-compatible card reader, which is not widely available. You also need the javax.comm library installed on your machine. See javax.comm Package for details on how to obtain this library.


javax.comm Package

Install javax.comm package if you are planning to use the development kit to communicate with a TLP224-compatible card reader.

Use the javax.comm package included in the latest version of the Java Communications API, available on Sun’s web site at: http://java.sun.com/products/javacomm

Follow the instructions provided in the file Readme.html to install the package, and make sure that the comm.jar file is added to the CLASSPATH.

To Establish a Connection To a PC/SC-Compatible Card Reader

To establish a connection to the default PC/SC-compatible card reader (unsupported) installed on the machine, use the following code.

cad=CadDevice.getCadClientInstance(CadDevice.PROTOCOL_PCSC, null, null);

To Power Up And Power Down the Card

To power up the card, use the following code.

cad.powerUp();

To power down the card and close the socket connection (for simulators only), use either of the following code lines.

cad.powerDown(true);

or

cad.powerDown();

To power down, but leave the socket open, use the following code. If the simulator continues to run (which is true if this is contactless interface of the RI) you can issue powerUp() on this card again and continue exchanging APDUs.

cad.powerDown(false);

The dual-interface RI is implemented in such a way that once the client establishes connection to a port, the next command must be powerUp on that port.

For example, the following sequence is valid:

1. Connect on "contacted" port.

2. Send powerUp to it.

3. Exchange some APDUs.

4. Connect on "contactless" port.

5. Send powerUp to it.

6. Exchange more APDUs.

However, the following sequence is not valid:

1. Connect on "contacted" port.

2. Connect on "contactless" port.

3. Send powerUp to any port.

To Exchange APDUs

To exchange APDUs, first create a new APDU object using the following code:

Apdu apdu = new Apdu();

Copy the header (CLA, INS, P1, P2) of the APDU to be sent into the apdu.command field.

Set the data to be sent and the Lc using the following code:

apdu.setDataIn(dataIn, Lc);

where the array dataIn contains the C-APDU data, and the Lc contains the data length.

Set the number of bytes expected into the apdu.Le field.

Exchange the APDU with a card or simulator using the following code:

cad.exchangeApdu(apdu);

After the exchange, apdu.Le contains the number of bytes received from the card or simulator, apdu.dataOut contains the data received, and apdu.sw1sw2 contains the SW1 and SW2 status bytes.

These fields can be accessed through the corresponding get methods.

To Print the APDU

The following code prints both C-APDU and R-APDU in the apdutool output format.

System.out.println(apdu)