AgenCard - INGÉNIEURS 2000 - Filière Informatique et Réseaux 3

powersmoneyΛογισμικό & κατασκευή λογ/κού

14 Ιουλ 2012 (πριν από 5 χρόνια και 1 μήνα)

611 εμφανίσεις

INGÉNIEURS 2000



Filière Informatique et Réseaux
3
ème
année


PROJET CORBA



AgenCard



Professeur responsable

M. Midonnet



Ivain Kesteloot
Fabien Locussol
Adrien Machado
Nicolas Phalippon





Année 2003
Filière IR


Promo 2000

Année 2003 Page 2


Table des matières

INTRODUCTION....................................................................................................................4
DESCRIPTION TECHNIQUE DU PROJET.......................................................................5
P
RESENTATION DE LA BASE DE DONNEES
................................................................................5
P
RESENTATION DE LA PARTIE
C
ORBA
......................................................................................6
Rappels des notions............................................................................................................6
Définition du contrat IDL...................................................................................................8
Projection vers le langage de programmation : JAVA......................................................9
Service de désignation (service de nommage).................................................................10
P
RESENTATION DE LA PARTIE
J
AVA
C
ARD
.............................................................................11
Description du Standard Class Libraries ou Java Card Framework..............................11
Les principaux termes utilisés dans JavaCard.................................................................13
Construction d'une applet avec le logiciel Schlumberger Cyberflex Access Toolkit.......13
Le protocole de communication APDU...........................................................................16
Description de l’applet.....................................................................................................19
DESCRIPTION DE LA REALISATION............................................................................21
M
ODULE SERVEUR
................................................................................................................21
Lancement........................................................................................................................21
Console de management...................................................................................................22
Administration..................................................................................................................23
M
ODULE CLIENT
....................................................................................................................25
Login et type de consultation...........................................................................................25
Fenêtre principale............................................................................................................26
Ajout et modification de rendez-vous...............................................................................28
Boutons d’action sur le logiciel.......................................................................................34
M
ODULE AUTONOME DE VISUALISATION
...............................................................................35
CODE COMMENTE.............................................................................................................37
P
ARTIE CORBA
.......................................................................................................................37
P
ARTIE
J
AVACARD
................................................................................................................42
Applet...............................................................................................................................42
Accès à l’applet................................................................................................................45
Fonctions de conversion et outils divers utilisés pour la conversion..............................55





Filière IR


Promo 2000

Année 2003 Page 3

PROCEDURE DE TEST.......................................................................................................63
D
EMARCHE PAS A PAS
...........................................................................................................63
M
ODULE SERVEUR
................................................................................................................63
M
ODULE CLIENT
....................................................................................................................64
M
ODULE AUTONOME DE VISUALISATION
...............................................................................64
P
ROBLEMES RENCONTRES
.....................................................................................................65
CONCLUSION.......................................................................................................................66
BIBLIOGRAPHIE.................................................................................................................67


Filière IR


Promo 2000

Année 2003 Page 4

Introduction
A l’heure actuelle, de plus en plus de personnes ne se séparent plus de leur agenda, au
travail comme dans la vie privée. On remarque d’ailleurs que les agendas électroniques
sont de plus en plus puissants et de moins en moins encombrants…
Conscient de ces caractéristiques, nous avons décidé de réaliser l’AgenCard dans le cadre
de notre projet de corba. Ce dernier a pour but de créer une application graphique
utilisant trois technologies. La première est le corba qui permet à des objets de
communiquer quelque soit leur emplacement. La deuxième est la Javacard qui permet de
programmer des cartes à puces évoluées et la dernière est java qui enveloppe le tout.
Le principe est d’avoir une base de données centralisée sur un serveur accessible pour
tous les clients grâce à la technologie corba. Aussi, chaque personne possédant une carte
à puce AgenCard pourra stocker ses rendez-vous et les consulter sans avoir besoin de
connexion avec le serveur.
Notre projet se découpe en trois modules. Le premier est le serveur qui possède sa
console d’administration graphique. Le serveur stocke la base de données commune à
tous les clients et gère sa mise à disposition grâce à la technologie corba. Il permet aussi
grâce à sa console de gérer les personnes et les types de rendez-vous utilisables.
Le deuxième module est l’application cliente. Elle permet essentiellement de prendre des
rendez-vous en fonction de la disponibilité des autres personnes grâce à la base de
données commune. C’est aussi grâce à cette application qu’on va pouvoir stocker son
agenda sur sa carte à puce. Elle contient une fonctionnalité client mail pour prévenir les
personnes des changements dans leur calendrier.
Le dernier module est l’application permettant de visualiser le contenu de sa carte à
puce, c’est à dire son agenda et cela, sans aucune connexion réseau (et donc sans
serveur) !
Ce document va décrire plus en détail notre projet dans sa globalité. Il fait suite à notre
étude préalable qui a présenté la Javacard et qui a préparé la mise en œuvre d’une
application utilisant cette technologie.

Filière IR


Promo 2000

Année 2003 Page 5

Description Technique du projet
Présentation de la base de données
La partie base de données de l’AgenCard est gérée par le serveur et est stockée sur ce
dernier. Elle est composée de trois fichiers :
- .ag_pers : fichier contenant le tableau des Personnes
- .ag_rdvs : fichier contenant le tableau des RDV
- .ag_trdv : fichier contenant le tableau des TypeRDV
Ces 3 fichiers sont créés s’ils n’existent pas et cela, à chaque lancement du logiciel. Leur
création se fait dans le répertoire personnel (repéré par la variable $HOME) de la
machine serveur. Leur emplacement et leur nom sont définis dans le début des fichiers :
- fr/umlv/agencard/src/serveur/database/PersonneManager.java pour .ag_pers
- fr/umlv/agencard/src/serveur/database/PersonneManager.java pour .ag_rdvs
- fr/umlv/agencard/src/serveur/database/TypeRDVManager.java pour .ag_trdv
Les fichiers correspondent à la sérialisation des tableaux d’objets contenus dans les
classes RDVManager, PersonneManager et RDVTypeManager (notées les XManager dans
la suite de ce document).
Aussi, nous avons choisi d’initialiser le fichier des personnes et celui des types de rendez-
vous avec quelques valeurs exemples pour faciliter les premières utilisations du logiciel.
C’est cette base de données, par l’intermédiaire de ses fichiers XManager, qui est placée
sur le bus corba. D’ailleurs, pour le passage de l’application en application distribuée,
nous avons du faire 3 modifications plus ou moins importantes :
- la première a été de passer toutes les variables de classe en public pour éviter de
devoir modifier les fichiers corba créés automatiquement par idlj (les fonctions read et
write des fichiers XManagerHelper plus précisément) en y insérant des getter et des
setter.
- la deuxième modification a été nécessaire compte tenu de l’impossibilité de déclarer
récursivement des variables n’étant pas des tableaux en idl. En effet, au début, nous
avions créé nos classes XManager comme des singleton. Chacune d’elle contenait donc
une variable de leur type pour stocker leur instance (la classe RDVManager contenait une
variable RDVManager, etc.). Or, cela donnait une déclaration récursive parfaitement
gérée par Java mais impossible a faire en idl. Nous avons donc du modifier la structure
de notre base de données pour palier ce manque de l’idl.
- la dernière modification a aussi été obligée par une « faiblesse » de l’idl concernant les
tableaux cette fois. Nous avons en effet été obligé de remplacer nos ArrayList contenus
dans nos XManager et gérant nos instances de personnes, de RDV et de TypeRDV, par
des tableaux de type X []. Cela a engendré de nombreuses modifications puisque nous
ne pouvions alors profiter des types évolués de java offrant des méthodes déjà définies
(pour l’ajout et la suppression par exemple). Nous nous posons aussi la question du
caractère scalable de l’AgenCard compte tenu de la présence de ces types « primitif »
non optimisés (comparés à une HashMap).
Filière IR


Promo 2000

Année 2003 Page 6

Le reste du programme n’a pas de particularités notables exceptées les suivantes :
- le champs permettant d’indiquer quel type de fonction a le droit de manager d’autre
calendrier que le sien (voir partie II-2) est la variable private final FONCTION_ALLOWED
du fichier fr/umlv/agencard/src/client/ui/LoginFrame.java. Elle est initialisée à
« Secretary » par défaut dans le logiciel.
- le mot de passe d’administration permettant d’accéder à la console (voir II-1) est
définit dans la variable private final ADMIN_PASSWORD du fichier
fr/umlv/agencard/src/client/AgencardMainClient/PasswordFrame. Elle est
initialisée à « secret » par défaut dans le logiciel.
- sur le client, nous offrons la possibilité de sauvegarder dans un fichier, par sérialisation,
les informations nécessaires à la connexion sécurisée à la carte pour la visualisation de
son contenu (voir II-3). Ce fichier est stocké sur le répertoire personnel de la personne
connectée (variable $HOME) ce qui rend l’application multi-utilisateurs. Cette sauvegarde
est sécurisée dans le cas ou le système d’exploitation est sécurisé. Le fichier se nomme
.ag_param. Ce nom et son emplacement sont définis dans le début du fichier
fr/umlv/agencard/src/cardview/CardInfoManager.java
Présentation de la partie Corba
Rappels des notions
Structure générale d’un modèle CORBA
Il s’agit d’un modèle objet de type client-serveur dans lequel les applications clientes
accèdent à des objets fournis par des applications serveurs.
La figure ci dessous synthétise les concepts de ce modèle objet.

Le langage IDL(Interface Definition Language)
Le langage IDL est un des éléments clés du bus à objets répartis Corba. En effet, il
permet la coopération entre utilisateurs et fournisseurs de services en masquant les
problèmes liés à l'interopérabilité et la localisation des objets.

Filière IR


Promo 2000

Année 2003 Page 7


Le langage IDL n'est pas un langage de programmation mais un langage de description
de services orientés objet pour l'environnement CORBA.
L'intérêt majeur du langage IDL est de permettre la définition des contrats passés entre
les fournisseurs d'objets CORBA et leurs utilisateurs. Les fournisseurs décrivent, grâce au
langage IDL, l'ensemble des interfaces des objets qu'ils veulent fournir à leurs clients;
ensuite, les clients utilisent ces interfaces IDL pour exploiter à travers leurs programmes
les objets ainsi fournis.

