Write OpenCard services for downloading Java Card apps

With this straightforward loading information in hand, you can load Schlumberger's CyberFlex 16K or Dallas Semiconductor's iButton

In prior articles, we've discussed methods for connecting smart card readers to your system so that you can use your Java Card. In this article we'll build on that knowledge, teaching you how to load Java Cards from a Web-delivery perspective.

This article assumes some knowledge of smart cards, Java Cards, and OpenCard. See the Resources section below for links to prior Java Developer columns that have covered these subjects.

Little programs that load card apps directly from a PC are a dime a dozen. These programs are uninteresting, however, because they require you to download files, then start up programs, and so on. Our approach is to allow files on Web pages containing interesting Java Card applications to be fed directly onto your personal Java Card.

We've been focusing on using PC/SC, the C standard for loading and managing cards on WIN32 machines, and OpenCard, the Java based standard. As a developer you have three choices for developing dynamically loadable Java Card applications for mass markets: cook your own for each combination of different cards and readers; use PC/SC and follow Microsoft; or use OpenCard, which leverages PC/SC when possible yet allows you to extend and have equivalent functionality on Windows platforms.

The best choice is OpenCard, because PC/SC doesn't work on a lot of platforms that OpenCard works on -- such as computers smaller than PalmPilots, set-top boxes, and network computers, to name a few. Additionally, PC/SC doesn't support dynamic and flexible automatic loading of services to communicate with an inserted iButton or smart card as part of the standard. Writing your own loading application only works if you can afford to do so in terms of support and maintenance. And it doesn't leverage the efforts of others, which means you'll have to supply the different program's plumbing yourself.

Why OpenCard?

Java Cards are small, personal, secure storage devices with a tamper-resistant architecture. This makes Java Cards ideal for storing important personal information and for financial applications, generally any application where authentication, Integrity, and secrecy are desired. Java Cards are accessed through special devices that attach to your computer or are already on your computer, much like ATM cards are accessed through ATM machines and scanners. Some potential users of Java Cards are concerned about writing applications that work the same on all the various entrance ramps to the Internet, intranet and extranet. OpenCard provides a solution to the problem of interfacing different devices for reading cards to these platforms.

The following are some of the advantages of using OpenCard:

  • OpenCard allows you to write your own services while standardizing on some simple concepts. Ideally, as developers write to OpenCard, we can reuse terminals (smart card readers) and services written by others.

  • OpenCard was developed with the Web in mind, and it is very easy to add dynamic downloading over the Web to OpenCard. So if the market demands it, billions of cards can be programmed routinely on traditional and nontraditional platforms.

  • Users can load Java Cards directly. This means custom applications can be added to the card. Many of the current smart card development environments only work on Windows, which is unacceptable to many developers who use Linux or Solaris for software development. (After all, who can afford an hour or so of reboot time every day, as required when using Windows?)

We were able to develop and load an application for the Java iButton on systems that support Java only. The folks at iButton started with a 100-percent-Java development environment over two years ago, so when using iButtons, you never have to pop into an application written in C. (Nothing against C, but C applications are often not portable due to the user interface bindings.) We didn't realize we could do this with any smart card out there until Schlumberger Engineering Specialist Mike Montgomery told us this was actually relatively easy. We also wanted to be able to use OpenCard and write one application that would load any Java Card as long as the specific implementation was available.

In this article, we'll show you how to load Java Cards with OpenCard services that implement the specific protocol for each of the devices. We'll cover two devices: Dallas Semiconductor's Java iButton and Schlumberger's CyberFlex 16K card. In each case you'll need some information from the card manufacturer on how to load the card. Some manufacturers, like Schlumberger, provide this information with sample programs, others just list the protocol without samples, and others do not even make it available. Eventually Sun and OpenPlatform will resolve this issue by providing converters and security to ensure that cards are loaded easily and safely with trusted programs.

We'll take two off-the-shelf cards and readers and provide the source code for loading specific Java Card devices as an OpenCard service. We're concentrating here on the process of putting the program onto the card. We're at very low level here -- kind of like writing individual sectors to a disk. Eventually you can execute the copy command, but how does the copy command really work? It moves every datum from the source to the destination. Smart cards require the same, in addition to wanting the data to be trusted and verified.

The complete cycle: creation, conversion and secure loading

One of the challenges for credit card companies and banks is defining card ownership. All sorts of business issues come into play here, given the widespread functionality of the cards. Java Cards can support multiple applications, however, this isn't quite like putting a file on your disk drive. If you read your credit card agreement, you'll see that you don't own the card. Which means legally you may not be entitled to put more apps on your Java Card without permission. Suppose a card-owning business entity decides to allow other companies -- possibly competing companies -- to put applications on its cards?

What's the process for this? Sun and Visa are busy working on this in the form of a standard for loading Java Card applets, as described briefly in the Java Card 2.1 Specification and the OpenPlatform Standard from Visa. (For more information on these standards, see Resources.) Visa recognized this issue very early on and is proposing a standard that will allow smart card applications to be written and loaded onto your card by many different institutions.

The OpenCard Framework and the components that can be plugged in

