Skip to content
Martin Paljak edited this page Jan 14, 2020 · 11 revisions

apdu4u presents: APDU-2020 release

Run and create smart card apps with Java.

Build Status Maven Central Javadocs Release MIT licensed

If you work with smart cards, if exchanging APDU-s allows you to do something meaningful, then APDU-2020 is the toolkit for you. It provides a framework and necessary tooling for creating and running smart card apps from the command line, in your Java project or on the web.

Reader selection

Reader to use (if more than one reader is connected) can usually be automatically selected based on environment variables ($APDU4J_READER, $APDU4J_IGNORE) or reader state (in exclusive use, card present etc). Or a helpful curses based chooser that reacts to card reader events can be used to select the desired reader.

Reader aliases

Assign meaningful aliases or fixed names to technical PC/SC reader names. Especially handy under Linux if reader reports a serial in name (see "Transparent ID" below)

$ cat ~/.apdu4j/aliases.yaml
- match: "ACR 38U"
  alias: "Fingerprint"
- match: "1252"
  alias: "Beeping"
- match: "E637D36B"
  alias: "Transparent ID"

Will result in:

$ sc -l
[*] Yubico YubiKey FIDO+CCID 00 00
[ ] Beeping (ACS ACR1252 Reader [ACR1252 Reader PICC] 01 00)
[ ] Transparent ID (Gemalto PC Twin Reader (E637D36B) 02 00)
[ ] Fingerprint (ACS ACR 38U-CCID 03 00)

And enable to use only portion of the alias from command line:

$ sc -r beep ...

Virtual and remote readers

BIBO communication could happen not only over PC/SC but via whatever mechanism needed, given there's a simple plugin available. Running GlobalPlatformPro against a smart card placed against a compatible NFC mobile phone (depends on CloudSmartCard plugin):

$ sc -r https://cloudsmartcard.com/Kro5i67mmAxDpmBJVIS6r9bUKboxj3dM5luQOe gp -l

Running smart card applications

Running APDU-2020 compatible smart card apps installed locally, from internet downloads, or straight from the internet is easy.

  • Running locally installed GlobalPlatformPro
$ sc gp -l
  • Running a download downloaded CardDB app:
$ sc run ~/Downloads/cdb.jar
  • Running apps straight from the internet:
$ sc run https://javacard.pro/demo.jar

Tweaking low level tunables

Standard SUN or JNA based PC/SC wrapper; exclusive connections; T=0/T=1; GET RESPONSE and logical channel handling; CCID/PCSCv2 PinPad readers

For developers

apdu4j is a library from developer to developers, for writing applications that talk to smart cards, on any platform. It provides meaningful abstractions that are free from archaic legacy surrounding smart cards to provide a sane environment 95% of the time and provides all the necessary knobs to make the remaining 5% happen.

Writing smart card applications

The core library apdu4j providesthe necessary interfaces to create smart card applications.

Constructing and parsing APDU-s

CommandAPDU and ResponseAPDU allows you to create, parse and convert the byte structures exchanged with smart cards. These are API-compatible with javax.smartcardio, just import from apdu4j package instead of javax.smartcardio.

SmartCardApp

This is similar to a main() method of a command line app, but you don't have to worry about the smart card connection details - you get a connected BIBO. To make it runnable from a jar file, be sure to implement the service (try AutoService). This is useful for writing apps like GlobalPlatformPro.

import apdu4j.i.SmartCardApp;

@AutoService({SmartCardApp.class})
public class DemoApp implements SmartCardApp {

    @Override
    int run(BIBO bibo, String[] args) {
        // bibo is a connected smart card, write your app like a main() method
    }  
}

Application example: GlobalPlatformPro

TouchTerminalApp

This is similar to a public transit terminal or the card reader next to your office door - something happens whenever a card is detected. Communication is usually short and simple.

import apdu4j.i.TouchTerminalApp;

@AutoService({TouchTerminalApp.class})
public class DemoTouchApp implements TouchTerminalApp {

    @Override
    int onStart(String[] args) {
        // called when the app starts. non-zero return code indicates error
    }

    @Override
    void onTouch(BIBO bibo) {
        // called whenever a (contactless) card is connected
    }
}

Application example: CardDB

Working with PC/SC (javax.smartcardio)

While apdu4j abstracts away javax.smartcardio, it is here to stay on desktop Java. apdu4j-pcsc contains all the necessary bits to work with PC/SC API in desktop context.

CardTerminalApp