Les phases de développement


Filière IR


Promo 2000

Année 2003 Page 8

Définition du contrat IDL
Nous avons tout d’abord défini les objets composant notre application à l'aide d'une
méthodologie orientée objet. Nous avons ensuite traduit cette modélisation sous la forme
de contrats IDL composés des interfaces des objets et des types de données utiles aux
échanges d'informations entre les objets. L'IDL est le moyen par lequel les objets
informent leurs clients potentiels des opérations disponibles et la façon dont il faut les
appeler.
Code
Commentaires
module fr {
module umlv {
module agencard {
module src {
module corba {
struct Personne {
unsigned long id;
string name;
string prenom;
string fonction;
string service;
string tel;
string email;
string password;
string macKey;
string autKey;
string keyKey;
};
struct RDV {
unsigned long id;
unsigned long personne;
unsigned long annee;
unsigned long mois;
unsigned long jour;
unsigned long heureDeb;
unsigned long minDeb;
unsigned long heureFin;
unsigned long minFin;
string with;
string typeRDV;
};
struct TypeRDV {
string designation;
string lieu;
string salle;
string notes;
};
typedef sequence<Personne> Tabpersonne;
typedef sequence<RDV> Tabrdv;
typedef sequence<TypeRDV> Tabtype;
struct PersonneManager {
string personneFile;
Tabpersonne personneArray;
};
struct RDVManager {
string rdvFile;
Tabrdv rdvArray;
};
Nous avons encastré
des déclarations de
module pour pouvoir
intégrer plus
facilement les
fichiers créés par la
conversion du fichier
idl en java dans nos
packages

Nos « struct » vont
correspondre à nos
classes Java.
Nous les déclarons
ici pour pouvoir les
utiliser dans les
XManager qui vont
être mis sur le bus.















Pour pouvoir utiliser
dans nos XManager
des tableaux de taille
non prédéfinie
d’objets, nous les
déclarons ici.

Enfin, nous
définissons les objets
qui vont transiter
grâce à la
technologie corba.
Filière IR


Promo 2000

Année 2003 Page 9


struct TypeRDVManager {
string typeRdvFile;
Tabtype typeRdvArray;
};
interface ServeurAgent {// Ecriture sur le serveur
PersonneManager importPersonneManager();
RDVManager importRDVManager();
TypeRDVManager importTypeRDVManager();
};
};
};
};
};
};




Ici, nous déclarons
les méthodes qui
vont permettre le
trafic sur le bus.
Projection vers le langage de programmation : JAVA
Nous avons ensuite utilisé comme pré-compilateur le JDK 1.4 de Sun avec la commande
idlj –fall agencard.idl pour compiler notre idl.
Par commodité, nous avons inclus cette commande dans le script compilationidl.bat.
La compilation génère le package corba défini (fr/umlv/agencard/src/corba) comprenant
les fichiers suivants.
1. du côté client, on a obtient nos XHelper et nos XHolder ainsi que le stub.
PersonneHelper.java et PersonneHolder.java
PersonneManagerHelper.java et PersonneManagerHolder.java
RDVHelper.java et RDVHolder.java
RDVManagerHelper.java et RDVManagerHolder.java
TypeRDVHelper.java et TypeRDVHolder.java
TypeRDVManagerHelper.java et TypeRDVManagerHolder.java
TabpersonneHelper.java et TabpersonneHolder.java
TabrdvHelper.java et TabrdvHolder.java
TabtyperdvHelper.java et TabtyperdvHolder.java
ServeurAgentHelper.java et ServeurAgentHolder.java
_ServeurAgentStub.java la souche (stub)
Tous les types utilisateurs définis dans l'IDL ont donné naissance à des classes suffixées
par le mot clef Helper (Xhelper). Elles permettent entre autres de gérer les types Any et
TypeCode de l'IDL.
Les classes XHelper contiennent les méthodes pour :
• Convertir des objets CORBA en type Java (Cast) : narrow()
• Lire/Ecrire des objets CORBA : write() , read()
Tous les types (prédéfinis ou utilisateurs) possèdent une classe suffixée par le mot clef
Holder (XHolder ). Ces classes sont utilisées lors des passages en out ou inout lors de
l'invocation de méthodes, en lieu et place du type correspondant.n
Les classes implémentent les passages out et inout (inexistant en Java natif).
_ServeurAgentStub.java est le représentant coté client du serveur distant. il convertit les
requêtes du client en appel au serveur distant, attend la réponse et la renvoie au client.
Filière IR


Promo 2000

Année 2003 Page 10

Les fichiers Personne.java, RDV.java, TypeRDV.java et les XManager.java ont aussi été
créés en fonction de la définition idl et par idlj. Toutefois, ces fichiers ayant déjà été
créés, nous nous sommes contenté d’indiquer dans ceux créés par nos soins qu’ils
implémentent l’interface corba org.omg.CORBA.portable.IDLEntity (qui indique
simplement qu’il existe un Helper pour ces classes).
2. du côté serveur, ont été créés :
ServeurAgentOperations.java qui est l’interface d’opérations en java
ServeurAgentPOA.java qui est le squelette (skeleton) pour utilisation du POA

En plus de ces fichiers générés, nous implémentons les fichiers suivants :
Serveur.java
ServeurAgentImpl.java Interface
Client.java
AgentImpl.java

Le serveur Le client
Initialise l’ORB, Initialise l’ORB,
Initialise l’adaptateur d’objet (POA), Récupère la référence de l’objet à utiliser,
Crée l’objet Corba (Instancie
ServeurAgentImpl),
Convertit la référence vers le type d’objet à
utiliser,
Enregistre l’objet Corba (Mets en chaîne de
caractères la référence objet),
Utilise l’objet.
Exporte la référence de l'objet Corba
Attends les invocations clientes (requêtes).

Service de désignation (service de nommage)
Son rôle est de retrouver les références d’objet à partir de noms symboliques.

Sa structure est une arborescence appelée graphe de désignation (Naming Graph)
comprenant :
– Une racine

– Des répertoires, appelés « contexte de nommage »
– Des feuilles : les références d’objet
Un contexte est un objet qui gère une liste de liaisons (= associations nom-référence)
Orbd est le service de désignation du jdk1.4.
Filière IR


Promo 2000

Année 2003 Page 11

Présentation de la partie JavaCard

Description du Standard Class Libraries ou Java Card Framework
Cet ensemble de classes mis à la disposition des programmeurs contient 4 packages :

javacard.framework




C'est le paquetage noyau de la carte. Elle contient les définitions des classes telles que
Applet et PIN qui sont des classes essentielles de Java Card et APDU, System et Until, qui
offrent des services de runtime et système aux programmes Java Card (par exemple :
manipulation des APDU et du partage d'objets ).

javacardx.framework


Filière IR


Promo 2000

Année 2003 Page 12


Ce package offre un système de fichiers compatible au modèle orienté objet défini par la
norme ISO 7816-4. Il supporte notamment les fichiers élémentaires, les fichiers dédiés et
les fichiers orientés APDU.

javacardx.crypto et javacardx.cryptoEnc

Ces deux paquetages sont responsables des classes offrant des fonctionnalités de
cryptographie souvent nécessaires pour les cartes dotées de la technologie Java Card.

Filière IR


Promo 2000

Année 2003 Page 13

Les principaux termes utilisés dans JavaCard
APDU (Application Protocole Data Unit) Correspond au format standardisé des données
échangées entre le lecteur de carte et la carte

CAD (Card Acceptance Device) c'est le lecteur de carte. Son rôle est de traduire le choix
de l’utilisateur en APDU de commande pour la carte et attendre l’APDU de réponse pour
l’afficher décodée

JCRE (Java Card Runtime Environment) machine virtuelle + classes

AID (Application Identifier)

Applet : l'application qui va tourner sur la Java Card. (Unité de sélection, contexte,
fonctionnalité et de sécurité sur une carte Java Card)
Construction d'une applet avec le logiciel
Schlumberger Cyberflex Access Toolkit
Pour construire une applet JavaCard il ne faut pas perdre de vue que l'API n'est pas la
même que celle du JDK 1.4. Pour cela il faut savoir ce que l'on a le droit d'utiliser. Une
fois que l'on sait ce à quoi on a le droit, on peut écrire l'application.
Voici la chaîne de compilation d'une applet :



On utilise javac (ou un autre créateur de code interprété comme jikes) pour obtenir le
« byte » code, puis on génère un fichier « .ijc » qui poura être contenu sur la carte.
Étape 1 : Création de l'applet
Toute applet Java Card est une instance d'une classe qui étend la classe
javacard.framework.Applet Cette classe contient quelques méthodes qui doivent être
surchargées durant la conception de l'applet. La création d'une applet Java Card se fait
exactement comme une applet Java 'normale', i.e. à la JDK ( Java Development Toolkit ),
à la différence près que cette applet doit respecter rigoureusement les spécifications de
Java Card et non de Java. Comme les ressources disponibles abord de la carte sont très
limitées, Java Card ne contient qu'un petit sous ensemble de l'ensemble des fonctions de
Java, qui est défini dans les API au niveau du Java Card Framework.
Étape 2 : Compilation – Program File Generator
Pour compiler des programmes Java, il faut utiliser le compilateur de Java, javac, en
précisant dans le classpath la librairie « jc_api_212.jar » spécifique à JavaCard. Tout
emploi de méthodes, exceptions ou classes n'appartenant pas à JavaCard est détecté lors
de cette phase de compilation.
Le compilateur javac, qui a un analyseur syntaxique adapté à Java et non à Java Card,
ne peut garantir que le programme compilé est bien écrit en JavaCard car certaines
erreurs syntaxiques ne pourront pas être détectées.
Pour cette raison, l’application Schlumberger Cyberflex Access Toolkit propose un outil
appelé Program File Generator qui transforme le « .class » obtenu par la compilation d’un
fichier java, en fichier « .ijc » qui pourra être ensuite placé sur la carte :
Programme Java
Card

