HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

"Writing Java Card Applications"
Vol. 9, Issue 9, p. 44

	



Listing 1

1 package com.vsp.eperson.javacard.applets;
2
3 // AID: 0x01:0x02:0x03:0x04:0x06:  0x0a:0x0b:0x00
4
5 import javacard.framework.*;
6
7 /**
8  * @author Vijay Phagura
9  */
10 public class EPersonApplet extends Applet
11 {
12     // Applet AID: 0x01:0x02:0x03:0x04:0x06:  0x0a:0x0b:0x01
13     // Cmds
14     final static byte CLA = ( byte )0xB0;   // CLA
15
16     // Read only cmds
17     final static byte GET_EMPID = ( byte )0x01;   // INS
18     final static byte GET_FIRST_NAME = ( byte )0x02;   // INS
19     final static byte GET_LAST_NAME = ( byte )0x03;   // INS
20     final static byte GET_ALL_INFO = ( byte )0x04;   // INS
21
22     // Update cmds
23     final static byte GET_CARD_STATUS = ( byte )0x05;   // INS
24     final static byte GET_AMOUNT_DUE = ( byte )0x06;   // INS
25     final static byte GET_ALLOWANCE = ( byte )0x07;   // INS
26
27     final static byte SET_CARD_STATUS = ( byte )0x08;   // INS
28     final static byte SET_AMOUNT_DUE = ( byte )0x09;   // INS
29     final static byte SET_ALLOWANCE = ( byte )0x0a;   // INS
30
31     // Constants
32     final static short MAX_ID_SIZE = ( short )5;
33     final static short MAX_NAME_SIZE = ( short )10;
34     final static short MAX_AMOUNT_SIZE = ( short )2;
35     final static short MAX_ALLOW_SIZE = ( short )1;
36     final static short All_INFO_SIZE = MAX_ID_SIZE +
37                  ( 2 * MAX_NAME_SIZE ) +
38                  MAX_AMOUNT_SIZE +
39                  MAX_ALLOW_SIZE;
40
41     // Fields
42     byte[] empId = null;
43     byte[] firstName = null;
44     byte[] lastName = null;
45     byte[] allInfo = null;
46 
47     boolean active = false;  // Card status
48     short amount = 0;        // Amount due in dollars
49     byte allow = 0;          // Days allowed to pay the dues
50
51 
52     /**
53      * Initializes all fields of this applet.
54      *
55      * Example Input:-
56      * EMPID: T1024 = 0x54 0x31 0x30 0x32 0x34
57      * FNAME: John = 0x4a 0x6f 0x68 0x6e 0x00 0x00 0x00 0x00 0x00 0x00
58      * LNAME: Smith = 0x53 0x6d 0x69 0x74 0x68 0x00 0x00 0x00 0x00 0x00
59      * AMOUNT: 257 = 0x01 0x01
60      * ALLOW: 5 = 0x05
61      *
62      * input: 54313032344a6f686e000000000000536d6974680000000000010105
63      * length: 28 bytes(0x1c)
64      *
65      * @param bArray
66      * @param bOffset
67      * @param bLength
68      */
69     private EPersonApplet( byte[] bArray, short bOffset, byte bLength )
70     {
71 
72         allInfo = new byte[ All_INFO_SIZE ];
73         empId = new byte[ MAX_ID_SIZE ];
74         firstName = new byte[ MAX_NAME_SIZE ];
75         lastName = new byte[ MAX_NAME_SIZE ];
76         active = true;
77 
78         byte[] tmp = new byte[ 2 ];
79         short offset = ( short )( bOffset + bArray[bOffset] + 4 );  // AID+4
bytes
80         Util.arrayCopyNonAtomic( bArray, offset, allInfo, ( short )0,
 All_INFO_SIZE );
81         Util.arrayCopyNonAtomic( bArray, offset, empId, ( short )0, MAX_ID_SIZE
 );
82         offset += MAX_ID_SIZE;
83         Util.arrayCopyNonAtomic( bArray, offset, firstName, ( short )0,
 MAX_NAME_SIZE );
84         offset += MAX_NAME_SIZE;
85         Util.arrayCopyNonAtomic( bArray, offset, lastName, ( short )0,
 MAX_NAME_SIZE );
86         offset += MAX_NAME_SIZE;
87         Util.arrayCopyNonAtomic( bArray, offset, tmp, ( short )0,
 MAX_AMOUNT_SIZE );
88         offset += MAX_AMOUNT_SIZE;
89         amount = ( short )( ( tmp[ 1 ] << 8 ) | (tmp[ 0 ] & 0xFF));
90 
91         Util.arrayCopyNonAtomic( bArray, offset, tmp, ( short )0, MAX_ALLOW_SIZE );
92         offset += MAX_ALLOW_SIZE;
93         allow = tmp[ 0 ];
94 
95         register();
96     }
97 
98     /**
99      * Installs a new instance of this applet and passes the input to the applet
 constructor
100      *
101      * @param bArray
102      * @param bOffset
103      * @param bLength
104      */
105     public static void install( byte[] bArray, short bOffset, byte bLength )
106     {
107         new EPersonApplet( bArray, bOffset, bLength );
108     }
109 
110     /**
111      * The process method which processes all cmds.
112      *
113      * @param apdu
114      * @throws ISOException
115      */
116     public void process( APDU apdu ) throws ISOException
117     {
118         byte[] buffer = apdu.getBuffer();
119 
120         if ( selectingApplet() )
121         {
122             return;
123         }
124         else if ( buffer[ ISO7816.OFFSET_CLA ] != CLA )
125         {
126             ISOException.throwIt( ISO7816.SW_CLA_NOT_SUPPORTED );
127         }
128 
129         switch ( buffer[ ISO7816.OFFSET_INS ] )
130         {
131             case GET_EMPID:
132                 getEmpId( apdu );
133                 return;
134             case GET_FIRST_NAME:
135                 getFirstName( apdu );
136                 return;
137             case GET_LAST_NAME:
138                 getLastName( apdu );
139                 return;
140             case GET_ALL_INFO:
141                 getAllInfo( apdu );
142                 return;
143             case GET_CARD_STATUS:
144                 getCardStatus( apdu );
145                 return;
146             case GET_AMOUNT_DUE:
147                 getAmountDue( apdu );
148                 return;
149             case GET_ALLOWANCE:
150                 getAllowance( apdu );
151                 return;
152             case SET_CARD_STATUS:
153                 setCardStatus( apdu );
154                 return;
155             case SET_AMOUNT_DUE:
156                 setAmountDue( apdu );
157                 return;
158             case SET_ALLOWANCE:
159                 setAllowance( apdu );
160                 return;
161             default:
162                 ISOException.throwIt( ISO7816.SW_INS_NOT_SUPPORTED );
163         }
164     }
165 
166     private void setAllowance( APDU apdu )
167     {
168         byte[] buffer = apdu.getBuffer();
169         byte cnt = ( byte )apdu.setIncomingAndReceive();
170         if ( cnt != 1 )
171         {
172             ISOException.throwIt( ISO7816.SW_WRONG_LENGTH );
173         }
174         byte tmp = buffer[ ISO7816.OFFSET_CDATA ];
175         allow = tmp;
176     }
177 
178     private void setAmountDue( APDU apdu )
179     {
180         byte[] buffer = apdu.getBuffer();
181         byte cnt = ( byte )apdu.setIncomingAndReceive();
182         if ( cnt != 2 )
183         {
184             ISOException.throwIt( ISO7816.SW_WRONG_LENGTH );
185         }
186         byte[] tmp = new byte[ MAX_AMOUNT_SIZE ];
187         Util.arrayCopy( buffer, ISO7816.OFFSET_CDATA, tmp, ( short )0,
 MAX_AMOUNT_SIZE );
188         amount = ( short )( ( tmp[ 1 ] << 8 ) | (tmp[ 0 ] & 0xFF) );
189     }
190 
191     private void setCardStatus( APDU apdu )
192     {
193         byte[] buffer = apdu.getBuffer();
194         byte cnt = ( byte )apdu.setIncomingAndReceive();
195         if ( cnt != 1 )
196         {
197             ISOException.throwIt( ISO7816.SW_WRONG_LENGTH );
198         }
199         byte tmp = buffer[ ISO7816.OFFSET_CDATA ];
200         active = ( tmp == 1 ) ? true : false;
201     }
202 
203     private void getAllowance( APDU apdu )
204     {
205         byte[] buffer = apdu.getBuffer();
206 
207         byte[] st = new byte[ MAX_ALLOW_SIZE ];
208         st[ 0 ] = allow;
209 
210         Util.arrayCopy( st, ( short )0, buffer, ( short )0, MAX_ALLOW_SIZE );
211         apdu.setOutgoingAndSend( ( short ) 0, MAX_ALLOW_SIZE);
212 
213     }
214 
215     private void getAmountDue( APDU apdu )
216     {
217         byte[] buffer = apdu.getBuffer();
218 
219         byte[] st = new byte[ MAX_AMOUNT_SIZE ];
220         st[ 0 ] = ( byte )( amount & 0xff );
221         short tmp = ( short )( amount >> 8 );
222         st[ 1 ] = ( byte )( tmp & 0xff );
223 
224         Util.arrayCopy( st, ( short )0, buffer, ( short )0, MAX_AMOUNT_SIZE );
225         apdu.setOutgoingAndSend( ( short ) 0, MAX_AMOUNT_SIZE);
226 
227     }
228 
229     private void getCardStatus( APDU apdu )
230     {
231         byte[] buffer = apdu.getBuffer();
232         byte[] st = new byte[ MAX_ALLOW_SIZE ];
233         st[ 0 ] = ( byte )( ( active == true ) ? 0x01 : 0x00 );
234         Util.arrayCopy( st, ( short )0, buffer, ( short )0, MAX_ALLOW_SIZE );
235         apdu.setOutgoingAndSend( ( short )0, MAX_ALLOW_SIZE );
236     }
237 
238     private void getAllInfo( APDU apdu )
239     {
240         byte[] buffer = apdu.getBuffer();
241         short offset = 0;
242         // EmpId
243         Util.arrayCopy( empId, ( short )0, buffer, offset, MAX_ID_SIZE );
244         offset += MAX_ID_SIZE;
245         // First Name
246         Util.arrayCopy( firstName, ( short )0, buffer, offset, MAX_NAME_SIZE );
247         offset += MAX_NAME_SIZE;
248         // Last Name
249         Util.arrayCopy( lastName, ( short )0, buffer, offset, MAX_NAME_SIZE );
250         offset += MAX_NAME_SIZE;
251         // Amount Due
252         byte[] st = new byte[ MAX_AMOUNT_SIZE ];
253         st[ 0 ] = ( byte )( amount & 0xff );
254         short tmp = ( short )( amount >> 8 );
255         st[ 1 ] = ( byte )( tmp & 0xff );
256         Util.arrayCopy( st, ( short )0, buffer, offset, MAX_AMOUNT_SIZE );
257         offset += MAX_AMOUNT_SIZE;
258         // Allowance
259         st[0] = allow;
260         Util.arrayCopy( st, ( short )0, buffer, offset,  MAX_ALLOW_SIZE );
261         offset += MAX_ALLOW_SIZE;
262 
263         apdu.setOutgoingAndSend( ( short )0, All_INFO_SIZE );
264     }
265 
266     private void getLastName( APDU apdu )
267     {
268         byte[] buffer = apdu.getBuffer();
269         Util.arrayCopy( lastName, ( short )0, buffer, ( short )0, MAX_NAME_SIZE
 );
270         apdu.setOutgoingAndSend( ( short )0, MAX_NAME_SIZE );
271     }
272 
273     private void getFirstName( APDU apdu )
274     {
275         byte[] buffer = apdu.getBuffer();
276         Util.arrayCopy( firstName, ( short )0, buffer, ( short )0,
 MAX_NAME_SIZE );
277         apdu.setOutgoingAndSend( ( short )0, MAX_NAME_SIZE );
278     }
279 
280     private void getEmpId( APDU apdu )
281     {
282         byte[] buffer = apdu.getBuffer();
283         Util.arrayCopy( empId, ( short )0, buffer, ( short )0, MAX_ID_SIZE );
284         apdu.setOutgoingAndSend( ( short )0, MAX_ID_SIZE );
285     }
286 }