Just like SmartCardApp, but gets a javax.smartcardio CardTerminal as an argument instead of a BIBO. Only do this type of apps if you are sure that a basic BIBO approach will not be sufficient (please open an issue in this case). This depends on apdu4j-pcsc and is only runnable in desktop environments.

import apdu4j.p.CardTerminalApp;

@AutoService({CardTerminalApp.class})
public class DemoApp implements CardTerminalApp {

    @Override
    int run(CardTerminal terminal, String[] args) {
        // terminal is the chosen terminal. write your app like a main() method
    }  
}

Available apps

  • GlobalPlatformPro - GlobalPlatform JavaCard management
  • CardDB - a database with notes for smart cards
  • FDSM - Fidesmo client
  • EstEID - Estonian eID utility

What is a smart card?

A small and secure microprocessor usually embedded inside a card (bank card, SIM card) or device (computer, phone, smartwatch).

What is a smart card application?

A piece of software that does something useful and meaningful, either to a secure chip (increases a counter on the card) or something with a secure chip (decrypts a file with a key in the card). Some software incorporates functionality that deals with smart cards, like internet browsers (for establishing TLS sessions with client authentication) or GnuPG (for decrypting files with a

How do smart cards communicate with external world?

By receiving and replying to small messages (APDU-s). APDU-s are Bags of Bytes with a specific archaic structure (ISO 7816-4).

How do applications normally talk to smart cards?

There are multiple API-s and several technical transports, but they all boil down to sending messages. Most common and well known API is PC/SC AKA SCard* API. Many other API-s resemble this (OpenMobile API, javax.smartcardio API etc)

apdu4j helps to work with smart cards in a Java coding environment. It intends to generalize some archaic concepts and provide re-usable platform-independent components for real life apps.

  • apdu4j-2020
    • Generic interfaces for a BIBO (think: reader) and utilities constructing and parsing APDU-s (think: byte arrays). This should work anywhere where Java runs - desktop, Android, server environment. No external dependencies.
  • apdu4j-pcsc
    • Makes apdu4j-core and apdu4j-plugins work on javax.smartcardio and underlying PC/SC access to smart card readers (terminals). Utility functions that should make reader selection, logging, PC/SC pinpads etc more convenient to use. Only makes sense in a desktop or embedded (think: raspberry pi) environment.
  • apdu4j-tool
    • CLI interface to the above.

BIBO

Bytes In, Bytes Out

Interface that allows to send a bag of bytes and receive a bag of bytes (or an exception) as a reply. Command-response. Synchronous.

byte[] transceive(byte[] bytes) throws IOException;

Implementations could be a UNIX pipe, a UDP message, JSON over HTTP, PC/SC API or anything similar.

APDUBIBO

APDU is an ancient convention of formatting bags of bytes. Keywords like CLA, INS, P1, P2, LC, LE, SW etc. CommandAPDU and ResponseAPDU provide convenience methods for constructing and parsing those byte arrays. Some ancient formatting, but still a bag of bytes.

ResponseAPDU transmit(CommandAPDU apdu) throws IOException;

is equivalent to

new ResponseAPDU(transceive(new CommandAPDU(...).toBytes()) throws IOException;

Sessions and channels

A session is a series of APDU transmits. A technical session can be considered broken if IOException is thrown. A logical session is responsibility of the application (interpretation of APDU-s)

A channel is a logical multiplexing on top of the physical BIBO (like a logical session is based on APDU-s). SE access is still serialized to a single command-response channel.

BIBO providers

  • PC/SC (provided by apdu4j with the help of jnasmartcardio)
  • Android NFC
  • OpenMobileAPI
  • RemoteEMV (provided by apdu4j)
  • Raspi i2c
  • ...

PC/SC, Terminals and javax.smartcardio

PC/SC is the ages-old desktop oriented C API to enumerate smart card readers and talk to cards in those readers. Not required to have a BIBO to a secure element (can use direct USB CCID like GnuPG or some other USB framing than CCID). But it is the default protocol stacking layer present in desktop environments. javax.smartcardio is the Java-adaption of the PC/SC API. jnasmartcardio is the JNA re-implementation of the PC/SC API in Java, in javax.smartcardio-compatible way.

Modern environments like Android NFC have no notion of PC/SC (but the "reader" concept carries on to API-s like OpenMobileAPI) https://developer.android.com/reference/android/se/omapi/package-summary.html

Other software

  • OCF - OpenCard Framework
  • scuba