Javac
Program File
Generato
r

Byte code
(.class)
Création
d’un fichier (.ijc)
Filière IR


Promo 2000

Année 2003 Page 14


Remarque :
Le champ « package name » doit correspondre au package précisé dans le
fichier « .java ».

Filière IR


Promo 2000

Année 2003 Page 15

Étape 3 : Installation de l'applet
Dans un premier temps, l’application Cyberflex Access Toolkit va permettre de visualiser
le contenu de la carte. Il est nécessaire d’avoir préalablement téléchargé les bons drivers
pour accéder à la carte.
Lorsque l’application est lancée, il suffit de sélectionner la carte dans l’arborescence. La
fenêtre « Establish Secure Channel » apparaît et il est nécessaire de sélectionner une clé
pour accéder à la carte.
Rappel
: Toute applet Java Card est une instance d'une classe qui étend la classe
javacard.framework.Applet - Cette classe contient quelques méthodes qui doivent être
surchargées durant la conception de l'applet.
Pour qu'une applet soit exécutable, il faut qu'elle soit connue dans le runtime Java Card.
C'est la procédure d'installation qui rend une applet connue du JCRE. L'installation de
l'applet se fait généralement à l'endroit de fabrication de la carte ou ultérieurement par
un terminal sécurisé.

L'installation de l'applet sur la carte à puce implique l'initialisation de ses membres
statiques. Lors de l'installation, une fois l'applet chargée de façon définitive dans la
mémoire persistante de la carte ( soit le ROM ou l'EEPROM, dépendant si l'applet est
installée à la fabrication de la carte ou ultérieurement ), le JCRE fait un appel
automatique de la méthode install ( ) qui est exécutée une seule fois lorsque l’applet est
placée sur la carte. Elle doit être déclarée public static parce qu'elle est appelée avant
que l'applet soit instanciée. Cette méthode doit être surchargée par le programmeur qui
doit y mettre les déclarations qui doivent exister durant toute la durée de vie de l'applet.
Une méthode très importante doit être appelée à partir de install ( ) : c'est la méthode
register ( ). Elle sert à enregistrer l'applet dans l'environnement d'exécution Java Card.
A partir de cet instant, l'applet sera connue tout le temps par le JCRE.


En pratique, nous utilisons l’application Cyberflex Access Toolkit qui va nous permettre de
placé notre applet sur la carte.
Une fois que la carte est accessible, il faut

Étape 4 : Sélection, activation et désactivation d'une applet - select() &
deselect()
Une applet dans la carte reste inactive aussi longtemps qu'elle n'est pas explicitement
choisie pour être exécutée. La sélection est décidée en fonction de la demande provenant
du Card Accepting Device. Chaque applet est identifiée par un identifiant unique, le
Application Identifier ( AID ). Quand le CAD envoie un message de selection (un APDU
contenant l'AID de l'applet à exécuter ) au JCRE, ce dernier suspend l'exécution de
l'applet active en faisant un appel à sa méthode deselect ( ) pour la rendre inactive.
Puis il active l'applet dont l'AID est indiqué dans le l'APDU de sélection en appelant sa
méthode select ( ). La méthode select ( ) prépare l'applet à recevoir des APDU
provenant du Card Accepting Device. Par la suite, le JCRE redirigera tous les paquets
entrants vers l'applet active jusqu'à ce qu'une autre demande de sélection soit reçue.

Remarque : Communication applet - CAD : La méthode process ( )

La classe Applet contient une méthode process ( ) qui est la seule façon pour une applet
d'extraire de l'information du CAD. L'information est passée dans un APDU . Toutes les
demandes de sélection sont donc envoyées à la machine virtuelle Java Card en utilisant
cette méthode.

Filière IR


Promo 2000

Année 2003 Page 16

Le protocole de communication APDU
Présentation
Le protocole de communication entre la carte à puce et le terminal peut être
assimilé au modèle client-serveur ou le serveur est la carte à puce et le client
l'application cliente (terminal). La communication est une relation de type maître-
esclave, où la carte est systématiquement esclave : elle n’est jamais source d’une
opération, elle ne fait répondre à des demandes émises par l’utilisateur via le CAD.
L'applet située sur la carte à puce attend les requêtes émanant de l'utilisateur. Le
dialogue entre la carte et l'application cliente s'effectue avec des trames de données
appelées APDU (Application Protocol Data Unit) et commence toujours par une trame de
type command APDU en provenance du terminal. L'applet située sur la carte exécute
alors l'action indiquée dans la command APDU et répond au terminal avec une trame
response APDU. Ainsi, on observe toujours le schéma de communication suivant entre
une carte et un terminal: une command APDU suivie d'une response APDU.
L'Application Protocol Data Unit (APDU) est définie dans la norme ISO 7816-4. C'est
une classe du JCRE (Java Card Runtime Environment). Elle transfère les données à
travers un buffer de 37 octets au moins : 5 octets pour l'entête et 32 pour les données.
En effet avec sa méthode getBuffer(), elle récupère l'APDU du buffer de transfert des
données. Avec cet objet il peut positionner le sens du transfert avec la méthode
setOutgoing() pour envoyer les données ou la méthode setIncomingandReceive() pour
recevoir les données. Pour envoyer des données elle utilise la méthode sendBytes() qui
prend en paramètres l'offset et la taille des données à envoyer.
La taille des données peut être plus grande que celle du buffer de l'APDU. Dans ce cas
la méthode sendBytesLong() qui prend en plus des deux paramètres de la méthode
sendBytes() un troisième qui est un tableau a partir duquel les données sont envoyées.
Ainsi les données peuvent être divisées en plusieurs blocs qui seront envoyées à la suite.
Pour une bonne communication, il faut cependant respecter la norme ISO 7816-4.
Les tables suivantes illustrent respectivement des formats de command APDU et
de response APDU.
APDU de commande
Command APDU
Mandatory Header
Conditional Body
CLA INS P1 P2 Lc Data Field Le

L'en-tête (Mandatory Header) code la commande voulue. Il se compose de quatre
champs, chacun ayant une longueur de 1 octet.
• CLA: Classe de la commande à exécuter. Cet octet est employé pour identifier une
application.
• INS: Cet octet permet de définir l'instruction souhaitée (ex
: B0 pour Read Binary
et D0 pour Writing Binary ).
• P1-P2: permet de spécifier des paramètres de l’instruction à la command APDU.

Filière IR


Promo 2000

Année 2003 Page 17

Le corps (Conditional Body) se compose de trois champs :
• Lc: spécifie le nombre d’octets dans le champ de données de la command APDU.
Ce champ est optionnel.
• Data Field : champ de données de Lc octets. Il sert à transmettre les données
associées à la commande. Dans le cas général (pour les instructions
non-définies dans la norme : CLA compris entre D0 et EF) ce champ
est libre et dépend du protocole défini par le développeur.
• Le: spécifie le nombre d’octets prévus dans la zone d'information de la réponse
APDU au CAD.
Exemple d’APDU de commande
: une APDU de sélection
- CLA=0X où X dépend du niveau de sécurité et du canal choisis, en
général X=0.
- INS=A4 : instruction de sélection.
- P1=04 : sélection directe à partir du nom de fichier.
- P2=00 : sert à sélectionner le type de retour et le type de sélection si
plusieurs occurrences existent.
- Lc=09 : longueur de la chaîne de caractère « MON APPLET »
- Données = codage hexadécimal de « MON APPLET » : nom de
l’application à sélectionner.
- Le est vide : pas de données de retour. Le retour contiendra donc 2 octets
indiquant comment la sélection s’est déroulée.
APDU de réponse
Les trames APDU renvoyées par le JCRE sont formées des champs suivants :
Response APDU
Conditional Body
Mandatory Trailer
Data Field (L octets) SW1 SW2

• Data Field (L octets): ce champ facultative est spécifique à chaque commande.
Ainsi, 3 cas sont envisageable selon la longueur Le spécifiée dans l’APDU de
commande.
o L = Le alors l’APDU est renvoyée telle quelle au CAD.
o L<Le alors l’APDU de réponse est ‘61XY’, où XY= L, ce qui signifie que L
octets sont en attente et pourront être lus par une APDU de
commande « GET RESPONSE » : 00C00000XY.
o L>Le alors l’APDU de réponse est formé des Le premier octets de la
réponse suivis de ‘61XY’, où XY= L – Le, ce qui signifie que XY
octets sont encore en attente et pourront être lus par une ou
plusieurs APDU de commande « GET RESPONSE ».
Filière IR


Promo 2000

Année 2003 Page 18

• SW1 et SW2 indiquent le statut de traitement de la commande APDU dans une
carte. Ils indiquent si la commande s’est bien déroulée. C’est le JCRE (et non
l’Applet) qui déterminent la valeur de ces 2 octets. L’Applet peut cependant influer
sur ces valeurs en levant une exception. Celle-ci sera ensuite récupérer par le
JCRE qui formera le mot correspondant. Le tableau suivant reprend quelque
valeurs que peuvent prendre SW1 et SW2 :
SW1 – SW2 Signification Exception levée par l’Applet
9000 L’instruction s’est bien déroulée. Aucune
61XY
L’instruction s’est bien déroulée
mais il reste des données de
réponse.
Aucune
6
E
00 CLA non supportée par l’application ISO7816.SW_CLA_NOT_SUPPORTED
6D00 INS non supportée par l’application ISO7816.SW_INS_NOT_SUPPORTED
6B00 Mauvais paramètres P1-P2 ISO7816.SW_INCORRECT_P1P2

Exemple de communication avec une application cliente





Filière IR


Promo 2000

Année 2003 Page 19