Listing 2

-classdir C:\prgs\egate\classes
-out EXP JCA CAP
-exportpath C:\jc211\api21
-applet  0x01:0x02:0x03:0x04:0x06:0x0a:0x0b:0x01
 com.vsp.eperson.javacard.applets.EPersonApplet
 com.vsp.eperson.javacard.applets
0x01:0x02:0x03:0x04:0x06:0x0a:0x0b:0x00 1.0

Listing 3

com.sun.javacard.installer.InstallerApplet
0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0x8:0x1
com.vsp.eperson.javacard.applets.EPersonApplet
0x01:0x02:0x03:0x04:0x06:0x0a:0x0b:0x01

Listing 4

powerup;

// Select the installer applet
0x00 0xA4 0x04 0x00 0x09 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0x08 0x01 0x7F;
// 90 00 = SW_NO_ERROR

// begin installer command
0x80 0xB0 0x00 0x00 0x00 0x7F;

// create EPersonApplet
0x80 0xB8 0x00 0x00 0x19 0x08 0x01 0x02 0x03 0x04 0x06 0x0a 0x0b 0x01 0x0f 0x54
 0x31 0x4a 0x6f 0x68 0x6e 0x00 0x53 0x6d 0x69 0x74 0x68 0x01 0x01 0x05 0x00;

