Chip, Chip, Hurra

In den letzten zwei Jahren wurden sowohl Chipkarten und Kartenleser in kleinen Stückzahlen als auch die zugehörige technische Dokumentation immer besser zugänglich. Ein Zehnerpack Chipkarten ist leicht über das Internet zu bestellen, und Software zu ihrer Benutzung unter Linux steht ebenfalls bereit.

In Pocket speichern vorlesen Druckansicht 3 Kommentare lesen
Lesezeit: 15 Min.
Von
  • Matthias Brüstle
Inhaltsverzeichnis

Im Folgenden wird es ausschließlich um Prozessorkarten gehen, die mehr Möglichkeiten als Speicherkarten bieten - was ihren Reiz erhöht und gleichzeitig mehr Erklärungen erfordert (siehe Kasten ‘Chipkartentypen’). Besonders verbreitet sind sie zurzeit vor allem in Handys, in einigen Ländern spielen sie zudem eine Rolle als Wertkarte (Geld-, Proton-, Mondex-Karte). Diese stoßen aber nur selten auf die erhoffte Begeisterung. Die bislang erfolgreichste dieser Art dürfte die belgische Proton-Karte sein [1]. Zunehmend dienen Prozessorkarten zur Verschlüsselung und Signierung von E-Mails und Dateien sowie zur Authentifizierung. Selbstverständlich kann man mit Chipkarten noch wesentlich mehr anstellen. Allein die Fantasie und die verfügbare Hardware setzen hier die Grenzen. Es gibt zum Beispiel eine IP-Stack-Implementierung mit Webserver für eine Chipkarte.

Mehr Infos

Chipkartentypen

Es gibt zwei große Kategorien von Chipkarten:

Speicherkarten: Dies sind Chipkarten, die keine oder nur sehr wenig fest kodierte Intelligenz besitzen. Sie haben normalerweise zwischen 256 Byte und 8 KByte EEPROM. Die Kommunikation verläuft über synchrone Protokolle wie I2C, 2-Draht oder 3-Draht. Bei einigen Kartentypen kann man den Speicher nur nach der erfolgreichen Prüfung einer PIN beschreiben. Anwendungsfelder sind die Krankenversicherten- und die Lotto-Karte oder solche in einigen Parkhäusern. Eine weit verbreitete Speicherkarte mit komplexerer Sicherheitslogik ist die Telefonkarte.

Prozessorkarten: Obwohl die Marketing-Abteilungen einiger Firmen dazu tendieren, alle Chipkarten als ‘SmartCards’ zu bezeichnen, sind eigentlich nur die Prozessorkarten ‘smart’. Sie enthalten einen vollständigen Computer mit Microcontroller, RAM, ROM, EEPROM und einer seriellen Schnittstelle. Die Kommunikation mit der Karte verläuft über eins von zwei in ISO 816-3 definierten asynchronen Protokollen, T=0 und T=1. Das einfachere und ältere T=0 ist zeichenbasiert, T=1 bietet mehr und arbeitet blockorientiert. Die Befehle werden als so genannte APDUs (siehe Kasten ‘APDU - Application Protocol Data Unit’) ausgetauscht und vom Betriebssystem interpretiert, das im ROM gespeichert ist. Bei einigen neueren Karten lassen eine Erweiterung des Betriebssystems mit Java, BASIC oder anderen Programmiersprachen zu. Diese Programme werden dann häufig als Dateien im EEPROM abgelegt.

Aus der Sicht des Linux-Programmierers kann man die Anwendungen in zwei Gruppen unterteilen: zum einen solche, die von anderen emittierte Karten verwenden, und zum anderen Programme für Karten, die man selbst ausgeben kann. Bei Anwendungen der ersten Art ist sicherlich die Verfügbarkeit der Dokumentation das größte Problem. Ist sie bei GSM noch einfach herunterzuladen, gestaltet sich das bei Wertkarten wesentlich schwieriger. Bei der Geldkarte kann man noch mit Glück und gründlicher Suche eine etwas ältere Dokumentation im Internet finden. Die aktuelle gibt es jedoch nur beim Bankenverlag für etliche hundert Mark, und nicht jeder bekommt sie. Beschreibungen des Mondex-Systems sind für einen ‘freien’ Programmierer vermutlich gar nicht zu erhalten. In diesem Fall muss man sich die Funktionsweise anhand der mitgeschnittenen Kartenkommunikation und einer Analyse der Karte erarbeiten.