Une opération d’utilisation de la carte est généralement composée des étapes suivantes :
• Sélection de l’Applet :
o Le JCRE reçoit une APDU de sélection indiquant l’Applet à selectionner.
o Si une autre Applet est active, il appelle la méthode deselect() de celle-ci.
o Il appelle la méthode select() de l’Applet à sélectionner.
o Il appelle ensuite la méthode process(apdu) en transmettant à celle-ci
l’APDU de sélection.
o Le JCRE renvoie alors une APDU indiquant si la sélection s’est bien
déroulée.
• Communication avec l’Applet :
o Le CAD envoie une APDU de commande au JCRE.
o Le JCRE transmet cette APDU à l’Applet en appelant la méthode
process(apdu).
o L’Applet exécute l’instruction correspondante.
o Le JCRE renvoie une APDU de réponse au CAD. Cette APDU est formée à
partir des informations renvoyées par l’Applet.
Le JCRE (Java Card Runtime Environement ) est implémentation sur la carte, de la
machine virtuelle JavaCard et des API. Il gère le stockage des variables persistantes ainsi
que l’enregistrement des Applets. Le JCRE organise aussi la communication entre le
lecteur de la carte (CAD) et les applications. Lors d’une opération, le JCRE reçoit les
informations venant du CAD (sous forme d’APDU) et il exécute alors la méthode
correspondante.
En fait, une trame APDU est vue par l’Applet comme un tableau du byte que le JCRE est
chargé de remplir au fur et à mesure que l’Applet a besoin de données ou qu’elle en
renvoie. Un seul buffer est utilisé. Le JCRE, comme l’Applet, remplace au fur et à mesure
les données correspondant à l’instruction précédente.

Description de l’applet
Au niveau de la communication avec l’applet, les trames sont conçues de tel façon que le
champ « Data Field » est composé comme il suit :



Comme on peut donc le voir, un rendez-vous est représenté par une taille fixe de 65
octets. Le champs « with » correspond à la personne avec qui le rendez-vous est pris, et
le champ « type RDV » correspond, comme son nom l’indique au type de rendez-vous
(bureau, client, personnel,…). Il sont eux aussi représenté par des tailles fixes
respectivement de 20 et 24 octets.
ID
RDV
ID
person
Année
mois
j
our
Heure
début
Min
début
Heure
fin
Min
fin
with
Type
RDV
3 octets 2 4 2 2 2 2 2 2 20 24
Filière IR


Promo 2000

Année 2003 Page 20

Pour simplifier la récupération des différents paramètres qui vont constituer un rendez-
vous, nous traitons donc avec des champs de longueur fixe.
Les codes d’instruction (INS) pour communiquer avec la carte sont les suivants :
0x40 : validate
0x50 : encrypt
0x60 : pinChange
0x69 : resetNbRdvTot
0x70 : addRDV
0x71 : ViewRDV

La communication avec l’applet se fait avec le fichier “CnxJavaCard”. En fait, pour stocker
des données dans la carte on ne peut lui envoyer que des tableau de ‘int’. C’est pourquoi,
nous utilisons différentes fonctions de conversion afin de convertir les chaînes de
caractères que l’on veut stocker en IntArray.



Filière IR


Promo 2000

Année 2003 Page 21

Description de la réalisation

Le but de cette partie est de fournir une sorte de manuel de l’utilisateur et de
l’administrateur.
Tous les modules sont entièrement en anglais pour permettre la plus grande diffusion du
logiciel et respecter le standard international.
Module serveur
Lancement
Le serveur se lance en exécutant le fichier start_server.bat
Avant de lancer le serveur, il faut avoir lancé le service de nommage. Dans le cas
contraire, on sera informé de l’indisponibilité de ce service avec une fenêtre de dialogue.

Lors du lancement du serveur, le service va s'activer sur la machine. Un affichage indique
l'avancement et la réussite de l'opération. En parallèle, les fichiers de la base de données
sont créés s’ils n’existent pas et sont ensuite lus.
Une console d'administration va être lancée en cas de succès. Celle-ci va permettre
d'administrer les personnes et les types de rendez-vous utilisables dans le logiciel.
La première fenêtre qui apparaît va vous demander le mot de passe d’administration
(unique et ne dépendant donc pas de la personne qui se connecte).

Filière IR


Promo 2000

Année 2003 Page 22

Celui-ci est « secret » et sera par défaut entré pour des raisons de simplicité mais ceci ne
sera bien sur pas le cas dans la version de "distribution" du logiciel. Si le mot de passe
entré est mauvais, le message suivant apparaît et bloque l’entrée.

Si vous ne souhaitez pas entrer dans la console, il vous suffit de cliquer sur le bouton
« No Console ». La fenêtre de dialogue va alors disparaître, sans couper le démon du
serveur.
Console de management
Si le mot de passe d'administration est correct, vous arrivez sur une fenêtre découpée en
trois parties. De haut en bas, vous avez :
- la partie pour l'administration des personnes,
- la partie pour l'administration des types de rendez-vous,
- des boutons.

Chaque élément d'administration va proposer 2 possibilités :
- l'ajout d'un élément,
- la mise à jour (modification et suppression) d'un élément.
Les boutons vont permettre respectivement (de gauche à droite) de fermer la console et
de garder le serveur lancé ou d'éteindre complètement l’application (démon et console).
Le dernier bouton permet d’avoir de l’aide sur l’utilisation de l’application lancée.
Remarque
: La fermeture de la fenêtre par la croix de la barre de titre entraîne
uniquement la fermeture de la console (sans arrêt du démon).
Filière IR


Promo 2000

Année 2003 Page 23

Administration
Personnes
Lorsque l'on choisit d'ajouter ou de supprimer une personne, on tombe sur des fenêtres
identiques.

Celles-ci contiennent des champs modifiables, initialisés avec les valeurs de la base s'il
s'agit d'une modification.
Les champs particuliers sont :
- le Job title qui va définir, entre autre, la possibilité ou d’administrer ou non d’autres
calendriers. Par défaut, seules les « secretary » ont le droit d’accéder et de manager
d’autres agenda que le leur ;
- macKey, authKey et keyKey sont les champs permettant de connecter d’une manière
sécurisée à la carte.
Remarque : Deux personnes différentes ne peuvent avoir le même couple nom/prénom,
dans ce cas, la fenêtre apparaît suivante lors de l’ajout et de l’enregistrement. Une
fenêtre semblable apparaîtra si on oublie d’entrer le nom de la personne (que nous
exigeons pour l’ergonomie et bien qu’il ne soit pas une clé dans la base de données).

Filière IR


Promo 2000

Année 2003 Page 24

Les actions possibles sont la sauvegarde avec le bouton « Save » qui créera la nouvelle
personne si vous aviez choisi un ajout. Ce même bouton enregistrera les modifications
dans le cas d’une mise à jour.
Le bouton « Delete » permet de supprimer la personne. Ce bouton n’est pas activé dans
le cas d’un ajout. La suppression d’une personne n’entraîne pas la suppression de ces
rendez-vous car sa disparition dans le logiciel n’implique pas sa disparition réelle. Ainsi,
d’autres personnes peuvent encore avoir des rendez-vous avec elle.
Le bouton « Close », tout comme la croix de la barre de titre, ferme la fenêtre sans
sauvegarder.
A noter que si vous avez choisi de modifier la personne symbolique « Personne
extérieur », vous ne pourrez faire aucun changement dessus. Vous pourrez par contre la
supprimer ce qui est, bien sur, fortement déconseillé dans le cas d’une utilisation
courante de l’AgenCard.
Type de RDV
La fenêtre qui s’affiche pour l’administration des types de rendez-vous est la suivante.

Ses actions et ses caractéristiques sont exactement les mêmes que celles de la fenêtre
d’administration des personnes.
NB
: le champ Désignation étant la clé pour retrouver le type de rendez-vous, si est
entrée une désignation déjà utilisée, le logiciel bloquera l’ajout et affichera la fenêtre de
dialogue suivante. Une fenêtre semblable apparaîtra si vous avez oublié d’entrer la
désignation.

Filière IR


Promo 2000

Année 2003 Page 25

Module client
Le client se lance avec le script start_client.bat
Avant de lancer le client, il faut bien sur avoir le service de nommage et le serveur de
lancé. Sinon, le message suivant apparaît.

Remarque
: on peut se connecter sans avoir de carte.
Login et type de consultation
Si tout est en ordre, la fenêtre de login suivante apparaît.

Les deux premiers champs vont permettre d’identifier la personne qui se connecte. Il faut
donc entrer son nom et son mot de passe personnels. Une vérification est alors faite par
rapport aux données contenues dans la base de données. En cas d’erreur, un message
d’erreur apparaît.
Filière IR


Promo 2000

Année 2003 Page 26


Le champ « Manage this agenda » permet, comme son nom l’indique, de gérer les
rendez-vous d’une autre personne.
Dans le menu déroulant, on peut donc choisir, « Mine » et dans ce cas, on entrera dans
son agenda, ou choisir une autre personne.
Bien sur, pour des raisons de confidentialité et de sécurité, seules les personnes ayant un
poste prédéfini (individu identifié par son nom/mot de passe) pourront visualiser l’agenda
d’une autre personne. Par défaut, le poste ayant ces droits privilégiés est « secretary ».

A noter que le calendrier de la personne symbolique « Personne Extérieur » ne peut-être
bien évidemment géré.


Fenêtre principale
La fenêtre principale peut être découpée en cinq parties :
1. Le titre qui rappelle le nom du propriétaire de l’agenda en cours (et non le nom
de la personne gérant l’agenda dans le cas de la gestion de l’agenda d’une autre
personne)
2. Le choix du jour (année, mois et jour) initialisé au jour courant
3. La liste des rendez-vous enregistrés dans la base de données du jour sélectionné
pour l’agenda choisi
4. Les boutons d’action pour modifier le calendrier du jour choisi
5. Les boutons d’action sur l’application
Filière IR


Promo 2000

Année 2003 Page 27

1
2 3
4
5

Le choix du jour peut se faire de plusieurs façons.

L’année peut être entrée à la main ou être atteinte par les petits boutons qui font défiler
une par une chaque année. Les années non gérables sont affichées rouge lorsqu’on les
entre à la main (années avant JC et après l’an 99 999 999, la pérennité du logiciel est
donc incontestable ! ).
Les mois peuvent être choisis dans le menu déroulant, ou comme pour l’année, grâce à
des boutons.
Le jour quant à lui se choisi en cliquant dessus.
Remarque
: les années bissextiles sont gérées par l’AgenCard.
Lorsqu’un jour est sélectionné, son calendrier est affiché dans la partie prévue à cet effet.
Filière IR