// end installer command
0x80 0xBA 0x00 0x00 0x00 0x7F;

// Select EPersonApplet
0x00 0xa4 0x04 0x00 0x08 0x01 0x02 0x03 0x04 0x06 0x0a 0x0b 0x01 0x00;

//Send GET_EMPID cmd
0xb0 0x01 0x00 0x00 0x00 0x00;

//Send GET_FIRST_NAME cmd
0xb0 0x02 0x00 0x00 0x00 0x00;

//Send GET_LAST_NAME cmd
0xb0 0x03 0x00 0x00 0x00 0x00;

//Send GET_ALL_INFO cmd
0xb0 0x04 0x00 0x00 0x00 0x00;

//Send GET_CARD_STATUS cmd
0xb0 0x05 0x00 0x00 0x00 0x00;

//Send GET_AMOUNT cmd
0xb0 0x06 0x00 0x00 0x00 0x00;

//Send GET_ALLOWANCE cmd
0xb0 0x07 0x00 0x00 0x00 0x00;

//Send SET_CARD_STATUS cmd
0xb0 0x08 0x00 0x00 0x01 0x00 0x00;

//Send GET_CARD_STATUS cmd
0xb0 0x05 0x00 0x00 0x00 0x00;

//Send SET_AMOUNT cmd
0xb0 0x09 0x00 0x00 0x02 0x02 0x11 0x00;