Bei selbst ausgegebenen Karten muss man zuerst ein oder mehrere geeignete Modelle finden. Die Karten unterscheiden sich im Wesentlichen durch Hardwaredaten (Größe des EEPROM, Coprozessor), Funktionsumfang (Geldbörsenbefehle, Hash- und Verschlüsselungsalgorithmen), Programmierbarkeit (Java, Basic) und Preis. Die Dokumentation ist normalerweise leicht zu beschaffen. Es gibt jedoch auch Ausnahmen, etwa bei Infineons CardOS. Hersteller, bei denen man die Dokumentation herunterladen kann, sind Schlumberger, Gemplus und ZeitControl.

Standardkarten haben heutzutage 8 bis 16 KByte EEPROM, besonders billige mit 1 KByte sind ebenso verfügbar wie die Highend-Modelle mit 32 KByte. Der freie Speicherplatz kann je nach Karte bis zu einige KByte kleiner sein. Ein numerischer Coprozessor ist immer dann notwendig, wenn die Karte Public-Key-Algorithmen wie RSA oder DSA unterstützen soll. Nur ECC (Elliptic Curve Cryptosystem) kommt ohne Hardwareunterstützung aus. Die Schlüssellänge von RSA beträgt auf den meisten Karten bis zu 1024 Bit. Wenige Karten unterstützen auch längere Schlüssel bis zu 2048 Bit. Von DSA ist abzuraten, da für eine Signatur echte Zufallszahlen notwendig sind und diese auf einer Chipkarte schwer zu erzeugen sind.

Mehr Infos

Select und das Dateisystem

Bei den meisten Karten enthält das EEPROM ein Dateisystem. Das Wurzelverzeichnis heißt dort Master File (MF), Verzeichnisse Dedicated File (DF) und Dateien Elementary File (EF). Bei den Dateien unterscheidet man zwischen normalen Dateien (Transparent) und datensatzorientierten (fixed record, variable record, cyclic). Alle Datei- und Verzeichnisnamen bestehen aus 2 Bytes. Das MF heißt immer 0x3F00. Verzeichnisse und Dateien haben Zugriffsrechte, die aber von Kartenmodell zu Kartenmodell stark differieren können.

Nach dem Reset einer Karte ist die aktuell angewählte Datei normalerweise das MF. Mit dem Kommando ‘Select’ wählt man andere Dateien. Je nach Kartenmodell kann man dazu einen absoluten oder relativen Pfad angeben oder andere Methoden benutzen. Die so gewählte Datei ist Ziel der folgenden Operationen wie Schreiben und Lesen.

Große Unterschiede gibt es bei den Geldbörsenfunktionen der Karten: Bei einigen kann man einfache Anwendungen mit In-/Dekrement-Befehlen erstellen. Andere erlauben recht komplexe Programme mit Seriennummern, Signaturen et cetera. Die Preise für Chipkarten liegen zwischen 1,5 und 30 Euro und hängen von der Hardwareausstattung, dem Chipkartenbetriebssystem und der benötigten Stückzahl ab.