Promo 2000

Année 2003 Page 28


Cette partie rappelle le jour choisi au format courant et donne un tableau des rendez-
vous présents dans la base de données pour ce jour.
Pour chaque rendez-vous est précisé l’heure de début, l’heure de fin, la personne avec
qui se fera l’entretien et le type de rendez-vous.
Lorsque l’on choisit une ligne par simple clic avec la souris, on va pouvoir modifier le
rendez-vous sélectionné. Le bouton Modify devient en effet cliquable et, surtout, une
fenêtre de mise à jour de rendez-vous apparaît.
Ajout et modification de rendez-vous
Ajout d’un rendez-vous
L’ajout d’un rendez-vous se fait par le clic sur le bouton new de la fenêtre principale.
Une fenêtre s’ouvre alors avec la date choisie sélectionnée dans la fenêtre principale (les
heures par défaut sont de 10h00 à 12h00 et ont été choisies arbitrairement).
Filière IR


Promo 2000

Année 2003 Page 29


Dans cette fenêtre, on va pouvoir préciser tout ce qui caractérise un rendez-vous.
De haut en bas, on peut commencer (l’ordre de réalisation est libre) par choisir la
personne avec qui on veut prendre le rendez-vous. On peut se choisir soit, pour se
réserver un créneau horaire (on pourra alors utiliser le type de rendez-vous « Intervalle
de temps réservé » pré configuré dans le logiciel). Pour avoir la description de la
personne choisie, on peut cliquer sur le bouton View Personne details. La fenêtre
suivante contenant des champs non modifiables apparaît alors.

Le deuxième champ de la fenêtre d’ajout d’un rendez-vous est le type de rendez-vous.
On le choisit, comme pour la personne, avec un menu déroulant en fonction des valeurs
présentes dans la base de données. On a aussi un bouton permettant de découvrir le
détail de ce type de rendez-vous.
Filière IR


Promo 2000

Année 2003 Page 30


Ensuite, on peut modifier la date, soit par des menus déroulants, soit en cliquant sur le
bouton « Choose ». Celui-ci va faire apparaître une fenêtre présentant un calendrier
semblable à celui de la fenêtre principale, initialisé au jour courant.

On peut alors choisir une date, de la même façon que dans la fenêtre principale ou
annuler.
Ensuite, on choisit les horaires de début et de fin par tranche de 15 minutes (intervalle
choisi pour permettre une bonne granularité sans trop alourdir les calendriers).
Ensuite, on peut annuler ce qu’on vient de faire ou sauvegarder avec, respectivement,
les boutons « Close » et « Save ».
Lors de la sauvegarde, après avoir vérifié que l’heure de début se trouve bien avant celle
de fin, plusieurs contrôles sont effectués pour repérer les conflits de calendrier. Le
premier est de voir si l’on (ou la personne pour qui on gère le calendrier) n’a pas déjà un
rendez-vous aux horaires choisis. En cas de conflit, un message d’erreur est affiché.
Filière IR


Promo 2000

Année 2003 Page 31


Le deuxième contrôle concerne la personne avec qui on a rendez-vous qui est permis
grâce à la base de données distribuée commune pour tous. On regarde alors dans son
calendrier, récupéré en temps réel sur le serveur (c’est à dire qu’une modification faite
par un autre logiciel client sera répercutée en direct sur tous les autres calendriers), si ce
rendez-vous n’est pas en conflit avec un autre.

Cette dernière vérification ne se fait pas, bien sur, dans le cas d’un rendez-vous pris avec
une « Personne Extérieure ».
Après toutes ces vérifications, le rendez-vous est ajouté dans notre agenda (ou celui de
la personne gérée), mais aussi à la personne avec qui est le rendez-vous, grâce à la
base de données centralisée, sauf si la nouvelle personne est nous-même.
Une fenêtre propose alors d’envoyer un mail à la personne avec qui on a rendez-vous
pour la prévenir de ce rendez-vous.

Les emails sont par défaut initialisés avec les valeurs de la base de données.
Si l’on clique sur le bouton « Cancel », l’envoi du mail est annulé (mais les modifications
sont malgré tout effectuées). Le bouton « Send » déclenche l’envoi du mail et ferme la
fenêtre.
Filière IR


Promo 2000

Année 2003 Page 32


En cas de problème comme l’inexistence d’une connexion à internet, un message
apparaît (la aussi les modifications sont malgré tout effectuées).

Modification d’un rendez-vous
Lorsque l’on clique sur un rendez-vous dans le tableau de la fenêtre principale, une
fenêtre s’ouvre pour modifier le rendez-vous.
Filière IR


Promo 2000

Année 2003 Page 33


La fenêtre alors affichée est exactement la même que pour l’ajout d’un rendez-vous,
mais avec ses champs correctement initialisés aux valeurs du rendez-vous sélectionné.
Les contrôles effectués sont aussi les mêmes et les actions se font aussi sur notre
rendez-vous.
Par contre, mes modifications d’un rendez-vous ne se font pas sur le calendrier de la
personne avec qui est le rendez-vous. En effet, nous avons préféré ne pas rendre
possible cette fonctionnalité pour nous assurer que la personne avec qui le rendez-vous
était, sera bien informée du changement. Toutefois, nous proposons, comme lors de
l’ajout d’un rendez-vous, l’envoi d’un email à la personne concernée.
Remarque
: sur la modification porte sur la personne avec qui on a rendez-vous, un
nouveau rendez-vous est créé pour cette nouvelle personne, et deux envois de mail sont
proposés :
- l’annulation de l’ancien rendez-vous à la personne avec qui on avait l’ancien rendez-
vous
- l’ajout du nouveau rendez-vous à la personne avec qui on a rendez-vous maintenant.
Ce mail n’est pas proposé si la nouvelle personne est nous-même.

Dans le cas de la modification, le bouton Delete est actif pour supprimer ce rendez-vous.
Une fenêtre de confirmation est affichée lorsque l’on fait ce choix.

Filière IR


Promo 2000

Année 2003 Page 34

Comme pour l’ajout et la modification, un envoi de mail d’annulation est proposé.
Remarque
: Pendant l’ajout ou la modification d’un rendez-vous, la fenêtre principale
est toujours accessible. Cela permet d’ouvrir plusieurs fenêtres d’ajout / modification de
rendez-vous pour des jours différents ou non permettant de consulter / modifier les
calendriers d’autres jours (et gérer les conflits…).
NB
: Après un ajout ou une modification, le tableau des rendez-vous de la fenêtre
principale est mis à jour.
Boutons d’action sur le logiciel
Les boutons placés tout en bas de la fenêtre principale permettent d’obtenir une aide sur
ce module du logiciel et de fermer la fenêtre.
Le bouton du centre permet quant à lui de connecter une carte à puce et de mettre
dessus ses rendez-vous. Lorsque l’on clique sur ce bouton, on tente de se connecter à la
carte avec les informations de la personne contenue dans la base de données.
Une fenêtre de login apparaît alors invitant à entrer le code pin (entré par défaut pour
simplifier la démarche).

Filière IR


Promo 2000

Année 2003 Page 35

Module autonome de visualisation
Ce module autonome de l’AgenCard va permettre de visualiser le contenu d’une carte
agenda sans connexion au serveur.
Le début de la procédure est identique à celle du bouton « Update » de l’application
cliente.
En raison de la complexité des informations à entrer pour la connexion sécurisée, nous
avons développé une fonctionnalité de sauvegarde. On peut grâce à cette dernière
enregistrer les informations fournies, sur le disque dur. Cet enregistrement se fait dans le
répertoire personnel de la personne connectée, ce qui rend le logiciel multi-utilisateurs.
Cela se fait en cochant tout simplement la case « Save » prévue à cet effet. Dans ce cas,
à la prochaine connexion, les champs seront automatiquement initialisés avec les valeurs
sauvegardées après lecture du fichier.
Lorsque l’on appuie sur le bouton « Enter », on va vérifier que la carte est bien connectée
et qu’on peut y accéder :

Si ce n’est pas le cas, on a les messages suivants qui apparaissent.

Si tout se passe bien, on stocke dans la mémoire de la machine le contenu de la carte
pour accélérer les démarches suivantes et ce qui permettra de déconnecter la carte.
Ensuite, la fenêtre suivante apparaît.
Filière IR


Promo 2000

Année 2003 Page 36


Elle est composée d’un sélecteur de jour sur la gauche et d’un panel de visualisation sur
la droite, sous la forme d’un tableau de rendez-vous.
Pour le choix de la date, l’année peut être entrée à la main ou être atteinte par les petits
boutons qui font défiler une par une chaque année. Les années non gérables sont
affichées en rouge lorsqu’on les entre à la main.
Les mois peuvent être choisis dans le menu déroulant, ou comme pour l’année, grâce à
des boutons.
Le jour quant à lui se choisi en cliquant dessus.
Lorsqu’un jour est choisi, on obtient le calendrier de ce jour sur la droite, sous la forme
d’un tableau de rendez-vous.
Les boutons dans le bas de la fenêtre permettent d’obtenir de l’aide et de fermer
l’application.

Filière IR


Promo 2000

Année 2003 Page 37

Code commenté
Pour ne pas surcharger le rapport, nous allons uniquement présenter dans cette partie
les classes utilisant le corba et la javacard. Le reste de l’application représente la base de
données et la partie graphique développé en Swing mais, bien que représentant un
volume bien supérieur, ne correspond pas à l’objet principal de ce projet. Toutes les
sources et la javadoc sont bien sûr consultables avec ce rapport.
Partie corba
Classe Serveur
package fr.umlv.agencard.src;