//Send GET_AMOUNT cmd
0xb0 0x06 0x00 0x00 0x00 0x00;

//Send GET_INSTALL_DATA cmd
0xb0 0x0b 0x00 0x00 0x00 0x00;

// *** SCRIPT END ***
powerdown;

Listing 5

Java Card 2.1.1 ApduTool (version 1.1)
Copyright (c) 2000 Sun Microsystems, Inc. All rights reserved.
Opening connection to localhost on port 9,025.
Connected.
CLA: 00, INS: a4, P1: 04, P2: 00, Lc: 09, a0, 00, 00, 00, 62, 03, 01, 08, 01, Le:
 00, SW1: 90, SW2: 00
CLA: 80, INS: b0, P1: 00, P2: 00, Lc: 00, Le: 00, SW1: 90, SW2: 00
CLA: 80, INS: b8, P1: 00, P2: 00, Lc: 19, 08, 01, 02, 03, 04, 06, 0a, 0b, 01, 0f,
 54, 31, 4a, 6f, 68, 6e, 00, 53, 6d, 69, 74, 68, 01, 01, 05, Le: 08, 01, 02, 03,
  04, 06, 0a, 0b, 01, SW1: 90, SW2: 00
CLA: 80, INS: ba, P1: 00, P2: 00, Lc: 00, Le: 00, SW1: 90, SW2: 00
CLA: 00, INS: a4, P1: 04, P2: 00, Lc: 08, 01, 02, 03, 04, 06, 0a, 0b, 01, Le: 00,
 SW1: 90, SW2: 00
CLA: b0, INS: 01, P1: 00, P2: 00, Lc: 00, Le: 02, 54, 31, SW1: 90, SW2: 00
CLA: b0, INS: 02, P1: 00, P2: 00, Lc: 00, Le: 05, 4a, 6f, 68, 6e, 00, SW1: 90, SW2:
 00
CLA: b0, INS: 03, P1: 00, P2: 00, Lc: 00, Le: 05, 53, 6d, 69, 74, 68, SW1: 90, SW2:
 00
CLA: b0, INS: 04, P1: 00, P2: 00, Lc: 00, Le: 0f, 54, 31, 4a, 6f, 68, 6e, 00, 53,
 6d, 69, 74, 68, 01, 01, 05, SW1: 90, SW2: 00
CLA: b0, INS: 05, P1: 00, P2: 00, Lc: 00, Le: 01, 01, SW1: 90, SW2: 00
CLA: b0, INS: 06, P1: 00, P2: 00, Lc: 00, Le: 02, 01, 01, SW1: 90, SW2: 00
CLA: b0, INS: 07, P1: 00, P2: 00, Lc: 00, Le: 01, 05, SW1: 90, SW2: 00
CLA: b0, INS: 08, P1: 00, P2: 00, Lc: 01, 00, Le: 00, SW1: 90, SW2: 00
CLA: b0, INS: 05, P1: 00, P2: 00, Lc: 00, Le: 01, 00, SW1: 90, SW2: 00
CLA: b0, INS: 09, P1: 00, P2: 00, Lc: 02, 02, 11, Le: 00, SW1: 90, SW2: 00
CLA: b0, INS: 06, P1: 00, P2: 00, Lc: 00, Le: 02, 02, 11, SW1: 90, SW2: 00
CLA: b0, INS: 0b, P1: 00, P2: 00, Lc: 00, Le: 11, 54, 31, 4a, 6f, 68, 6e, 00, 53,
 6d, 69, 74, 68, 01, 01, 05, 0f, 0f, SW1: 90, SW2: 00

Listing 6