Auf Programmierbarkeit von Chipkarten sollte man verzichten, wenn die Aufgabe mit nicht programmierbaren Karten zu lösen ist, die dort ohnehin vorhandenen Funktionen also ausreichen. Programmierbare Karten kosten in der Regel mehr, haben weniger freies EEPROM und sind nach meinen Erfahrungen auch nicht so fehlerfrei. Von diesen Karten sind keine Wunder zu erwarten: aufwändigere Programme können unbenutzbar langsam sein; schließlich läuft hier eine virtuelle Maschine auf einem 8-Bit-Microcontroller und nicht auf einem Pentium III. Soll die gesamte Anwendungsentwicklung unter Linux stattfinden, ist zudem eine Entwicklungsumgebung des Herstellers nötig. An der Unterstützung von Linux hapert es hier jedoch. Die einzige mir bekannte Ausnahme ist Schlumbergers JavaCard Cyberflex [2]. Näher kann hier nicht auf die Programmierung der Karten eingegangen werden, da dies den Rahmen dieser Einführung sprengen würde. Interessierten sei JavaWorld empfohlen, die ein paar einführende Artikel über die JavaCard bereithalten.

Bei der Entwicklung einer Applikation sollte man sich darüber klar sein, dass Chipkarten keine Hochsicherheitssysteme sind. Es muss bei ihnen immer damit gerechnet werden, dass sie ‘geknackt’, also ausgelesen werden. Die Anwendung muss so entworfen sein, dass der Schaden durch Auslesen oder Kopieren einer Karte möglichst gering bleibt, etwa durch Verwendung von so genannten diversifizierten Schlüsseln. Diese sind mit einem Hauptschlüssel von der Kartenseriennummer abgeleitet. Auch die Austauschbarkeit von Schlüsseln oder Algorithmen ist von Vorteil. So sind beispielsweise Mondex-Karten mit zwei Algorithmensätzen ausgestattet. Erweist sich einer von ihnen als zu unsicher, kann man sie auf den zweiten Satz umstellen.

Hat man sich nun für eine oder mehrere Karten entschieden, kann das Programmieren beginnen. Zuvor jedoch sollte man sich über einen wichtigen Punkt klar werden: Das größte Problem bei der Chipkartenprogrammierung sind die Unterschiede zwischen den einzelnen Modellen. Dies bereitet vor allem dann Ärger und Arbeit, wenn eine Anwendung mit Karten verschiedener Hersteller funktionieren soll oder man das Kartenmodell wechseln möchte. Es gibt zwar einige Spezifikationen von Kartenbefehlen (ISO/IEC 7816 [3], EN 726 [4], EMV [5], GSM 11.11 [4]); die momentan auf dem Markt befindlichen Karten implementieren die Befehle jedoch nach dem einen oder anderen Standard nicht vollständig oder haben eigene Erweiterungen. Beim verschlüsselten oder mit MAC (Message Authentication Code) gesicherten Übertragen von Befehlen gibt es ebenfalls große Variationen. Glücklicherweise ist aber der Trend zu erkennen, dass sich moderne Karten ähnlicher werden.

Für die eigentliche Arbeit benötigt man neben den Karten einen Kartenleser, der immer auch ein Schreiber ist, traditionell ‘Terminal’ genannt. Er bildet die Schnittstelle zur Karte und erledigt den Austausch von Daten und Befehlen. Diese wiederum sind in APDUs (siehe Kasten) verpackt. Für einige Kartentypen existieren Treiber, die Entwicklern die Zusammenbastelei dieser APDUs abnehmen. Höhere Softwareschichten, beispielsweise der ‘FileAccess Service’ der OpenCard Foundation, können auf diesen Treibern aufsetzen und bieten eine von der einzelnen Karte abstrahierende API. Neben Hardware und Treibern benötigt man zur Chipkartenprogrammierung ein Framework, von dem es für Linux-Nutzer mehrere gibt.

Mehr Infos

APDU - Application Protocol Data Unit

Chipkarten erhalten Befehle als Command-APDU. Eine C-APDU besteht aus vier Header-Bytes: Class, Instruction und zwei Parameterbytes (P1/P2). Class gibt die allgemeine Befehlsklasse an, Instruction den genauen -typ, P1 und P2 gegebenenfalls erforderliche Parameter. Optional sind folgende Längenbytes und Daten. Lc steht für die Länge der gesendeten Daten und Le für die Länge der Daten, die die Karte erwartet. Die Antwort schickt sie als Response-APDU (R-APDU). Diese besteht aus optionalen Daten und dem Status-Word, das bei den meisten Karten nach erfolgreicher Ausführung den Wert 0x9000 hat.

