C H A P T E R 14

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`.

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.

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 located in this bundle at `JC_Connected_HOME\docs\apduio\`.

### APDU I/O Classes and Interfaces

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

- `class Apdu`

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.

- `interface CadClientInterface`

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

- `void exchangeApdu(Apdu apdu)`

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

- `public byte[] powerUp()`

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

- `void powerDown(boolean disconnect)`

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.

- `void powerDown()`

Equivalent to `powerDown(true)`.

- `abstract class CadDevice`

Factory and a base class for all `CadClientInterface` implementations included with the APDU I/O library. Includes constants for the T=0 and T=1 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:

- `CadDevice.PROTOCOL_T0`

- `CadDevice.PROTOCOL_T1`

### 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.

- `CadTransportException` extends `Exception`

- `T1Exception` extends `CadTransportException`

- `TLP224Exception` extends `CadTransportException`

##

Two-interface Card Simulation

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

- The simulator (`cjcre`) listens for communication on two TCP sockets: (n) and (n+1), where n is the default (9025) or the socket number given in the command line.

- The client creates two instances of the `CadClientInterface`, with protocols T=1 on both. One of these instances communicates on the port (n), while the other communicates on the port (n+1).

- Each of these client interfaces needs to issue the `powerUp` command before being able to exchange APDUs.

- Issuing the `powerDown` command on the contactless interface closes all contactless logical channels. After this, the contacted interface is still available to exchange APDUs. The client also may issue `powerUp` on a contactless interface again and continue exchanging APDUs on the contactless interface too.

- Issuing the `powerDown` command on the contacted interface closes all channels and causes the simulator (`cjcre`) to exit. That is, any activity after powering down the contacted interface requires restarting the simulator and reestablishing connections between the client and the simulator.

- At most, one socket can be processing an APDU at any time. The client may send the next APDU only after the response of the previous APDU is received. This means, behavior of the client+simulator still remains deterministic and reproducible.

- If you have a source release of the Java Card development kit, you can see a sample implementation of such a dual-interface client in the file `ReaderWriter.java` inside the `apdutool` source tree.

##

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`, 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 Prerequisites to Installing the Development Kit for details on how to obtain this library.

### 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)

Copyright © 2009 Sun Microsystems, Inc. All rights reserved.