import java.util.*; // Pour properties...
import javax.swing.JOptionPane;
import org.omg.CORBA.*; // Pour l’accès à l’ORB
import org.omg.CosNaming.*; // Pour l’accès au service de nommage
import org.omg.CosNaming.NamingContextPackage.*; // idem
import org.omg.PortableServer.*;
import fr.umlv.agencard.src.corba.*;

// Le serveur est lancé par le script start_serveur.bat
// apres init repository par script start_naming.bat
// NB : le nom de la machine sera concatene
// a "sb_" pour former le nom de serveur
// declare au service de nommage

/**
* Application java encapsulant les servants CORBA
* -init acces ORB
* -creation servant ServeurAgent
* -init acces au naming service
* -inscription du servant au naming service (binding)
* --------------------------------------------
*/
public class Serveur {

public static void main(String args[]) {
ORB orb = null; // Référence a l'ORB
POA poa = null; // Référence au POA
ServeurAgentImpl sb; // Référence au servant
NameComponent[] path; // Pour le bind du service de nommage
String home;
home = System.getProperty("user.home");
showDialog(home);
try { // Voiture balai pour les exceptions

// Initialisation de l’accès à l’ORB
try {
// Initialisation de l'ORB
orb = ORB.init(args, System.getProperties());



// Récupération ref. du rootPOA
poa =

POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
} catch (SystemException ex) {
showDialog("Error while ORB initialisation");
Filière IR


Promo 2000

Année 2003 Page 38

System.exit(2);
}

// Création du servant ServeurAgent
sb = new ServeurAgentImpl("Mon Agencard");

// Calcul de l’IOR
ServeurAgent href =

ServeurAgentHelper.narrow(poa.servant_to_reference(sb));

// Initialisation de l’acces au service de nommage
org.omg.CORBA.Object obj = null;
try {
obj =
orb.resolve_initial_references("NameService");
// cf option ligne lancement pour ior Naming
Service
// (script start_serveur)
} catch (org.omg.CORBA.ORBPackage.InvalidName ex) {
showDialog("Naming service not reachable");
System.exit(1);
}
NamingContextExt nc = NamingContextExtHelper.narrow(obj);
if (nc == null) {
showDialog("Problem with the naming service");
System.exit(1);
}

// Inscription du servant au service de nommage (binding)
String name = "sb_" + args[0];
try { // Création du contexte de nom et (re)bind sur sb
// Le rebind marche même si déja inscrit : ce qui
évite d’ avoir a faire un unbind...
System.out.println("Serveur : bind " + name);
path = nc.to_name(name);
nc.rebind(path, href);
System.out.println("Serveur : bind Ok");
} catch (Exception ex) {
showDialog("Bind error");
System.exit(2);
}

// Activation du POA
System.out.println("Serveur : ready");
poa.the_POAManager().activate();

// Attente du client
orb.run();




// Voiture balai pour les exceptions
} catch (Exception ex) {
showDialog("Corba initialisation error");
System.exit(2);
}
}

public static void showDialog(String message) {
JOptionPane.showMessageDialog(
null,
message,
"Server error",
JOptionPane.ERROR_MESSAGE);
}
Filière IR


Promo 2000

Année 2003 Page 39

}
Filière IR


Promo 2000

Année 2003 Page 40

Classe Client
package fr.umlv.agencard.src;
// NB : nom machine concatene a "sb_" --> nom
// declare au NamingService pour serveur bancaire
import org.omg.CORBA.ORB;
import java.util.*; // Pour properties...
import org.omg.CORBA.*; // Pour l’accès à l’ORB
import org.omg.CosNaming.*; // Pour l’accès au service de nommage
import org.omg.CosNaming.NamingContextPackage.*; // idem
import fr.umlv.agencard.src.client.AgencardMainClient;
import fr.umlv.agencard.src.corba.ServeurAgent;
import fr.umlv.agencard.src.corba.ServeurAgentHelper;
// Le main cree une instance et appelle son init()
// Init (issu version applet) :
// -consulte le NamingService --> ior ServeurAgent
// -cree une instance de l'interface ItfServeurAgent
public class Client {
private AgencardMainClient ui; // IHM
private ServeurAgent serveurAgent; // Proxy serveur agent
// Initialisation de l’instance client
public void init(String args []) {
ORB orb = null;
// Initialisation de l’ORB
try {
orb = ORB.init(args, System.getProperties ());
} catch (Exception e) {
System.out.println("Client : exception init ORB : " + e);
System.exit (1);
}
// Recherche service de nom
org.omg.CORBA.Object obj = null;
try {
obj = orb.resolve_initial_references("NameService");
} catch (org.omg.CORBA.ORBPackage.InvalidName ex) {
System.out.println ("Client : naming service pas dispo "+ex);
System.exit (1);
}
// Consultation du service de nommage
NamingContextExt nc = NamingContextExtHelper.narrow (obj);
if (nc == null) {
System.out.println ("Client : pb Naming context");
System.exit (1);
}
String name = "sb_" + args [0];
try { // Resolution du nom
System.out.println ("Client : resolve " + name);
org.omg.CORBA.Object o = nc.resolve_str (name);
serveurAgent = ServeurAgentHelper.narrow (o);
} catch (Exception ex) {
System.out.println ("Client : pb resolve ou narrow : "+ex);
System.exit (2);
}
ui = new AgencardMainClient(serveurAgent); // lancement interface
}
public static void main (String args []) {// main de l'application client
Client client = new Client ();
client.init (args);
}
}
Filière IR


Promo 2000

Année 2003 Page 41


Classe ServeurAgentImpl

package fr.umlv.agencard.src;

import fr.umlv.agencard.src.corba.ServeurAgentPOA;
import fr.umlv.agencard.src.serveur.AgencardMainServer;
import fr.umlv.agencard.src.serveur.database.PersonneManager;
import fr.umlv.agencard.src.serveur.database.RDVManager;
import fr.umlv.agencard.src.serveur.database.TypeRDVManager;

public class ServeurAgentImpl extends ServeurAgentPOA {

private PersonneManager personneManager;
private TypeRDVManager typeRdvManager;
private RDVManager rdvManager;

public ServeurAgentImpl(String name) {
personneManager = new PersonneManager();
typeRdvManager = new TypeRDVManager();
rdvManager = new RDVManager();

new AgencardMainServer(personneManager, typeRdvManager,
rdvManager);
}

public PersonneManager importPersonneManager() {
return personneManager;
}

public RDVManager importRDVManager() {
return rdvManager;
}

public TypeRDVManager importTypeRDVManager() {
return typeRdvManager;
}
}

Classe AgentImpl

package fr.umlv.agencard.src;

import fr.umlv.agencard.src.client.AgencardMainClient;
import fr.umlv.agencard.src.corba.ServeurAgent;

public class AgentImpl {
private AgencardMainClient ui; // IHM

// Constructeur
public AgentImpl(ServeurAgent serveurAgent) {
// Lancement de l'interface
ui = new AgencardMainClient(serveurAgent);
}

}
Filière IR


Promo 2000

Année 2003 Page 42

Partie Javacard
Pour ne pas surcharger cette partie du rapport, nous avons placé ci-après le code de
l’applet, le code qui va permettre la communication avec la carte, ainsi qu’une classe
proposant divers outils de conversion.
Applet

package applet;

import javacard.framework.*;
import javacard.security.*;

public class AgencardApplet extends javacard.framework.Applet {

/* constants declaration */
// code of CLA byte in the command APDU header
final static byte Wallet_CLA =(byte)0x80;

// codes of INS byte in the command APDU header
final static byte Validate = (byte) 0x40;
final static byte Encrypt = (byte) 0x50;
final static byte PinChange = (byte) 0x60;
final static byte ResetNbRdvTot = (byte) 0x69;
final static byte AddRDV = (byte) 0x70;
final static byte ViewRDV = (byte) 0x71;
final static byte ResetidxRdvRead = (byte) 0x72;

// maximum number of incorrect tries before the PIN is blocked
final static byte PinTryLimit =(byte)0x03;

// maximum size PIN
final static byte MaxPinSize =(byte)0x04;


final static short SW_WRONG_PIN = (short) 0x6300;
final static short LG_TRAME = (short)65; // longueur des trames
final static short NB_MAX_RDV = (short)200; // nombre max de RDV
final static short SW_AGENCARD_FULL = (short)0x6666; // plus de
place sur la carte

/* instance variables declaration */
OwnerPIN pin;
byte rdvs[];
short nbRdvTot = (short)0; //nb total de rdv sur la JC
short idxRdvRead = (short)0;
final static short nbOfByteInDataField = (short)0x65;
DESKey key;
Signature signature;

private AgencardApplet(byte buffer[],short offset,byte length) {

pin = new OwnerPIN(PinTryLimit, MaxPinSize);
rdvs = new byte[(short)(LG_TRAME*NB_MAX_RDV)];
key =
(DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES_TRANSIENT_RESET,KeyBuilder.
LENGTH_DES,false);
signature =
Signature.getInstance(Signature.ALG_DES_MAC8_ISO9797_M1,false);
signature.init(key,Signature.MODE_SIGN);
if (buffer[offset] == (byte)0) {
register();
}
else {
Filière IR


Promo 2000

Année 2003 Page 43

register(buffer, (short)(offset+1)
,(byte)(buffer[offset]));
}
}

public static void install(byte buffer[],short offset,byte length){
new AgencardApplet(buffer, offset, length);
// create a AgencardApplet applet instance (Simulator) *!*

}

public boolean select() {
// reset validation flag in the PIN object to false
pin.reset();
// returns true to JCRE to indicate that the applet
// is ready to accept incoming APDUs.
return true;
}

public void process(APDU apdu) {
// APDU buffer
// APDU object carries a byte array (buffer) to
// transfer incoming and outgoing APDU header
// and data bytes between card and CAD
byte buffer[] = apdu.getBuffer();

// Implement a select handler
if (selectingApplet()) {
ISOException.throwIt(ISO7816.SW_NO_ERROR);
}

// verify that if the applet can accept this
// APDU RDV
if (buffer[ISO7816.OFFSET_CLA] != Wallet_CLA)
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);

byte ins = buffer[ISO7816.OFFSET_INS];
if (ins == ViewRDV) viewRDV(apdu);
else if (ins == Validate) validate(apdu);
else if (ins == Encrypt) encrypt(apdu);
else if (ins == PinChange) PinChange(apdu);
else if (ins == ResetNbRdvTot) resetNbRdvTot(apdu);
else if (ins == AddRDV) addRDV(apdu);
else ISOException.throwIt (ISO7816.SW_INS_NOT_SUPPORTED);

} // end of process method