ISO 7816-4 unterscheidet vier Befehlstypen:

  • keine Datenübertragung,
  • nur die Karte schickt Daten,
  • nur die Anwendung schickt Daten und
  • es werden Daten in beide Richtungen übertragen.

Mit dem Protokoll T=0 sind Befehle der letzten Art nicht übertragbar, sie müssen in zwei Kommandos zerlegt werden. Das erste ist der eigentliche Befehl, das zweite ein ‘Get Response’, das die Antwortdaten abholt.

Trotz aller Normierungsversuche benutzen unterschiedliche Karten nicht immer identische APDUs für dieselbe Funktion. So sieht ISO 7816-4 für das Select-Kommando CLA=00 und INS=A4 vor. Als Modi kann man das Wurzelverzeichnis (MF) direkt anwählen oder eine Applikation per ID oder eine Datei über einen (absoluten oder relativen) Pfad. Zudem kann der Entwickler angeben, ob er er nur das Status-Word oder die Dateiinformationen als Antwort wünscht. Eine ISO-7816-4-konforme APDU, mit der man das Directory 0x1234 im MF über den absoluten Pfad wählt und auf Dateiinformationen verzichtet, wäre:

00 A4 08 0C 02 12 34 

Also CLA=00, INS=A4, P1=08 (absoluter Pfad), P2=0C (keine File-Info), dann die Pfadlänge und der Pfad. Schlumbergers Cryptoflex-Karte benutzt stattdessen CLA=C0, unterstützt nur einen Modus und will auf jeden Fall eine Antwort liefern. Die GPK4000/GPK8000 aus dem Hause Gemplus wiederum erlaubt die Wahl der Application ID, des übergeordneten Verzeichnisses oder direkt des MF.

Für den Einsatz von M.U.S.C.L.E. (Movement for Using Smart Cards in the Linux Environment) sind die PC/SC-Lite-Distribution, aktuell 0.7.8, und ein Treiber für den Kartenleser erforderlich. PC/SC-Lite implementiert die PC/SC-Spezifikation (Personal Computer/Smart Card), die die Benutzung von Chipkarten unter Windows standardisiert.

Die Installation von PC/SC-Lite aus der komprimierten tar-Datei erfolgt wie üblich (Auspacken, Übersetzen, Installieren). PC/SC-Lite ist danach im Verzeichnis /usr/local/pcsc zu finden. Um den PC/SC-Daemon ausführen zu können, muss noch /usr/local/pcsc/lib in den LD_LIBRARY_PATH aufgenommen und ein Kartenlesertreiber installiert sein.

Als Beispiel für einen Kartenleser- sei hier der Towitoko-Treiber aufgeführt. Dieser ist aktuell in der Version 2.0.0-pre5 bei M.U.S.C.L.E erhältlich. Die Installation ist ebenso unproblematisch wie von PC/SC-Lite (./configure -prefix=/usr/local/pcsc; make; make install), wobei die prefix-Option nur notwendig ist, wenn alles ins PC/SC-Lite-Verzeichnis installiert werden soll. Nun ist noch die PC/SC-Lite-Konfigurationsdatei /etc/reader.conf anzupassen. Die Datei mit einem Eintrag für einen Towitoko-Leser an der zweiten seriellen Schnittstelle sähe dann so aus:

FRIENDLYNAME "TOWITOKO"
DEVICENAME GEN_SMART_RDR
LIBPATH /usr/local/pcsc/lib/libtowitoko-ifdhandler.so
CHANNELID 2