1 package com.vsp.eperson.javacard.clientside;
2 
3 import slb.iop.*;
4 
5 /**
6  * @author Vijay Phagura
7  */
8 public class CardProxy implements slb.iop.IOPListener
9 {
10     // Cmds
11     private final static byte CLA = ( byte ) 0xB0;   // CLA
12 
13     // Read only cmds
14     private final static byte GET_EMPID = ( byte ) 0x01;   // INS
15     private final static byte GET_FIRST_NAME = ( byte ) 0x02;   // INS
16     private final static byte GET_LAST_NAME = ( byte ) 0x03;   // INS
17     private final static byte GET_ALL_INFO = ( byte ) 0x04;   // INS
18 
19     // Update cmds
20     private final static byte GET_CARD_STATUS = ( byte ) 0x05;   // INS
21     private final static byte GET_AMOUNT_DUE = ( byte ) 0x06;   // INS
22     private final static byte GET_ALLOWANCE = ( byte ) 0x07;   // INS
23 
24     private final static byte SET_CARD_STATUS = ( byte ) 0x08;   // INS
25     private final static byte SET_AMOUNT_DUE = ( byte ) 0x09;   // INS
26     private final static byte SET_ALLOWANCE = ( byte ) 0x0a;   // INS
27 
28     // Constants
29     private final short[] AID = {0x01, 0x02, 0x03, 0x04, 0x06, 0x0a, 0x0b,
 0x01};
30     private final short[] MAC = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F};
31     private final short[] AUTH = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F};
32     private final short[] KEK = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F};
33 
34     private final static short MAX_ID_SIZE = ( short ) 5;
35     private final static short MAX_NAME_SIZE = ( short ) 10;
36     private final static short MAX_AMOUNT_SIZE = ( short ) 2;
37     private final static short MAX_ALLOW_SIZE = ( short ) 1;
38     private final static short All_INFO_SIZE = MAX_ID_SIZE + ( 2 * MAX_NAME_SIZE
 ) + MAX_AMOUNT_SIZE + MAX_ALLOW_SIZE;
