TheOpenCard Framework (OCF) is a smart card middleware implemented in Java. The framework allows a smart card awareapplication to access contact and contactless cards that implement commands using Application Protocol Data Units (APDUs)as defined by ISO/IEC 7816-4, -8 and -9.
The OpenCard Framework was orginally defined by the OpenCard Consortium, but mainly driven by IBM and Gemplus.The work ended with version 1.2 of the specification and a reference implementation by IBM. The consortium split up andleft the OpenCard Framework in a dormant state. The website was still available until 2007 and is now shut down.The original code was transfered the a project on SourceForge, but never actively maintained.
The version of OCF maintained by the OpenSCDP projects is based on the last version of the reference implementation.It contains some bug-fixes and minor modifications to the original code and a generic card service to access smart cardswith an ISO 7816-4 file system. Such a generic service was missing from the original code and rendered it pretty muchuseless for any serious application.
This distribution of OCF contains the base-core, base-opt and pcsc components, but does not include the referenceimplementation for the IBM MFC and special Gemplus terminals. It includes support for card readers using the CT-APIinterface.
The increasing interest in conducting electronic business over the Internet requires authentication and secured transactions. The use of smart cards in an Internet context and especially in connection with Java has not been standardized. This paper presents the architecture of the OpenCard Framework, an industry initiative to standardize smart card middleware for Java. The reference implementation for the framework in the Java programming language is described. Related standardization efforts will be reviewed briefly.
In order to use a smart card, you need to be able to read the card and communicate with it using an application. OpenCard provides a framework for this by defining interfaces that must be implemented. The OpenCard framework defines several of these interfaces. Once these interfaces are implemented, you can use other services in the upper layers of the API. For example, with a properly interfaced reader, OpenCard can start a Java card agent whenever the card is inserted. The card agent can then communicate with applications on the smart card via the card terminal in the context of a session.
This article will teach you how to interface card terminals to OpenCard. Future articles will discuss how to write an agent. A small test application, which gets the ATR (Answer to Reset) string is provided. The ATR is fundamental to smart cards. We will take the OpenCard development kit and explain implementations for two different smart card readers using the Card Terminal Interface. The techniques discussed in the article for powering up readers, starting card sessions, and the use of Protocol Data Units and Application Protocol Data Units can be reused for most of the readers on the market.
OpenCard provides an architecture for developing applications in Java that utilize smart cards or other ISO 7816-compliant devices on different target platforms such as Windows, network computers, Unix workstations, Webtops, set tops, and so on. The OpenCard Framework provides an application programming interface (API), which allows you to register cards, look for cards in readers, and optionally have Java agents start up when cards are inserted in the reader. The architecture of OpenCard is depicted in Figure 1.
The architecture of the OpenCard Framework is made up of the CardTerminal, the CardAgent, the Agents and/or applications that interact with these components. OpenCard consists of four Java packages with the prefix opencard:
The packages opencard.application and
opencard.io provide the high-level API used by the application developer. The services needed by the high-level API are carried out by classes in the opencard.agent and opencard.terminal packages. The opencard.agent package abstracts the functionality of the smart card through the CardAgent. Package opencard.terminal abstracts the card terminals (also known as card readers). Understanding the structure of the opencard.terminal package is required to understand the sample implementations of card terminals provided in this article.
Each card terminal is represented by an instance of class CardTerminal that defines the abstract OpenCard-compliant card terminal. A card terminal may have one or more slots for smart cards and optionally a display and a keyboard or PIN pad. The slots of a card terminal are represented by instances of the abstract class Slot, which offers methods to wait for a card to be inserted, to communicate with the card, and to eject it (if possible).
Cards and card readers require resource management so that agents can be granted the level of access control they require. Resource management provides for the sharing of card terminals and the cards inserted in them among the agents in the system. For example, say you are using your smart card to sign a document at the same time that a high-priority mail message comes in that needs to be decoded using your smart card. Resource management arbitrates the access to the CardTerminal and the correct port.
The resource management for card terminals is achieved by the CardTerminalRegistry class of OpenCard. There is only one instance of CardTerminalRegistry: the system-wide card terminal registry. The system-wide card terminal registry keeps track of the card terminals installed in the system. The card terminal registry can be configured from properties upon system start up or dynamically through register and unregister methods to dynamically add or remove card terminals from the registry.
During the registration of a card terminal, a CardTerminalFactory is needed to create an instance of the corresponding implementation class for the card terminal. The card terminal factory uses the type name and the connector type of the card terminal to determine the CardTerminal class to create. The concept of a card terminal factory allows a card terminal manufacturer to define a mapping between user-friendly type names and the class name.
In order to access a card terminal from within OpenCard, an implementation for both abstract classes CardTerminal and Slot must be provided. These have been named IBM5948CardTerminal and IBM5948Slot, respectively. In addition, an appropriate CardTerminalFactory named IBMCardTerminalFactory is needed. The terminal implementation consists of package com.ibm.zurich.smartcard.terminal.ibm5948. Figure 2 depicts the inheritance relationships between the classes of opencard.terminal, the Java classes, and the terminal implementation. The class diagram also contains class IBM5948Driver, which does not implement any abstract class of OpenCard but serves as a Java interface to the terminal driver library written in C.
We assume that the terminal is already connected to the workstation or PC, and that the serial port is configured to work with the terminal. In the following section, we describe the design and implementation of the driver, the terminal, the slot, and the card terminal factory. The configuration of the card terminal registry also is provided.
The function CT_init is used to open a connection to a card terminal that is connected to a certain serial port. After the connection has been established, protocol data units (PDU) can be exchanged with the card terminal and APUs can be exchanged with the smart card that is plugged into the slot of the terminal via the CT_data function.
The native methods described above mimic the C API in Java. The reason for this was to have as little C code to maintain as possible. On top of the native methods, which are private, the methods init, data, and close are implemented. They call the native methods and throw an exception if the return code indicates an error. In the case of the data method, the response byte array is returned upon a successful completion of the native method call. The example below shows the data method:
In order to keep memory management inside Java, a buffer response for the answer from the terminal is allocated once and passed on to the native code. Since the C API is not re-entrant, the methods of IBM5948Driver must be declared synchronized.
The card terminal is controlled by submitting control PDUs to the data method of the IBM5948Driver. The format of the control PDUs is ISO 7816-4 compliant. This allows us to deploy class opencard.agent.CommandPDU to construct the PDUs and opencard.agent.ResponsePDU to handle the responses.
The IBM5948CardTerminal class extends class CardTerminal. The constructor initializes the super class and instantiates the driver. Then it instantiates the array to hold the slots, and instantiates one instance of IBM5948Slot to represent the only slot of the IBM 5948 card terminal.
The abstract methods of CardTerminal are implemented using the command set of the IBM 5948 card terminal. Before constructing a command PDU, the actual parameters of the method are checked against the features of the card terminal. For the UserInteraction, for example, we must use the UserInteractionHandler if we want to read alpha-numeric input, since our terminal has only a pinpad and no keyboard.
The implementation of the waitForCard method is straightforward since only one slot exists. With only one slot in the terminal, waiting for a card in the terminal is equivalent to waiting at the slot itself. Hence, we call the waitForCard method of the slot instance.
A slot as defined in OpenCard can either extend the Slot class or the PollingSlot class, depending on whether or not the insertion and removal of the smart card causes the virtual machine to generate an event. Normally, such an event is not generated, so a thread must be started to poll for smart card presence in the slot. This is carried out by the PollingSlot class. Our driver is implemented in C, and, as it does not generate the event, we extend PollingSlot.
3a8082e126