Leider ist die Bedeutung von CHANNELID nicht für alle Kartenleser identisch; so müsste man etwa bei einem Gerät der Schlumberger Reflex60-Serie für die zweite serielle Schnittstelle den Wert 0x0102F8 eintragen. Das erste Byte bedeutet hier, dass dies eine serielle Schnittstelle ist, die beiden folgenden Bytes sind die I/O-Portnummer.

Nun kann man den PC/SC-Daemon in /usr/local/bin/pcscd starten. Mit diesem Programm kommunizieren die Anwendungen per RPC. Zur Überprüfung der Funktion ist testrpc verwendbar, das in der PC/SC-Lite-Distribution kompiliert, aber nicht mit installiert wird.

Ein Nachteil von PC/SC-Lite sind die nur spärlich vorhandenen Kartentreiber (Service Provider). Die existierenden sind zudem unvollständig und für die Anwendungsentwicklung noch ungeeignet. Listing 1 enthält ein Programmfragment, das einen Eindruck von der Arbeit mit M.U.S.C.L.E vermittelt.

Mehr Infos

Listing 1

Programmfragment zur Benutzung von PC/SC-Lite; das Zusammenstellen des Befehls ist hier nur sehr kurz abgehandelt, sollte aber in der Praxis nicht unterschätzt werden.

#include <winscard.h>

SCARDCONTEXT hContext;
SCARDHANDLE hCard;
SCARD_READERSTATE readerState;
LPSTR mszReaders, tmpstr;
DWORD dwReaders, dwProtocol, rsplen, dwState;
SCARD_IO_REQUEST ioSendPci;
BYTE cmd[ 261 ];
BYTE rsp[ 258 ], bAtr[ 40 ];
LONG rv;
int i;

/* Erzeugen eines Kontexts */
SCardEstablishContext( SCARD_SCOPE_SYSTEM,
NULL, NULL, &hContext );

/* Ermitteln der Länge der Kartenleserliste */
SCardListReaders( hContext, NULL, NULL, &dwReaders );

/* Anfordern des Speichers und
Abfrage der Kartenleserliste */
mszReaders = malloc( sizeof(char)*dwReaders );
SCardListReaders( hContext, NULL, mszReaders, &dwReaders );

/* Ausgabe der Kartenleserliste */
printf("Readers:\n");
tmpstr = mszReaders;
while( strlen( tmpstr ) ) {
printf( " %s\n", tmpstr );
tmpstr += strlen( tmpstr );
}

/* Warten auf das Einfügen einer Karte in den ersten Leser */
readerState.szReader = strdup( mszReaders );
readerState.dwCurrentState = SCARD_STATE_EMPTY;
SCardGetStatusChange( hContext, INFINITE, &readerState, 1 );

/* Eine exklusive Verbindung zur Karte herstellen */
SCardConnect( hContext, mszReaders, SCARD_SHARE_EXCLUSIVE,
SCARD_PROTOCOL_T0, &hCard, &dwProtocol );

/* Abfragen des Kartenstatus */
SCardStatus( hCard, mszReaders, &dwReaders,
&dwState, &dwProtocol,
bAtr, &rsplen );

/* Zusammenstellen eines Befehls */
...

/* Senden des Befehls und Abholen der Antwort */
ioSendPci.dwProtocol = SCARD_PROTOCOL_T0;
SCardTransmit( hCard, &ioSendPci,
cmd, sizeof(cmd), NULL, rsp,
&rsplen );

/* Auswerten der Antwort */
...

/* Verbindung zur Karte trennen */
SCardDisconnect( hCard, SCARD_EJECT_CARD );

/* SCard-Sitzug beenden */
SCardReleaseContext( hContext );

Fast alle Kartenlesertreiber des M.U.S.C.L.E.-Projekts implementieren auch die CT-API. Sie wurde von verschiedenen deutschen Firmen als Standard für die Krankenversicherungskarten entwickelt und erlaubt lediglich die Steuerung des Kartenlesers sowie das Verschicken und Empfangen von APDUs. Die Installation eines CT-API-Treibers ist nicht für alle Kartenleser einheitlich, sollte für einen Programmierer jedoch kein Problem darstellen.

