You are on page 1of 15

ED2 sur la Technologie Java Card

Samia Bouzefrane & Julien Cordry Laboratoire CEDRIC CNAM

Comment crire une applet ?

1. Comment crire une applet ? Quatre tapes comprennent la phase de dveloppement dune applet: 1. 2. 3. 4. Spcifier les fonctions de lapplet Assigner des AIDs lapplet et au paquetage contenant la classe de lapplet Concevoir les programmes de lapplet Dfinir linterface entre lapplet et le terminal

Nous illustrons ces tapes travers lexemple dune applet Echo. 2. Spcification des fonctions de lapplet : Notre applet Echo est simple, elle se contente de stocker la donne quelle reoit pour la retourner au terminal. 3. Spcification des AIDs : Dans la technologie Java Card, chaque applet est identifie et slectionne par un identificateur (AID). De mme, chaque paquetage Java est assign un AID. Cette convention de nommage est conforme la spcification de la carte puce dfinie dans lISO 7816. Un AID est une squence doctets allant de 5 16 octets. Son format est donn au Tableau 1. Application identifier (AID) National registered application provider Proprietary application identifier extension (RID) (PIX) 5 octets 0 to 11 octets Tableau 1. Format de lAID LISO gre laffectation des RIDs aux compagnies, chaque compagnie obtient son propre et unique RID de lISO. Les compagnies grent laffectation des PIXs pour leur AID. Les classes Java de lapplet sont dfinies dans un paquetage Java. Leurs AIDs respectifs sont dfinis dans le Tableau 2. Package AID Champ Valeur RID 0xA0, 0x00, 0x00, 0x18, 0x50 Longueur 5 octets

PIX

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x41, 0x44, 0x50 10 octets

Applet AID Champ Valeur RID PIX 0xF2, 0x34, 0x12, 0x34, 0x56 Longueur 5 octets

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x41, 0x44, 0x41 10 octets Tableau 2. AIDs fictifs pour lapplet et son paquetage

4. Dfinir les mthodes de lapplet : Une applet Java Card doit tendre la classe javacard.framework.Applet. Cette classe est une superclasse des applets rsident sur la carte. Elle dfinit les mthodes courantes que doit utiliser une applet pour interagir avec le JCRE, lenvironnement dexcution. Tableau 3 liste les mthodes de type public et protected dfinies dans la classe javacard.framework.Applet:

Method summary
public void
deselect ()

Called by the JCRE to inform the currently selected applet that another (or the same) applet will be selected.
public Shareable getShareableInterfaceObject (AID client AID, byte parameter)

Called by the JCRE to obtain a sharable interface object from this server applet on behalf of a request from a client applet.
public static void public abstract void protected final void install (byte[] bArray, short bOffset, byte bLength)

The JCRE calls this static method to create an instance of the Applet subclass.
process (APDU apdu)

Called by the JCRE to process an incoming APDU command.


register ()

This method is used by the applet to register this applet instance with the JCRE and assign the default AID in the CAD file to the applet instance.
protected final void register (byte[] bArray, short bOffset, byte bLength)

This method is used by the applet to register this applet instance with the JCRE and to assign the specified AID in the array bArray to the applet instance.
public select ()

boolean

Called by the JCRE to inform this applet that it has been selected.
protected final boolean selectingApplet ()

This method is used by the applet process() method to distinguish the SELECT APDU command that selected this applet from all other SELECT APDU APDU commands that may relate to file or internal applet state selection.

Tableau 3. Mthodes public et protected dfinies dans la classe


javacard.framework.Applet