39 
40 
41     // Fields
42     private boolean connected = false;
43     private boolean errorFlag = false;
44     private SmartCard card = null;
45     private String cardReaderName = null;
46     private String error = null;
47 
48     // Static Fields
49     private static IOP sIOP = null;
50 
51     static
52     {
53         System.loadLibrary( "slbjiop3" );
54 
55         sIOP = new IOP();
56     }
57 
58 
59     public CardProxy( String readerName )
60     {
61         if(sIOP == null) sIOP = new IOP();
62 
63         cardReaderName = readerName;
64         card = new SmartCard();
65 
66         sIOP.addIOPListener( this );
67 
68         // Try to connect if the card is in the reader
69         connect();
70     }
71 
72     public String getCardReaderName()
73     {
74         return cardReaderName;
75     }
76 
77     public void setCardReaderName( String cardReaderName )
78     {
79         this.cardReaderName = cardReaderName;
80     }
81 
82     // Card listener callback operations
83     public void CardRemoved( slb.iop.IOPEvent event )
84     {
85         disconnect();
86     }
87 
88     public void CardInserted( slb.iop.IOPEvent event )
89     {
90         connect();
91     }
92 
93     public void ReaderRemoved( slb.iop.IOPEvent event )
94     {
95         CardRemoved( event );
96     }
97 
98     public void ReaderInserted( slb.iop.IOPEvent event )
99     {
100         CardInserted( event );
101     }
102 
103     // House keeping operations
104     public boolean isConnected()
105     {
106         return connected;
107     }
108 
109     public boolean isError()
110     {
111         return errorFlag;
112     }
113 
114     public String getErrorString()
115     {
116         errorFlag = false;
117         return error;
118     }
119 
120     public void disconnect()
121     {
122         sIOP.Disconnect( card);
123         connected = false;
124     }
125 
126     public boolean connect()
127     {
128         try
129         {
130             if ( sIOP.Connect( card, cardReaderName ) )
131             {
132                 Thread.sleep( 500 );
133 
134                 if ( card.EstablishSecureChannel( MAC, AUTH, KEK ) )
135                 {
136                     if ( card.SelectAID( AID ) )
137                     {
138                         connected = true;
139                     }
140                     else
141                     {
142                         System.out.println( "Could not SELECT Application!" );
143                         setError();
144                     }
145                 }
146                 else
147                 {
148                     System.out.println( "Could not ESTABLISH secure channel!"
 );
149                     setError();
150                 }
151             }
152             else
153             {
154                 System.out.println( "Could not CONNECT to card!" );
155                 setError();
156             }
157         }
158         catch ( slbException e )
159         {
160             e.printStackTrace();
161         }
162         catch ( InterruptedException e )
163         {
164         }
165 
166         return connected;
167     }
168 
169     // Cmds
170     public String getEmployeeId() throws slbException
171     {
172         int[] in = new int[ 0 ];
173         short[] out = card.SendCardAPDU( ( CLA & 0xFF ), ( GET_EMPID & 0xFF ),
 0, 0, in, ( int ) MAX_ID_SIZE );
174         setError();
175 
176         byte[] bytes = new byte[ out.length ];
177         for ( int i = 0; i < out.length; i++ )
178         {
179             bytes[ i ] = ( byte ) out[ i ];
180         }
181 
182         return new String( bytes );
183     }
184 
185     public String getFirstName() throws slbException
186     {
187         int[] in = new int[ 0 ];
188         short[] out = card.SendCardAPDU( ( CLA & 0xFF ), ( GET_FIRST_NAME &
 0xFF ), 0, 0, in, MAX_NAME_SIZE );
189         setError();
190 
191         byte[] bytes = new byte[ out.length ];
192         for ( int i = 0; i < out.length; i++ )
193         {
194             bytes[ i ] = ( byte ) out[ i ];
195         }
196 
197         return new String( bytes ).trim();
198     }
199 
200     public String getLastName() throws slbException
201     {
202         int[] in = new int[ 0 ];
203         short[] out = card.SendCardAPDU( ( CLA & 0xFF ), ( GET_LAST_NAME & 0xFF
 ), 0, 0, in, MAX_NAME_SIZE );
204         setError();
205 
206         byte[] bytes = new byte[ out.length ];
207         for ( int i = 0; i < out.length; i++ )
208         {
209             bytes[ i ] = ( byte ) out[ i ];
210         }
211 
212         return new String( bytes ).trim();
213     }
214 
215     public Employee getAllInfo() throws slbException
216     {
217         int[] in = new int[ 0 ];
218         short[] out = card.SendCardAPDU( ( CLA & 0xFF ), ( GET_ALL_INFO & 0xFF
 ), 0, 0, in, All_INFO_SIZE );
219         setError();
220 
221         byte[] bytes = new byte[ out.length ];
222         for ( int i = 0; i < out.length; i++ )
223         {
224             bytes[ i ] = ( byte ) out[ i ];
225         }
226 
227         int offset = 0;
228         // Get Emp ID
229         byte[] empId = new byte[ MAX_ID_SIZE ];
230         System.arraycopy( bytes, offset, empId, 0, MAX_ID_SIZE );
231         offset += MAX_ID_SIZE;
232 
233         // Get First Name
234         byte[] fName = new byte[ MAX_NAME_SIZE ];
235         System.arraycopy( bytes, offset, fName, 0, MAX_NAME_SIZE );
236         offset += MAX_NAME_SIZE;
237 
238         // Get Last Name
239         byte[] lName = new byte[ MAX_NAME_SIZE ];
240         System.arraycopy( bytes, offset, lName, 0, MAX_NAME_SIZE );
241         offset += MAX_NAME_SIZE;
242 
243         // Get Amount
244         byte[] amt = new byte[ MAX_AMOUNT_SIZE ];
245         System.arraycopy( bytes, offset, amt, 0, MAX_AMOUNT_SIZE );
246         offset += MAX_AMOUNT_SIZE;
247 
248         // Get Allowed Days to pay
249         byte[] dys = new byte[ MAX_ALLOW_SIZE ];
250         System.arraycopy( bytes, offset, dys, 0, MAX_ALLOW_SIZE );
251 
252         // Converting
253         String id = new String( empId ).trim();
254         String firstName = new String( fName ).trim();
255         String lastName = new String( lName ).trim();
256         int amount = ( ( amt[ 0 ] << 8 ) | ( amt[ 1 ] & 0xFF ) );
257         int allow = ( dys[ 0 ] & 0xff );
258         int empType = ( id.startsWith( "T" ) ) ? Employee.TEMPORARY_EMPLOYEE :
 Employee.PERMANENT_EMPLOYEE;
259 
260         return new Employee( id, firstName, lastName, amount, allow, empType );
261     }
262 
263     public boolean getCardStatus() throws slbException
264     {
265         int[] in = new int[ 0 ];
266         short[] out = card.SendCardAPDU( ( CLA & 0xFF ), ( GET_CARD_STATUS &
 0xFF ), 0, 0, in, 1 );
267         setError();
268 
269         byte active = 0;
270         active = ( byte ) out[ 0 ];
271 
272         return ( active == 1 ) ? true : false;
273     }
274 
275     public short getAmountDue() throws slbException
276     {
277         int[] in = new int[ 0 ];
278         short[] out = card.SendCardAPDU( ( CLA & 0xFF ), ( GET_AMOUNT_DUE &
 0xFF ), 0, 0, in, MAX_AMOUNT_SIZE );
279         setError();
280 
281         byte[] bytes = new byte[ out.length ];
282         for ( int i = 0; i < out.length; i++ )
283         {
284             bytes[ i ] = ( byte ) ( out[ i ] & 0xff );
285         }
286 
287         return ( short ) ( ( bytes[ 0 ] << 8 ) | ( bytes[ 1 ] & 0xFF ) );
288     }
289 
290     public short getAllowedDaysToPay() throws slbException
291     {
292         int[] in = new int[ 0 ];
293         short[] out = card.SendCardAPDU( ( CLA & 0xFF ), ( GET_ALLOWANCE & 0xFF
 ), 0, 0, in, 1 );
294         setError();
295 
296         return out[ 0 ];
297     }
298 
299     public void setCardStatus( boolean stat ) throws slbException
300     {
301         int[] in = new int[ 1 ];
302         in[ 0 ] = ( stat == true ) ? 0x01 : 0x00;
303         card.SendCardAPDU( ( CLA & 0xFF ), ( SET_CARD_STATUS & 0xFF ), 0, 0,
 in, 0 );
304         setError();
305     }
306 
307     public void setAmountDue( short amt ) throws slbException
308     {
309         int[] in = new int[ 2 ];
310         in[ 1 ] = amt & 0xff;
311         amt = ( short ) ( amt >> 8 );
312         in[ 0 ] = amt & 0xff;
313 
314         card.SendCardAPDU( ( CLA & 0xFF ), ( SET_AMOUNT_DUE & 0xFF ), 0, 0, in,
 0 );
315         setError();
316     }
317 
318 
319     public void setAllowanceDays( short dys ) throws slbException
320     {
321         int[] in = new int[ 1 ];
322         in[ 0 ] = dys & 0xff;
323 
324         card.SendCardAPDU( ( CLA & 0xFF ), ( SET_ALLOWANCE & 0xFF ), 0, 0, in,
 0 );
325         setError();
326     }
327 
328     // Static operations
329     public static String[] ListReaders()
330     {
331         String[] readers = sIOP.ListReaders();
332         return readers;
333     }
334 
335     // Private operations
336     private void setError()
337     {
338         int iErrorCode = card.GetLastErrorCode();
339         if ( iErrorCode != 0x9000 )
340         {
341             error = card.GetErrorMessage();
342             errorFlag = true;
343         }
344     }
345 
346 
347 }