/** This method is called one time when the user wants update RDVs
from DataBase to Javacard
*/
private void resetNbRdvTot(APDU apdu) {

byte buffer[] = apdu.getBuffer();

nbRdvTot = (short)0;
} // end of validate method
private void resetidxRdvRead(APDU apdu) {
byte buffer[] = apdu.getBuffer();

idxRdvRead = (short)0;
} // end of validate method

/***** addRDV ******/
private void addRDV(APDU apdu) {

byte buffer[] = apdu.getBuffer();

Filière IR


Promo 2000

Année 2003 Page 44

// access authentication
if ( ! pin.isValidated() )
ISOException.throwIt
(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);

// indicate that this APDU has incoming data and
// receive data starting from the offset
// ISO7816.OFFSET_CDATA
byte byteRead = (byte)(apdu.setIncomingAndReceive());
if( (short)nbRdvTot < (short)NB_MAX_RDV ){

(short)0,(short)byteRead);
Util.arrayCopy( buffer, (short)(ISO7816.OFFSET_CDATA ),
//G enlevé
+3
rdvs, (short)(nbRdvTot *
LG_TRAME),(short)(LG_TRAME) );
nbRdvTot++;
}
else{
ISOException.throwIt( SW_AGENCARD_FULL
);
}
// // return successfully
return;

} // end of addRDV method

/****** viewRDV ***********/
private void viewRDV(APDU apdu) {

byte buffer[] = apdu.getBuffer();

// access authentication
if ( ! pin.isValidated() )
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);

// inform system that the applet has finished processing
// the command and the system should now prepare to
// construct a response APDU which contains data field

// nbOfByteInDataField correspond à LG_TRAME;
apdu.setOutgoing();

// indicate the number of bytes in the data field
apdu.setOutgoingLength((byte)nbOfByteInDataField);

// move the data into the APDU buffer starting at offset 0
if( idxRdvRead < nbRdvTot){//le le rdv est valide on l'envoi
Util.arrayCopy( rdvs, (short)(idxRdvRead*LG_TRAME),
//copy
directement et sans offset dans buffer APDU
buffer, (short)0,(short)(LG_TRAME) );
//le rdv.
idxRdvRead++;
}
else{
//On a lu tous les rdv de la carte...
idxRdvRead = (short)0;
//On informe l'appli avec une trame spécifique,
qu'il n’y a plus de RDV
for( byte i=0; i<(byte)65; i++ ){
buffer[(byte)i] = (byte)69;
//la trame vaut
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE comme END
}
}
Filière IR


Promo 2000

Année 2003 Page 45

// send LG_TRAME byte of data at offset 0 in the APDU buffer
apdu.sendBytes((short)0, (short)nbOfByteInDataField);

} // end of viexRDV method

/***************************/

private void validate(APDU apdu) {

byte buffer[] = apdu.getBuffer();

// retrieve the PIN data which requires to be valid ated
// the user interface data is stored in the data field of the
APDU
byte byteRead = (byte)(apdu.setIncomingAndReceive());

// validate user interface and set the validation flag in the
user
interface
// object to be true if the validation succeeds.
// if user interface validation fails, PinException would be
// thrown from pin.check() method.
if (!pin.check(buffer, ISO7816.OFFSET_CDATA, byteRead))
ISOException.throwIt(SW_WRONG_PIN);

key.setKey(buffer,(short)0);
} // end of validate method

private void encrypt(APDU apdu) {

byte buffer[] = apdu.getBuffer();

// get 4 bytes of data and return the encrypted result.
// access authentication
if ( ! pin.isValidated() )
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);

short byteRead = apdu.setIncomingAndReceive();

signature.sign(buffer,(short)5,byteRead,buffer,(short)0);
apdu.setOutgoingAndSend((short)0,(short)8);
}

private void PinChange(APDU apdu) {

byte buffer[] = apdu.getBuffer();

byte newPIN[] =
{(byte)buffer[ISO7816.OFFSET_P1],(byte)buffer[ISO7816.OFFSET_P1],(byte)buff
er[ISO7816.OFFSET_P1],(byte)buffer[ISO7816.OFFSET_P1]};
pin.update(newPIN,(short)0, (byte)4);
}
} // end of class AgencardApplet

Accès à l’applet
package fr.umlv.agencard.src.client.cnxjavacard;

import java.awt.*;
import java.util.Enumeration;
import java.util.Vector;

import javax.swing.JOptionPane;
import javax.swing.JTabbedPane;
Filière IR


Promo 2000

Année 2003 Page 46

import javax.swing.JPanel;

import com.sun.corba.se.internal.javax.rmi.CORBA.Util;

import fr.umlv.agencard.src.cardview.CardInfoFrame;
import fr.umlv.agencard.src.cardview.InsertCard;
import fr.umlv.agencard.src.client.tools.AgencardTools;
import fr.umlv.agencard.src.client.ui.LoginFrame;
import fr.umlv.agencard.src.client.ui.ManagerFrame;
import fr.umlv.agencard.src.serveur.database.RDVManager;
import fr.umlv.agencard.src.serveur.database.RDV;


/**
* Class of the AgenCard project
* En fait ça permet d'avoir un vector de vector de RDV.
* Warning le format date est xxxx par exemple 2003 et non 03.
* On ne gère pas les années 134 par exmple.
* @author AgenCard team
* @version 1.0 - Feb 27, 2003
*/