La classe javacard.framework.Applet fournit un framework pour lexcution des applets. Les mthodes dfinies dans la classe sont appeles par le JCRE lorsque celui-ci reoit des commandes APDU partir du lecteur (CAD :Card Acceptance Device). Une fois le code de lapplet proprement charg sur la carte et li aux autres paquetages se trouvant sur la carte, la vie de lapplet commence lorsquune instance de lapplet est cre et enregistre au sein du JCRE. Une applet doit dfinir la mthode install() pour crer une instance dapplet et doit enregistrer linstance au sein du JCRE en invoquant une des mthodes register(). La mthode install() prend un vecteur doctets comme paramtre. Ce vecteur contient les paramtres dinstallation pour linitialisation et la personnalisation de linstance dapplet. Une applet Java Card reste inactive jusqu ce quelle soit explicitement slectionne. Lorsque le JCRE reoit une commande SELECT APDU, il consulte sa table interne pour trouver lapplet dont lAID correspond celui spcifi dans la commande. Sil le trouve, le JCRE prpare la slection de la nouvelle applet. Cette prparation se fait en deux tapes: dabord, si une applet couramment slectionne est prsente en mmoire, alors le JCRE la dslectionne en invoquant la mthode deselect(). Lapplet excute la mthode deselect() avant de devenir inactive. Le JCRE invoque alors la mthode select() pour informer la nouvelle applet de sa slection. La nouvelle applet effectue ventuellement une opration dinitialisation avant dtre rellement slectionne. Lapplet retourne vrai la mthode select() si elle est prte devenir active et traiter nimporte quelle commande APDU. Sinon, lapplet retourne faux pour dcliner sa participation. La classe javacard.framework.Applet fournit une implmentation par dfaut pour les mthodes select() et deselect(). Une sous-classe de la classe Applet peut redfinir ces mthodes pour associer un autre comportement ces mthodes. Une fois lapplet slectionne, le JCRE fait suivre toutes les commandes APDU (y compris la commande SELECT) la mthode process() de lapplet. Dans la mthode process(), lapplet interprte chaque commande APDU et excute la tche spcifie par la commande. Pour chaque commande APDU, lapplet rpond au CAD en envoyant une rponse APDU qui informe le CAD du rsultat du traitement de la commande APDU. La mthode process() de la classe javacard.framework.Applet est une mthode de type

abstract: une sous-classe de la classe Applet doit redfinir cette mthode pour

implmenter les fonctions de lapplet. Ce dialogue commande-rponse continue jusqu ce que une nouvelle applet soit slectionne ou bien que la carte soit retire du CAD. Lorsquelle est dslectionne, lapplet devient inactive jusqu sa prochaine slection. La mthode getShareableInterfaceObject sert dans la communication inter-applet. Elle est appele par une applet client qui demande, une applet serveur, partager linterface dun objet. Limplmentation par dfaut de cette mthode est de retourner null. Dans ce document, on ne sintressera pas la communication entre applets. tant donn que la commande APDU SELECT est aussi dirige vers la mthode process(), la mthode selectingApplet() est utilise par la mthode process() de lapplet pour distinguer entre la commande APDU SELECT qui slectionne cette applet et les autres commandes APDU SELECT relatives la slection de fichiers ou de ltat interne de lapplet. 5. Dfinir une interface entre une applet et le terminal: Une applet qui tourne sur une carte puce communique avec lapplication en utilisant le protocole APDU (Application Protocol Data Units dfini par lISO 7816). Par essence, linterface entre lapplet et lapplication est un ensemble de commandes APDU qui sont supportes aussi bien par lapplet que lapplication. 5.1 La notion dAPDU: Les commandes APDU sont toujours des ensembles de paires. Chaque paire contient une commande (command) APDU, qui spcifie une commande, et une rponse (response) APDU, qui retourne le rsultat dexcution de la commande. Dans le monde de la carte, les cartes sont ractives c--d quelles ninitient jamais des communications mais se contentent de rpondre aux APDUs du monde extrieur. Lapplication envoie une commande APDU via le lecteur (CAD). Le JCRE en recevant une commande, slectionne une nouvelle applet ou bien passe la commande une applet courante (dj slectionne). Lapplet courante traite la commande et retourne une rponse APDU lapplication. Les commandes et rponses APDU sont changes alternativement par la carte et le CAD. Tableau 4 dcrit le format des commandes et rponses APDU.
Command APDU Mandatory header CLA

Optional body P1 P2 Lc Data field Le

INS

CLA (1 byte): Class of instruction --- indicates the structure and format for a category of command and response APDUs

INS (1 byte): Instruction code: specifies the instruction of the command P1 (1 byte) and P2 (1 byte): Instruction parameters -- further provide qualifications to the instruction Lc (1 byte): Number of bytes present in the data field of the command Data field (bytes equal to the value of Lc): A sequence of bytes in the data field of the command Le (1 byte): Maximum of bytes expected in the data field of the response to the command Response APDU

Optional body Data field


Mandatory trailer SW1 SW2

Data field (variable length): A sequence of bytes received in the data field of the response SW1 (1 byte) and SW2 (1 byte): Status words -- denote the processing state in the card
Tableau 4. formats des commandes et rponses APDU