Listing 7

1 package com.vsp.eperson.javacard.clientside;
2 
3 import java.util.Date;
4 
5 /**
6  * @author Vijay Phagura
7  */
8 public class Employee
9 {
10     private String empId = null;
11     private String firstName = null;
12     private String lastName = null;
13     private Date startDate = new Date();
14     private Date endDate = new Date();
15     private int amountSpentToDate = 0;
16     private int amountDue = 0;
17     private int allowedDaysToPay = 0;
18     private int empType = 0;
19     private String closeReason = null;
20 
21     // Constants
22     public final static int NONEMPLOYEE = 0;
23     public final static int PERMANENT_EMPLOYEE = 1;
24     public final static int TEMPORARY_EMPLOYEE = 2;
25     public final static String[] strEmpType = {"NONEMPLOYEE",
26                                                "PERMANENT_EMPLOYEE",
27                                                "TEMPORARY_EMPLOYEE"
28     };
29 	:
30 	:
31 	:
32 	:
33 	:
34 	:
35 }


Listing 8

1 package com.vsp.eperson.javacard.clientside;
2 
3 import slb.iop.slbException;
4 
5 import javax.swing.*;
6 
7 /**
8  * @author Vijay Phagura
9  */
10 public class Viewer extends JApplet
11 {
12     private CardProxy card = null;
13     private String[] readerList = null;
14 
15     public Viewer()
16     {
17         readerList = CardProxy.ListReaders();
18         card = new CardProxy(readerList[0]);
19     }
20 
21 
22     public static void main( String[] args )
23     {
24         Viewer vw = new Viewer();
25 	
26 
27 	// Wait for connection
28         while(true)
29         {
30             try
31             {
32                 Thread.sleep( 100 );
33                 System.out.print( "." );
34 
35                 if(vw.card.isError() )
36                 {
37                     System.out.println( "Error: " + vw.card.getErrorString());
38                 }
39 
40                 if(!vw.card.isConnected())
41                 {
42                      continue;
43                 }
44                 else
45                 {
46                     // Gets
47                     System.out.println( "\nEmpId: " + vw.card.getEmployeeId() );
48                     System.out.println( "First Name: " + vw.card.getFirstName()
 );
49                     System.out.println( "Last Name: " + vw.card.getLastName() );
50                     System.out.println( "Card Status: " +
 vw.card.getCardStatus() );
51                     System.out.println( "Amount Due: " + vw.card.getAmountDue() );
52                     System.out.println( "Days Left to Pay: " +
 vw.card.getAllowedDaysToPay() );
53 
54                     // Get all info
55                     Employee emp = vw.card.getAllInfo();
56                     System.out.println( "Employee: " + emp );
57 
58                     // Sets
59                     vw.card.setAmountDue(( short ) 513);
60                     System.out.println( "Amount Due: " + vw.card.getAmountDue()
 );
61 
62                     vw.card.setAllowanceDays( ( short ) 10);
63                     System.out.println( "Days Left to Pay: " +
 vw.card.getAllowedDaysToPay() );
64                     vw.card.setCardStatus(false);
65                     System.out.println( "Card Status: " +
 vw.card.getCardStatus() );
66 
67                     vw.card.setCardStatus(true);
68                     System.out.println( "Card Status: " +
 vw.card.getCardStatus() );
69 
70                     vw.card.disconnect();
71                     System.exit( 0);
72                 }
73             }
74             catch ( InterruptedException e )
75             {
76                 // Do nothing
77             }
78             catch ( slbException e )
79             {
80                 System.out.println( "Exception: " + vw.card.getErrorString() );
81                 e.printStackTrace();
82             }
83         }
84 
85     }
86 }
87 

Listing 9