Smart cards should someday be able to hold several applications at once -- one from American Express, one from MBNA, and one from your personal bank, for example. The big question is whether (and how soon) competing institutions will realize some consumers want only one card, not several different cards boasting a lot of pretty artwork!

Security and loading the app

Loading an application securely onto a Java Card can be accomplished in a number of ways, but generally you need to take care of the following -- using the existing, well-established security procedures Java enables.

  • Ensure that the code you are loading comes from an authentic Web site. While SSL-enabled Web sites should be secure, don't forget to look at the signer of the certificate. It's important to not assume that because you see the SSL security indication everything is OK.

  • In this scheme either an institution or a user can load an application onto a Java Card, with either party being informed of the request and the result. Once the bytes have been loaded, make sure the bytes are correct and authentic, that is, that no bytes were changed due to malicious intent or dropped data.

  • Use only signed applets.

Accomplishing the tasks listed above is straightforward using the Java Plug-in. The Java Plug-in provides a consistent execution environment for Java across different browsers and platforms. If you get tired of fighting your browser, take a look at the Java Plug-in in the Resources below.

When deploying a Java Card loading system in the real world, you must deal with the security issues raised in this section. OpenCard promises to be a big help in this area.

Let's put aside the security concerns for a short time and get on to loading the card.

The structure of a CardService loader

In a previous Java Developer column, "Write OpenCard card services for Java Card applets," Thomas Schaeck covered the anatomy of a card service. Card services are used by an application to communicate with the application on the card inserted into a terminal. For inserted cards, OpenCard can automatically select and load the right card service implementation. For a refresher on card services, or to gather more details, consult that article.

The value of the Java application provided in this article is that it can load any Java Card on a number of different readers. This is a very useful program because we'll be seeing many card readers and many cards from various manufacturers. As stated earlier, for this article's purposes we are interested only in OpenCard solutions.

To load Java Cards using OpenCard, we must have the card-specific information to load cards, discussed earlier, and a CardService that can be called to load cards. Both should be available from the manufacturer of the card.

First, we will discuss the creation of a CardService in terms of the OpenCard framework requirements. Then we will examine the code that takes a Java Card application and loads it onto the card or iButton.

We use the model of a proxy loader for inserted cards, rings, and other devices. When a card is inserted into an OpenCard terminal, OpenCard makes an attempt to load a CardService for it. Loading a CardService is something you can control by looking at the ATR (answer to reset) and the AIDs (application identifiers). In prior articles we've discussed the ATR and pointed out that this field is not really guaranteed to be unique across all cards. (For more on the ATR, see last month's column.) ATRs are defined in ISO7816-3 (this spec is available for a fee), but there is no requirement that the ATR be unique. Besides, an ATR identifies a card and should not be used to identify applications on the card. In future articles, we'll discuss how to register applications.

AIDs are guaranteed to be unique, in that you apply for an AID and register it. The smart card industry would benefit from using the Web to register and download applications using AIDS. The proxy for loading is designed as an interface and requires specific loaders to provide implementations.

We're finally ready to load a card. We're assuming the OpenCard framework has already determined which card is loaded and which loader to use (using the imperfect ATR scheme). The proxy for loading is called, and it will send a series of APDUs to the card to get the application loaded onto the card.

The first interface is the Java CardLoader proxy interface, which determines the loader to call. You can easily extend this reader to support more loaders by providing specific implementations. The Java CardLoaderProxy interface is very simple and consists of the following three methods:

import java.util.Hashtable;
import java.io.ByteArrayInputStream;
/**
 * Manufacturer specific loader need to implement this interface
 *
 * @param Hashtable Properties that can be used by instance of loader
 * @param ByteArrayInputStream The applet code to download in a format that
    the card understands
 * @returns Hashtable Properties of load
 */
public interface Java CardLoaderProxy {
    public Hashtable downloadApplet(Hashtable loadProperties,
ByteArrayInputStream
 bis);
    public int getBytesSent();
    public int getBytesToSend();
}

The most important method in this interface is downloadApplet, which has two arguments. Rather than having myriad methods for setting various load attributes, here we use a property sheet so that additional features can be added easily. The second formal parameter, ByteArrayInputStream, contains the bytes representing the class file in the manufacture-specific format. Dallas Semiconductor and Schlumberger provide converter programs to convert the class file produced by any certified Java compiler into the device-specific bytecodes. Ideally, the converter program will be written in Java so that it is portable. The utility programs from Dallas Semiconductor are written in Java. Every loader for a particular target such as a card, ring, or other device needs to provide a card service. This card service registers the implementation described above specific to the card that has been recognized using its ATR.

Code for the CyberFlex card

The code sample below for a CyberFlex card registers a LoadCyberflex class, which is an implementation of Java CardLoaderProxy. The Java CardLoaderProxyFactoryCyberFlex answers queries from the card service registry when the CardService scheduler is looking for a service for a particular card. This is very useful when, say, you have 10 services written for different types of devices. How do you decide which one to use? OpenCard left this to the application programmer to figure out: the CardServices will be called in the order registered, and you can take the desired action.

1 2 3 Page 1
Page 1 of 3