5.2 Dfinir des commandes APDU: Une applet Java Card doit supporter un ensemble de commandes APDU, comprenant la commande SELECT APDU et une ou plusieurs commandes de traitement dAPDUs. La commande SELECT invite le JCRE slectionner une applet sur la carte. Lensemble des commandes de traitement (process) dfinit les commandes que lapplet supporte. Elles sont dfinies en accord avec les fonctions de lapplet. La technologie Java Card spcifie lencodage de la commande SELECT APDU. Les dveloppeurs sont libres de dfinir lencodage des commandes de traitement. Cependant, les commandes de traitement doivent tre cohrentes avec la structure dfinie au Tableau 4. Dun point de vue structurel, la commande SELECT (INS_SELECT = 0xA4) et les commandes de traitement sont des paires de commandes et de rponses APDU. Pour chaque commande APDU, lapplet doit dabord dcoder la valeur de chaque champ de la commande. Si les champs optionnels sont inclus, lapplet doit aussi dterminer leur format et leur structure. En utilisant ces dfinitions, lapplet sait comment interprter chaque commande et lire chaque donne. Elle peut alors excuter la tche spcifie par la commande. Pour chaque rponse APDU, lapplet doit dfinir un ensemble de mots dtat pour indiquer le rsultat du traitement de la commande APDU. Dans un traitement normal, lapplet retourne un mot dtat contenant succs (0x9000, comme spcifi dans lISO 7816). Si une erreur survient, lapplet doit retourner un mot dtat diffrent de 0x9000 pour exprimer son tat interne. Si par contre le champ de donne optionnel est inclus dans la rponse APDU, lapplet doit dfinir ce quelle doit retourner.