Auffallend ist bei der CT-API die Schnittstelle: diese besteht nur aus den drei Funktionen CT_init(), CT_close() und CT_data():

char CT_init ( unsigned short Ctn, unsigned short pn );
char CT_close( unsigned short Ctn);
char CT_data( unsigned short ctn, unsigned char *dad,
unsigned char *sad, unsigned short lc, unsigned char *cmd,
unsigned short *lr, unsigned char *rsp);

CT_init() dient zum Öffnen der Bibliothek, CT_close zum Schließen. CT_data wird für alle anderen Funktionen verwendet. dad kennzeichnet hier den Empfänger (Leser oder eine Karte) und cmd enthält das Kommando. Dieses Kommando hat auch für Kartenleser die Struktur einer APDU (siehe Kasten). Der Aufbau der APDUs ist im CT-BCS (Basic Command Set) definiert; Listing 2 enthält ein Programmfragment.

Mehr Infos

Listing 2

Programmfragment zu den CT-API-Bibliotheken; auffallend ist hier, dass auch die Befehle zum Steuern des Kartenlesers APDUs sind.

#include <ctapi.h>

unsigned char ctn=0, dad, sad, cmd[261], rsp[258];
unsigned short lc, lr;

/* Initialiserung der CT-API-Bibliothek */
CT_init( ctn, PORT_COM1 );

/* RESET CT: Zurücksetzen des Lesers */
dad = CT;
sad = HOST;
lr = sizeof( rsp );
CT_data( ctn, &dad, &sad, 4,
(unsigned char*)"\x20\x11\x00\x00", &lr, rsp );

/* GET STATUS: Abfragen des Kartenstatus */
dad = CT;
sad = HOST;
lr = sizeof( rsp );
CT_data( ctn, &dad, &sad, 5,
(unsigned char*)"\x20\x13\x00\x80\x00", &lr,
rsp );

/* REQUEST ICC: Warten auf das Einstecken
einer Chipkarte (Timeout 20s) */
dad = CT;
sad = HOST;
lr = sizeof( rsp );
CT_data( ctn, &dad, &sad, 7,
(unsigned char*)"\x20\x12\x01\x01\x01\x14\x00",
&lr, rsp );

/* Zusammenstellen eines Befehls */
/* In diesem Beispiel ein fertiges Select MF Kommando */
...

/* Send a command: Abschicken eines Befehls
und Abholen der Antwort */
dad = 0;
sad = HOST;
lr = sizeof( rsp );
CT_data( ctn, &dad, &sad, 7,
(unsigned char*)"\x00\xA4\x00\x00\x02\x3F\x00",
&lr, rsp );
if( sad!=0 ) { }

/* Auswerten der Antwort */
...

/* EJECT ICC: Deaktivieren der Karte */
dad = CT;
sad = HOST;
lr = sizeof( rsp );
CT_data( ctn, &dad, &sad, 4,
(unsigned char*)"\x20\x15\x01\x00", &lr, rsp );

/* Schließen der Bibliothek */
CT_close( ctn );

Noch ein Hinweis zu den CT-API-Treibern: Deren Qualität schwankt stark. Sie reicht von ziemlich spezifikationskonform bis so schlecht, dass sich der Treiber mit der Spezifikation zanken würde, lägen beide auf demselben Tisch. Man sollte sich also die benötigten Treiber vorher gut ansehen und auf Eignung prüfen.

SCEZ ist ein Framework, das im Gegensatz zu CT-API auch Treiber für Chipkarten zur Verfügung stellt und ebenso wie PC/SC-Lite in C geschrieben ist. Die Distributionen bestehen zurzeit nur aus lauffähigen Snapshots, die nach dem Erstellungsdatum nummeriert sind; eine Version 1.0 sollte aber nicht mehr lange auf sich warten lassen. Snapshots gibt es auf dem FTP-Server oder im CVS-Baum. Die Installation gestaltet sich recht einfach, da die SCEZ-Snapshots auch als RPM erhältlich sind. Zuvor muss jedoch libdes installiert werden.

