C H A P T E R  3

Working with APDU I/O

APDU I/O is a library included with the Java Card development kit. This library is used by many Java Card development kit components, such as apdutool, Java Card platform Workstation Development Environment (Java Card WDE), and the RMI client framework.

This 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 Java Archive (JAR) file apduio.jar.


The APDU I/O API

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

Javadoc tool files for the APDU I/O API are located in this bundle in HTML format at java_card_kit-2_2_2/doc/en/dev-notes/html/apduiojavadocs and a compilation of them in PDF format at java_card_kit-2_2_2/doc/en/dev-notes/pdf/apdiojavadocs.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 C-language Java Card RE and Java Card WDE, 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 cref of Java Card WDE), 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 simply 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 will also need the javax.comm library installed on your machine. See the Development Kit User's Guide for the Java Card Platform, Version 2.2.2 for details on how to obtain this library.

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 C-language Java Card RE or Java Card WDE), you can issue powerUp() on this card again and continue exchanging APDUs.

cad.powerDown(false);

The dual-interface C-language Java Card RE 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)