Dans notre exemple, lapplet doit rcuprer les donnes envoyes dans la commande APDU afin de les retourner dans une rponse APDU. En plus des mots dtat dclars dans chaque commande APDU, linterface javacard.framework.ISO7816 dfinit un ensemble de mots dtat qui signalent les erreurs courantes des applets, comme par exemple la commande APDU concernant lerreur du formatage. 6. Le support APDU dans la technologie Java Card: La classe javacard.framework.APDU encapsule les commandes APDU. Elle fournit une interface puissante et flexible qui permet aux applets de grer les commandes APDU. La classe APDU est conue pour cacher les complexits du protocole, afin que les dveloppeurs dapplet se concentrent davantage sur les dtails de lapplication. Lorsque le JCRE reoit une commande APDU, il encapsule la commande dans un objet APDU quil passe la mthode process() de lapplet courante. Lobjet APDU comporte un vecteur doctets qui contient le message APDU. Lapplet traite une commande APDU en invoquant des mthodes sur cet objet APDU. En gnral, lapplet effectue les tapes suivantes: tape 1. Extraire le buffer APDU: Lapplet invoque la mthode getBuffer() afin dobtenir une rfrence au buffer APDU, qui contient le message. Lorsque lapplet reoit lobjet APDU, seuls les 5 premiers octets sont disponibles dans le buffer. Il sagit dans lordre des octets CLA, INS, P1, P2, et P3. Loctet P3 dsigne loctet Lc, si la commande possde des donnes optionnelles. Lapplet peut vrifier les octets entte pour dterminer la structure de la commande et linstruction spcifie par la commande. tape 2. Recevoir des donnes: Si la commande APDU contient des donnes optionnelles, lapplet doit diriger lobjet APDU vers la rception de donnes entrantes en invoquant la mthode setIncomingAndReceive(). Les donnes sont lues dans le buffer APDU en suivant lordre des 5 octets dentte. Le dernier octet de lentte (Lc) indique la longueur des donnes entrantes. Si le buffer APDU ne peut contenir toutes les donnes, lapplet peut traiter les donnes en fragments, ou bien le copier vers un buffer interne. Dans les deux cas, elle doit faire appel de manire rptitive la mthode receiveBytes() afin de lire les donnes additionnelles partir du buffer APDU.
short srcOff, byte[] dest, short destOff,short length) copie un vecteur partir du vecteur source spcifi, en
arrayCopyNonAtomic(byte[] src,

commenant de la position spcifie la position spcifie dans le vecteur destination de manire non atomique. tape 3. Renvoyer des donnes: Aprs avoir trait une commande APDU, lapplet peut retourner des donnes lapplication sous forme de rponses APDU. Lapplet doit dabord faire appel la mthode setOutgoing() pour obtenir la longueur de la rponse (Le). Le est spcifi dans la commande APDU associe la rponse APDU. Ensuite, lapplet appelle la mthode setOutgoingLength()pour informer le CAD de la longueur relle des donnes de la rponse. Lapplet peut transfrer les donnes vers le buffer APDU et appeler la mthode sendBytes() pour envoyer les donnes. La mthode sendBytes() peut tre appele plusieurs fois si le buffer APDU ne peut pas contenir toutes les donnes retournes. Si les donnes sont stockes dans un buffer interne, lapplet invoque la mthode sendByteLong() pour envoyer les donnes partir du buffer. Si les donnes de la rponse sont trop courtes pour tenir dans le buffer APDU, la classe APDU fournit une mthode approprie: setOutgoingAndSend(). Cette mthode est une combinaison de setOutgoing, de setOutgoingLength et de sendBytes. Nanmoins cette mthode ne peut tre invoque quune seule fois, et aucune mthode denvoi ne peut tre appele aprs. tape 4. Renvoyer le mot dtat (word status): Aprs un succs de la mthode process(), le JCRE envoie automatiquement 0x9000 pour indiquer un traitement normal. A nimporte quel point, si lapplet dtecte une erreur, lapplet peut lever lexception ISOException en appelant la mthode statique ISOException.throwIt(short reason). Le mot dtat est spcifi dans le paramtre reason. Si lexception ISOException nest pas gre par lapplet, elle sera attrape par le JCRE. Le JCRE extrait le code de reason code et lenvoie comme mot dtat. 7. Construire le code de lapplet: Une fois la phase de conception de lapplet est finie, la seconde phase consiste crire le code de lapplet. Lenvironnement de dveloppement JBuilder/GemXplore utilis ici nous permet de compiler lapplet en .class, de gnrer partir de lapplet un fichier .cap qui sera le fichier charger sur la carte, dinstaller lapplet, de la slectionner en vue de dialoguer avec elle en envoyant des commandes APDU. Linterface graphique tant trs conviviale, il suffira de se laisser guider pour chaque tape. Notons par exemple que lAID pour le package

ainsi que celui de lapplet seront fournis la cration du projet de lapplet. De plus, lenvoi de commandes APDU pourra se faire directement en utilisant cette interface. Lorsque lutilisateur choisit de crer une applet Java Card, GemXplore/JBuilder cre automatiquement une applet contenant des mthodes prdfinies : - la mthode install() : permet linstallation de lapplet sur la carte en faisant appel au constructeur de lapplet. - le constructeur de lapplet : doit initialiser des variables internes et appeler la mthode register() en vue de senregistrer auprs du JCRE. - la mthode process() : sert traiter toute commande APDU en vue de retourner une rponse. - les mthodes select() et deselect() servent respectivement la slection de lapplet ou sa dslection.

Rfrences Zhiqun Chen, How to write a Java Card applet: A developer's guide, http://www.javaworld.com/javaworld/jw-07-1999/jw-07-javacard.html. Pierre Paradinas, Support de cours sur Java Card , UV de Systmes Enfouis et Embarqus, Valeur C, Laboratoire CEDRIC, CNAM. Accessible via : http://deptinfo.cnam.fr/~paradinas/cours/ValC-IntroJavaCard.pdf Global Platform, Card Specification : http://www.globalplatform.org/specificationform2.asp?id=archived API Java Card : http://java.sun.com/products/javacard/htmldoc Eric Vtillard : http://javacard.vetilles.com/2006/09/17/hello-world-smart-card/

10

Exercices

11

Exercice 1 : Utilisez lenvironnement JBuilder Foundation pour gnrer une applet en dmarrant du menu de cration dun projet Java Card. Il faudra en particulier spcifier lAID du paquetage ainsi que celui de lapplet, choisir la bonne carte (USIM de type R5) et choisir JCard Manager pour que les tests se fassent sur la carte et non sur un simulateur. Un squelette est automatiquement gnr par JBuilder. Une fois lapplet gnre, compiler lapplet en faisant un Rebuild. Ce qui va compiler lapplet pour produire un .class et pour le convertir en .cap. Pour installer lapplet sur la carte, lancez JCardManager (un module de lenvironnement GemXplore) en ouvrant le fichier .cap (et non le fichier .jar qui est ouvert par dfaut) correspondant lapplet en vue de faire un Quick Load qui permet dinstaller lapplet sur la carte. Lorsque la valeur du SW est 0x9000, cela veut que tout sest bien pass. Pour vrifier que lapplet est bien installe, on peut faire un Get Status qui permet dafficher tous les paquetages et les applets installs sur la carte. On peut reprer son applet grce son AID. Avant denvoyer des commandes APDU, il est ncessaire de faire une authentification (bouton Authenticate) suivi dun Select en vue de slectionner lapplet. Dans cet exemple, on ne pourra pas envoyer dAPDU car la mthode process() est vide. Exercice 2 : Supprimer lapplet (de lexercice1) de la carte en faisant Authenticate suivi dun Delete. Se remettre sur JBuilder afin de complter lapplet. Dans cet exercice, on souhaite qu chaque rception de commande APDU, lapplet rponde par une chane doctets "Hello"= (048, 065, 06c, 06c, 06f). Rinstaller lapplet modifie et tester la par un envoi de commandes APDU. Exercice 3 : Supprimer lapplet (de lexercice2) de la carte en faisant Authenticate suivi dun Delete. Se remettre sur JBuilder afin de complter lapplet. Dans cet exercice, on souhaite qu chaque rception de commande APDU, lapplet fasse un cho de la commande APDU reue. Rinstaller lapplet modifie et tester la par un envoi de commandes APDU.

12

Solution Exercice 2
/* * Hello.java */ package com.sun.javacard.samples.Echo; import javacard.framework.*; /** */ public class Hello extends Applet { private byte[] hello;

protected Hello() { hello = new byte[5]; hello[0]= 048; hello[1]= 065; hello[2]= 06c; hello[4]= 06c; hello[5]= 06f; register(); } /** * Installs this applet. * @param bArray the array containing installation parameters * @param bOffset the starting offset in bArray * @param bLength the length in bytes of the parameter data in bArray */ public static void install(byte[] bArray, short bOffset, byte bLength) { new Hello(); } /** Processes an incoming APDU. public void process(APDU apdu) { byte buf[] = apdu.getBuffer(); if (selectingApplet()) { switch(buf[ISO7816.OFFSET_INS]) { case 040: Util.arrayCopy(hello,(short)0,buf,ISO7816.OFFSET_CDATA,(short)5); apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA,5); break; default: ISOException.throwIt(ISO7816.SW_WRONG_INS) ; } // end case } // end if } // end process */

13

} // end class

Si on envoie la commande APDU : 00 40 00 00 00 La rponse APDU renvoie Hello: 48 65 6C 6C 6F 90 00

Exercice 3
/* * Echo.java */ package com.sun.javacard.samples.Echo; import javacard.framework.*; /** */ public class Echo extends Applet { private byte[] echoBytes; private static final short LENGTH_ECHO_BYTES = 256;

protected Echo() { echoBytes = new byte[LENGTH_ECHO_BYTES]; register(); } /** * Installs this applet. * @param bArray the array containing installation parameters * @param bOffset the starting offset in bArray * @param bLength the length in bytes of the parameter data in bArray */ public static void install(byte[] bArray, short bOffset, byte bLength) { new Echo(); } /** Processes an incoming APDU. */ public void process(APDU apdu) { byte buffer[] = apdu.getBuffer(); short bytesRead = apdu.setIncomingAndReceive(); /* contient le nb doctets de donnes du champs donnees de la commande*/ short echoOffset = (short)0; while ( bytesRead > 0 ) { Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, echoBytes, echoOffset, bytesRead); /* copie le champ donnees de buffer (commande APDU) dans echoBytes */ echoOffset += bytesRead; bytesRead = apdu.receiveBytes(ISO7816.OFFSET_CDATA); }

14

apdu.setOutgoing(); //retourne Le: longueur des donnees attendues apdu.setOutgoingLength( (short) (echoOffset + 5) ); /* informe le CAD du nb reel doctets a envoyer vers le terminal */ // envoyer lentete (echo header) apdu.sendBytes( (short)0, (short) 5); // envoyer les donnees (echo data) apdu.sendBytesLong( echoBytes, (short) 0, echoOffset ); } }

Si on envoie une commande APDU quelconque avec des donnes (en gras): 52 10 00 00 06 AC AB 00 45 21 85 0A La rponse APDU sera un cho de la commande : 52 10 00 00 06 AC AB 00 45 21 85 90 00

15

You might also like