rpm -i libdes-4.01-1.i386.rpm
rpm -i scez-20000906-1.i386.rpm

Alternativ kann man den Quellcode im tar-Archiv selbst kompilieren, wozu die Konfigurationsbibliothek Keeper erforderlich ist.

mkdir scez
tar xvzf ../scez-20000906.tar.gz
make Linux

Ist DES-Unterstützung gewünscht und die passende Bibliothek samt Header-Dateien vorhanden, sollte der letzte Schritt make Linux-libdes heißen. Anschließend müssen noch die Bibliotheken und Header-Dateien an den gewünschten Ort kopiert werden. Die mit ‘t’ beginnenden Programme sind normalerweise für Entwickler nicht relevant, alle übrigen können für sie wie für Anwender hilfreich sein.

So erlaubt etwa simman das Bearbeiten des Telefonbuches und der SMS-Nachrichten auf einer GSM-SIM, und scdir gibt Informationen über die eingesteckte Karte aus.

Zunächst sollte man die Konfiguration des Kartenlesers in der Umgebungsvariablen SCEZ_READER angeben. Ihr Inhalt besteht aus den durch Kommata getrennten Werten für Lesertyp, Kartenslot und Interface-Parameter. Für ein Towitoko Chipdrive an der zweiten seriellen Schnittstelle muss sie ‘TOWITOKO,1,1’ enthalten.

Listing 3 zeigt ein Programmfragment für SCEZ. Die Bibliothek ist einfach aufgebaut, um die Portierbarkeit auch auf nicht unixoide Betriebssysteme zu erleichtern. An Palm-PDAs ist per selbst gebautem Adapter ein Kartenleser anschließbar, und mit einem gcc-Crosscompiler können Enthusiasten unter Linux für diese Plattform programmieren. Im Gegensatz zu M.U.S.C.L.E. existieren wenige Treiber für Kartenleser, dafür umso mehr Treiber für Karten.

Mehr Infos

Listing 3

Programmfragment zur SCEZ-Bibliothek; bei den vielen Karten, für die bereits ein Treiber existiert, kann man sich das Zusammensetzen der APDUs sparen und vermeidet so eine häufige Fehlerquelle.

#include <scgeneral.h>
#include <scsmartcard.h>
#include <screader.h>
#include <sccyberflex.h>

SC_READER_INFO *ri;
SC_CARD_INFO *ci;
SC_READER_CONFIG rc;
BYTE rsp[258];
int rsplen, ret;

/* Initialisierung der Bibliothek */
scInit();

/* Ermitteln der Kartenleserkonfiguration */
rc.type=SC_READER_DUMBMOUSE;
rc.slot=1;
rc.param="0";

scReaderGetConfig( argc, argv, &rc );

/* Erzeugung von Leser- und Kartenobjekten */
ri = scGeneralNewReader( rc.type, rc.slot );
ci = scGeneralNewCard( );

/* Initialisierung des Lesers */
scReaderInit( ri, rc.param );

/* Aktivierung der Karte */
scReaderActivate( ri );

/* Abfragen des Kartenstatus */
scReaderCardStatus( ri);
if( !(ri->status&SC_CARD_STATUS_PRESENT) )
{ /* Keine Karte */ }

/* Reset der Karte */
scReaderResetCard( ri, ci );

/* Bestimmung des Kartentyps aufgrund des ATRs */
scSmartcardGetCardType( ci );
if( (ci->type&0xFF00)!=SC_CARD_CYBERFLEX )
{ /* Falsche Karte */ }

/* Anwählen des Master Files */
ret = scCyberflexCmdSelect( ri, ci,
SC_CYBERFLEX_SELECT_FILE, 0x3F00,
NULL, 0, rsp, &rsplen );
if( (ret!=SC_EXIT_OK) || (ci->sw[0]!=0x90) ||
(ci->sw[1]!=0x00) )
{ /* Fehler */ }