import slb.iop.*;
public class CnxJavaCard {
final static short LG_TRAME = 65;

private String typeJavaCardReader;
//sert à définir le lecteur de JC utilisé
private ManagerFrame manaframe;
private RDVManager rdvm; // Vector rdvs;
private int personId;
private short[] sDataOut; //sert à récupérer les bytes de la JC
//permettra d'afficher la liste des drivers dans une popup


java.awt.Choice cboReaders = new java.awt.Choice();

InsertCard insertCard;

/** Constructor
*
*/
public CnxJavaCard(int personId, String jcReaderType) {
//{{INIT_CONTROLS
insertCard = new InsertCard();
//avec ça on récupère les drivers de carte qui sont installés
this.personId = personId;
typeJavaCardReader = jcReaderType;
String[] ListReader = sIOP.ListReaders();
ListReader = sIOP.ListReaders();

if (ListReader.length > 0) {
for (int i = 0; i < ListReader.length; i++) {
cboReaders.add(ListReader[i]);
}
SymSIOP lSymSIOP = new SymSIOP();
sIOP.addIOPListener(lSymSIOP);
}
}

slb.iop.IOP sIOP = new slb.iop.IOP();
slb.iop.SmartCard iopCard = new slb.iop.SmartCard();
SymSCard lSymSCard = new SymSCard();
//StandardLog MyLog = new StandardLog("Standard Log");

private boolean bConnected = false;
private boolean bSecureChannel = false;
Filière IR


Promo 2000

Année 2003 Page 47

private int nextAPDU = 1;

class SymSIOP implements slb.iop.IOPListener {
public void CardRemoved(slb.iop.IOPEvent event) {
//disconnect from card
if (bConnected) { //mode connecter il faut mettre à jour
les champs dans la ManagerFrame
bConnected = false;
if (bSecureChannel) { //"Establish Secure Channel"
bSecureChannel = false;
}

iopCard.removeSmartCardListener(lSymSCard);
iopCard = new slb.iop.SmartCard();
}
}

public void CardInserted(slb.iop.IOPEvent event) {
//Detect when the card is inserted
insertCard.dispose();
}

public void ReaderRemoved(slb.iop.IOPEvent event) {
//Add reader removed code here
}

public void ReaderInserted(slb.iop.IOPEvent event) {
//Add reader insert code here
}
}
//classe utilisée avant pour la gestion des buffers entre autre.
//maintenant on passe directement par la méthode launch();

class SymSCard implements slb.iop.SmartCardListener {
public void DataSent(slb.iop.SmartCardEvent event) {
short[] myShort = event.getData();
String strHex = ShortArrayToHexString(myShort);
byte[] dataArray =
AgencardTools.HexStringToByteArray(strHex);
//ATTENTION
//MyLog.DataSent(dataArray);
}

public void DataReceived(slb.iop.SmartCardEvent event) {
short[] myShort = event.getData();
String strHex = ShortArrayToHexString(myShort);
byte[] dataArray =
AgencardTools.HexStringToByteArray(strHex);
//ATTENTION
//MyLog.DataReceived(dataArray);
}
}


/**
* Method updateRDVfromDBtoJC.
* @throws Exception
*/
public void updateRDVfromDBtoJC() throws Exception{
rdvm = new RDVManager();
String CLA;
String P1;
String P2;
String body;
String INS;
boolean result;
//1) Méthode cmdconnect
Filière IR


Promo 2000

Année 2003 Page 48

cmdConnect();
//2) Sélection de l'Applet Id.
CLA = "00";
P1 = "04";
P2 = "00";
body = "11223344556677";
INS = "A4";
result = LaunchAPDU(CLA, INS, P1, P2, body, "00");
//3) Vérification du code PIN
CLA = "80";
P1 = "00";
P2 = "00";
body = "00000000"; //code Pin sur 4 bytes
INS = "40";
result = LaunchAPDU(CLA, INS, P1, P2, body, "00");

//4) On peut passer aux choses sérieuses et enregistrer ts les
rdv sur la JC
CLA = "80";
P1 = "00";
P2 = "00";
body = "On remet à 0 le nb de rdv sur la carte";
INS = "69";
//String lengthOfTrameRdvId = "" + body.length();
String lengthOfTrameRdvId =
AgencardTools.ByteToHexString((byte) body.length());
result = LaunchAPDU(CLA, INS, P1, P2, body,
lengthOfTrameRdvId);
//On format le tableau avec la "35"
//rdvm.getRdvVector().size()
int nbRdvSent = 0;
for (Enumeration enumrdv = rdvm.getRdvVector().elements();
enumrdv.hasMoreElements() && (nbRdvSent <
AgencardTools.NB_RDV_MAX);
) {
RDV rdvToTransfert = (RDV) enumrdv.nextElement();
//ATTENTION AU CAST
//Tester si la personne du RDV récupéré correspond bien à
celle qui est loguée
if (rdvToTransfert.getPersonne() == personId) {
//on ne stocke sur la JC que les RDV de l'utilisateur connecté
body = rdvToTransfert.toAgencardFormat();
// body est la représentation d'un RDV en String
result =
LaunchAPDU(CLA, "70", P1, P2, body,
lengthOfTrameRdvId);
nbRdvSent++;
if (result == false){
throw new Exception ();
}
}
}
}

/**
* Method updateRDVfromJCtoDB.
* Méthode qui permet de lire tous les rendez vous de la JAVACARD.
* @return Vector
* @throws Exception
*/
public Vector updateRDVfromJCtoDB() throws Exception {
Vector rdvsFromJC = new Vector();
String CLA;
String P1;
String P2;
String body;
String INS;
Filière IR


Promo 2000

Année 2003 Page 49

boolean result;
//1) Méthode cmdconnect
cmdConnect();
//2) Sélection de l'Applet Id.
CLA = "00";
P1 = "04";
P2 = "00";
body = "11223344556677";
INS = "A4";
result = LaunchAPDU(CLA, INS, P1, P2, body, "00");
//3) Vérification du code PIN
CLA = "80";
P1 = "00";
P2 = "00";
body = "00000000"; //code Pin sur 4 bytes
INS = "40";
result = LaunchAPDU(CLA, INS, P1, P2, body, "00");

//4) On peut passer aux choses sérieuses et lire ts les rdv de
la JC
CLA = "80";
P1 = "00";
P2 = "00";
body = "";
INS = "72";
//String lengthOfTrameRdvId = "" + body.length();
String lengthOfTrameRdvId =
AgencardTools.ByteToHexString((byte) body.length());
result = LaunchAPDU(CLA, INS, P1, INS, body,
lengthOfTrameRdvId);
//On format le tableau avec la "35"
//rdvm.getRdvVector().size()
int nbRdvGet = 0;
for (nbRdvGet = 0; nbRdvGet < AgencardTools.NB_RDV_MAX;) {
//On récupère le buffer APDU.
byte[] buffer_recup = new byte[LG_TRAME];

for (int i = 0; i < LG_TRAME; i++) {
buffer_recup[i] = (byte) sDataOut[i];
}
byte[] marquerEndofRdv = new byte[LG_TRAME];
//marqueur fin des RDV Applet
//création de l'image du marqueur
for (byte i = 0; i < (byte) 65; i++)
marquerEndofRdv[(byte) i] = (byte) 69;

if (compare2ByteArrays(buffer_recup, marquerEndofRdv))
break;
else {

rdvsFromJC.addElement(
AgencardTools.ArrayByteToRDV(buffer_recup));
body = "";
result =
LaunchAPDU(CLA, "71", P1, P2, body,
lengthOfTrameRdvId);
nbRdvGet++;
}
}
if (rdvsFromJC.size() < 1) {
throw new Exception();
}
return rdvsFromJC;
}

/**
* Method compare2ByteArrays.
Filière IR


Promo 2000

Année 2003 Page 50

* @param a1
* @param a2
* @return boolean
*/
public boolean compare2ByteArrays(byte[] a1, byte[] a2) {
for (int i = 0; i < 65; i++) {
if (a1[i] != a2[i])
return false;
}
return true;
}


/**
* Method cmdConnect.
*/
void cmdConnect() {
if (!bConnected) {
slb.iop.SmartCard sCard = new slb.iop.SmartCard();
short[] sATR;
String strcardATR = "";

String[] ListReader = sIOP.ListReaders();

if (typeJavaCardReader.length() > 0) {
//Si je n'y arrive pas il faut mettre en dur le
type de carte dans la ligne ci dessous
boolean result = sIOP.Connect(sCard,
typeJavaCardReader, false);
//ListReader[cboReaders.getSelectedIndex()],
false);

if (result) { //mode connecté donc on affiche le
boutton "Disconnect"
bConnected = true;
try {
sATR = sCard.GetATR();
strcardATR = " - " +
ShortArrayToHexString(sATR);
} catch (slb.iop.slbException e) {
e.printStackTrace();
}

String strTemp = sCard.GetCardName();
// lblCardname.setText(strTemp);
// lblATR.setText(strcardATR);
iopCard = sCard;
iopCard.addSmartCardListener(lSymSCard);

}

}
} else {
bConnected = false;
if (bSecureChannel) {
try {
iopCard.BeginTransaction();

boolean result =
iopCard.ReleaseSecureChannel();

if (result) {
bSecureChannel = false;
} else {
bSecureChannel = false;
// "Release Failed"
}
Filière IR


Promo 2000

Année 2003 Page 51

iopCard.EndTransaction();
} catch (slb.iop.slbException e) {
e.printStackTrace();
}
}

iopCard.removeSmartCardListener(lSymSCard);
iopCard = new slb.iop.SmartCard();
}

}

/**
* Method cmdEstablish_ActionPerformed.
* @param event
*/
void cmdEstablish_ActionPerformed(java.awt.event.ActionEvent event) {
boolean result = false;
if (!bSecureChannel) {
try {
short[] MACKey;
short[] autKey;
short[] KEKKey;

MACKey =

HexStringToShortArray("404142434445464748494A4B4C4D4E4F");
autKey =

HexStringToShortArray("404142434445464748494A4B4C4D4E4F");
KEKKey =

HexStringToShortArray("404142434445464748494A4B4C4D4E4F");

iopCard.BeginTransaction();

result = iopCard.EstablishSecureChannel(MACKey,
autKey, KEKKey);

if (result) { //channel secure établit, boutton
"Release Channel"
bSecureChannel = true;
//Now list the Domains and Applets
short shortAID[];
result = false;

try {
//lstEnumAID.clear(); //ATTENTION


shortAID = iopCard.EnumerateAID((byte)
0x80);
short shortListAID[] = new
short[shortAID[0]];
for (int x = 0; x < shortListAID.length;
x++) {
shortListAID[x] = shortAID[x + 1];
}
// lstEnumAID.addItem("Card
Domain: " + ShortArrayToSpacedHexString(shortListAID));

//Security Domains and Instance Files
shortAID = iopCard.EnumerateAID((byte)
0x40);

int z = 0;
Filière IR


Promo 2000

Année 2003 Page 52

for (int y = 0; y < shortAID.length; y =
z) {
shortListAID = new
short[shortAID[y]];
z = z + shortListAID.length + 3;
for (int x = 0; x <
shortListAID.length; x++) {
shortListAID[x] = shortAID[x
+ y + 1];
}

if ((shortAID[z - 1] & (byte)
0x80) == 1) {
//
lstEnumAID.addItem("Secure Domain: " +
ShortArrayToSpacedHexString(shortListAID));
} else {
//
lstEnumAID.addItem("Instance: " +
ShortArrayToSpacedHexString(shortListAID));
}

}

//Load Files
shortAID = iopCard.EnumerateAID((byte)
0x20);

z = 0;
for (int y = 0; y < shortAID.length; y =
z) {
shortListAID = new
short[shortAID[y]];
z = z + shortListAID.length + 3;
for (int x = 0; x <
shortListAID.length; x++) {
shortListAID[x] = shortAID[x
+ y + 1];
}
//
lstEnumAID.addItem("Load Files: " +
ShortArrayToSpacedHexString(shortListAID));
}

//
lstEnumAID.setVisible(true);
} catch (slb.iop.slbException e) {
e.printStackTrace();
}
} else { //channel non monté ==> bouton "Establish
Secure Channel"
bSecureChannel = false;
// lstEnumAID.setVisible(false);
}
iopCard.EndTransaction();
} catch (slb.iop.slbException e) {
e.printStackTrace();
}
} else {
try {
iopCard.BeginTransaction();

result = iopCard.ReleaseSecureChannel();

if (result) { // appartition du bouton "Establish
Secure Channel"
bSecureChannel = false;
Filière IR


Promo 2000

Année 2003 Page 53

// lblEstablish.setText("");
} else { // appartition du bouton "Establish Secure
Channel"
bSecureChannel = false;

//"Release Failed";
// lstEnumAID.setVisible(false);
}
iopCard.EndTransaction();
} catch (slb.iop.slbException e) {
e.printStackTrace();
}
}
}

/**
* Method cmdQuit_ActionPerformed.
* @param event
*/
void cmdQuit_ActionPerformed(java.awt.event.ActionEvent event) {
System.exit(0);
}

/**
* Method LaunchAPDU.
* @param CLA
* @param INS
* @param P1
* @param P2
* @param dataIn
* @param LE
* @return boolean
*/
private boolean LaunchAPDU(
String CLA,
String INS,
String P1,
String P2,
String dataIn,
String LE) {
boolean OK = true;

int apduCLA = (int) Integer.parseInt(CLA, 16);
int apduINS = (int) Integer.parseInt(INS, 16);
int apduP1 = (int) Integer.parseInt(P1, 16);
int apduP2 = (int) Integer.parseInt(P2, 16);

int[] apduBody;
byte[] apduBodyByte =
AgencardTools.AscStringToByteArray(dataIn);
apduBody = AgencardTools.byteArrayToIntArray(apduBodyByte);
int apduLe = (int) Integer.parseInt(LE, 16);
int apduLc = apduBody.length;

try {
iopCard.BeginTransaction();
//PROBLEME A CE NIVEAU: sDataOut NE SE REMPLIT PAS
sDataOut =
iopCard.SendCardAPDU(
apduCLA,
apduINS,
apduP1,
apduP2,
apduBody,
apduLe);

Filière IR


Promo 2000

Année 2003 Page 54