1 package com.vsp.eperson.javacard.clientside;
2 
3 import slb.iop.slbException;
4 
5 import javax.swing.*;
6 import java.awt.*;
7 
8 /**
9  * @author Anita Phagura
10  */
11 public class Viewer extends JApplet
12 {
13     // Card
14     private CardProxy card = null;
15     private String[] readerList = null;
16 
17     // GUI
18     private JPanel topPane = null;
19     private JPanel statusPane = null;
20     private JPanel displayPane = null;
21 
22     private JTextField statusTextField = null;
23     private JTextArea empDisplayArea = null;
24 
25     // Business
26     private Employee emp = null;
27     private EmployeeDao dao = null;
28     private ConnectorThread connectorThread = null;
29 
30     // Constants
31     private static final int SPENDING_LIMIT = 1000;
32     private String spendingLimitMsg = "Passed spending limit";
33     private String contractExpiredMsg = "Contract Expired";
34     private String paymentOverDueMsg = "Payment overdue";
35 
36     private String waitingStatus = "Waiting for connection...";
37     private String connectedStatus = "Connected !";
38 
39     public void init()
40     {
41         readerList = CardProxy.ListReaders();
42         card = new CardProxy(readerList[0]);
43         dao = new EmployeeDao();
44 
45         // Status Panel
46         statusPane = new JPanel();
47         JLabel statusLabel = new JLabel("Status: ");
48         statusPane.add(statusLabel);
49         statusTextField = new JTextField(waitingStatus, 20);
50         statusPane.add( statusTextField);
51 
52         // Display Panel
53         displayPane = new JPanel(new BorderLayout( ));
54         JLabel employeeInfoLabel = new JLabel("Employee Info: ");
55         displayPane.add( employeeInfoLabel, BorderLayout.NORTH );
56         empDisplayArea = new JTextArea(20, 10);
57         displayPane.add(new JScrollPane(empDisplayArea), BorderLayout.CENTER);
58 
59         // Top Panel
60         topPane = new JPanel(new BorderLayout());
61         topPane.add( displayPane, BorderLayout.CENTER);
62         topPane.add(statusPane, BorderLayout.SOUTH);
63 
64         getContentPane().add( topPane);
65 
66         validate();
67     }
68 
69     public void start()
70     {
71         connectorThread = new ConnectorThread();
72         Thread connector = new Thread(connectorThread);
73         connector.start();
74 
75         validate();
76     }
77 
78     public void stop()
79     {
80         connectorThread.stopThread();
81     }
82     public void destroy()
83     {
84         card.disconnect();
85         connectorThread.stopThread();
86     }
87 
88     // Business Validation
89     private void validateAndDisplayEmployee()
90     {
91             empDisplayArea.selectAll();
92             empDisplayArea.cut();
93             statusTextField.setText( this.connectedStatus);
94 
95             try
96             {
97                 Employee cardEmp = card.getAllInfo();
98                 emp = dao.findEmployee( cardEmp.getEmpId() );
99 
100                 emp.setAmountDue( cardEmp.getAmountDue() );
101                 emp.setAllowedDaysToPay( cardEmp.getAllowedDaysToPay() );
102 
103                 if( card.getCardStatus() )
104                 {
105                     // Check contract
106                     if(!emp.isContractValid())
107                     {
108                         card.setCardStatus( false );
109                         emp.setCloseReason( contractExpiredMsg );
110                     }
111                     // Check spending
112                     if(emp.getAmountDue() > SPENDING_LIMIT )
113                     {
114                         card.setCardStatus( false );
115                         emp.setCloseReason( spendingLimitMsg );
116                     }
117                     // Check days
118                     if(emp.getAllowedDaysToPay() <= 0)
119                     {
120                         card.setCardStatus( false );
121                         emp.setCloseReason( paymentOverDueMsg );
122                     }
123 
124                 }
125                 else
126                 {
127                     empDisplayArea.append( "WARNING: Employee card has been
 deactivated...");
128                 }
129 
130                 // Display the emp object, anyways
131                 empDisplayArea.append(emp.toString());
132                 dao.updateEmployeeAmounts( emp );
133
134                 validate();
135             }
136             catch ( slbException e )
137             {
138                 e.printStackTrace();
139             }
140
141     }
142     /**
143      * Inner class
144      */
145     class ConnectorThread implements Runnable
146     {
147         private boolean stop = false;
148 
149         public void stopThread()
150         {
151             stop = true;
152         }
153         public void run()
154         {
155             boolean loop = false;
156             while(true)
157             {
158                 while(!card.isConnected())
159                 {
160                     loop = false;
161                     try
162                     {
163 
164                         statusTextField.setText( waitingStatus);
165                         Thread.sleep(700);
166                     }
167                     catch ( Exception e )
168                     {
169                        // Do nothing
170                     }
171 
172                     if(stop)
173                         return;
174                 }
175 
176                 if(!loop)
177                 {
178                     validateAndDisplayEmployee();
179                     loop = true;
180                 }
181             }
182         }
183 
184     }
258 }
  
 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.