/* Deaktivieren der Karte und des Lesers */
scReaderDeactivate( ri );
scReaderShutdown( ri );

/* Deallozierung der Objekte */
scGeneralFreeCard( &ci );
scGeneralFreeReader( &ri );

/* Schließen der Bibliothek */
scEnd();

Eine weitere Möglichkeit, um unter Linux auf Chipkarten zuzugreifen, ist das OpenCard Framework (OCF). Es wurde vom OpenCard Consortium in Java entwickelt. Leider gibt es kaum Pure-Java-Terminaltreiber für OCF, die auf javax.comm aufsetzen. Die meisten Treiber basieren auf dem PC/SC- für OCF und sind somit nur unter Windows einsetzbar. Um OCF auch Linux-Anwendern und -Programmierern besser zugänglich zu machen, wurde vor einiger Zeit eine Anbindung an M.U.S.C.L.E. geschaffen.

Für OCF sind einige kartenunabhängige Dienste - beispielsweise FileAccessCardService oder SignatureCardService - definiert. Dies bringt Vorteile, wenn man viele verschiedene Karten unterstützen möchte, schränkt aber den Funktionsumfang dieser ein. Aus diesem Grund hat etwa Gemplus zusätzlich für jedes Kartenkommando eine Funktion implementiert. Sehr nützlich können selbst entwickelte, applikationsspezifische Dienste sein, da sie eine Unterstützung verschiedener Kartenmodelle erleichtern. Eine kartenspezifische Low-Level-API erleichtert die Implementierung dieser Dienste. Betrachtet man die Anzahl der Low- und High-Level-Treiber, so sieht es hier mit der Unterstützung nicht viel besser aus als bei M.U.S.C.L.E.

Zusammenfassend kann man sagen, dass je nach Präferenz entweder M.U.S.C.L.E. oder SCEZ die Bibliothek der Wahl ist. CT-API bringt dann Vorteile, wenn man ein Programm portieren möchte, das bereits die CT-API benutzt, oder man wirklich nur ein einfaches Interface für einen Kartenleser benötigt. OCF verlangt aufgrund der Implementierung in Java die meisten Ressourcen aller vorgestellten Modelle. Sein Einsatz kann aber von Vorteil sein, wenn man mit JavaCards arbeitet. In diesem Fall reicht eine Programmiersprache für die gesamte Entwicklung.

Für weitere ausführliche Informationen über Chipkarten sei das Buch ‘Handbuch der Chipkarten’ [6] von Wolfgang Rankl und Wolfgang Effing empfohlen.

Matthias Brüstle
ist Diplomchemiker und promoviert am Computer Chemie Centrum in Erlangen. Er ist der Autor von SCEZ und arbeitet nebenbei freiberuflich im Chipkartenbereich.

[1] Leo Van Hove, ‘Electronic Purses: (Which) Way to Go?’

[2] Informationen zur Javacard

[3] ISO-Standards

[4] ETSI-Standards

[5] EMV-Standards

[6] Wolfgang Rankl, Wolfgang Effing; Handbuch der Chipkarten, 3. Auflage; Verlag Carl Hanser 1999

[7] Uwe Hansmann; SmartCards; Selbstbeschriftung; OpenCard Framework: Chipkarten mit Java programmieren; iX 3/1999, S. 135

Mehr Infos

iX-TRACT

  • Softwareentwicklung für Chipkarten ist dank allgemein verfügbarer Leser und Karten nicht mehr nur Experten vorbehalten.
  • Für Linux stehen vier Frameworks zur Verfügung, die sich sowohl in der Zahl der unterstützten Geräte als auch dem Programmierkomfort unterscheiden.
  • Das OpenCard-Framework basiert auf Java und eignet sich deshalb für den Einsatz mit JavaCards.

(ck)