Você está na página 1de 4

// Read and Write - Example for read and write into a data field in the card // File: ReadWrite.

java // // Source code based on java card specification version 2.1. // Compiled with JBuilder 6 and JDK 1.3.1. Tested with Java Card Application Stu dio // (JCAST) V 2.2, JLoad 2.0, IFDSIM 4.0 and UniverSIM Java Card 64 kB from Giese cke & Devrient. // // Package AID: 'D2 76 00 00 60 50 02' // Applet AID: 'D2 76 00 00 60 41 02' // //-------------------------------------------------------------------------------------// Specification of the proprietary command READ // command APDU CLA = '80' || INS = '02' || // P1 (= '00') || P2 (= offset [byte]) || // Le (= number of bytes to read = DATA) // response APDU (good case) DATA (with length Le) || SW1 || SW2 // response APDU (bad case) SW1 || SW2 // // Specification of the proprietary command WRITE // command APDU CLA = '80' || INS = '04' || // P1 (= '00') || P2 (= offset [byte]) || // Lc (= number of bytes to write) // DATA (bytes t o write) // response APDU (all cases) SW1 || SW2 // //-------------------------------------------------------------------------------------// Test Strategy (x: not used memory, D: data, for commands READ, WRITE) // // basic tests // Dxxxx xxxxx ... good case, inside lower border // DDDxx xxxxx ... good case, inside lower border // xxxxx xxxxD ... good case, inside upper border // xxxxx xxDDD ... good case, inside upper border // xDxxx xxxxx ... good case, offset and inside border // xDDDx xxxxx ... good case, offset and inside border // // length tests // Dxxxx xxxxx ... good case, inside lower border // ... good case, all possible length values inside the bor der // DDDDD DDDDD ... good case, max. possible length // // border tests // DDDDD DDDDD D.. bad case, outside upper border // xxxxx xxxxx D.. bad case, offset and outside upper border // xxxxx xxxxD D.. bad case, offset and partly outside upper border // //-------------------------------------------------------------------------------------// This source code is under GNU general public license (see www.opensource.org for details). // Please send corrections and ideas for extensions to Wolfgang Rankl (www.wrank l.de) // Copyright 2003-2004 by Wolfgang Rankl, Munich //--------------------------------------------------------------------------------------

// 20. Nov. 2003 - V 1: initial runnable version // 25. Nov. 2003 - V 2: improved documentation // 11. Dez. 2003 - V 3: tested with a real Java Card, 1st published version // 22. March 2004 - V 4: add test strategy, fix a bug (Le=0 in READ command) // fix a bug (Lc=0 in WRITE command), 2nd published versio n //-------------------------------------------------------------------------------------package packreadwrite; import javacard.framework.*; public class ReadWrite final static byte nds final static byte D APDU command final static byte TE APDU command final static short e area static byte[] for the application // this is the package name // import all neccessary packages for java card // class of the APDU comma // instruction for the REA // instruction for the WRI // size of the data storag // this is the data memory

extends Applet { CLASS = (byte) 0x80; INS_READ INS_WRITE = (byte) 0x02; = (byte) 0x04; 9;

SIZE_MEMORY = (short) memory;

//----- installation and registration of the applet ----public static void install(byte[] buffer, short offset, byte length) { memory = new byte[SIZE_MEMORY]; // this is the data storage area new ReadWrite().register(); } // install //----- this is the command dispatcher ----public void process(APDU apdu) { byte[] cmd_apdu = apdu.getBuffer(); if (cmd_apdu[ISO7816.OFFSET_CLA] == CLASS) { // it is the rigth class switch(cmd_apdu[ISO7816.OFFSET_INS]) { // check the instruction byte case INS_READ: // it is a READ instruction cmdREAD(apdu); break; case INS_WRITE: // it is a WRITE instruction cmdWRITE(apdu); break; default : // the instruction in the comm and apdu is not supported ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); } // switch } // if else { // the class in the command ap du is not supported ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED); } // else } // process //----- program code for the APDU command READ ----private void cmdREAD(APDU apdu) { byte[] cmd_apdu = apdu.getBuffer(); //----- check the preconditions ----// check if P1=0 if (cmd_apdu[ISO7816.OFFSET_P1] != 0) ISOException.throwIt(ISO7816.SW_WRONG_ P1P2);

// check if offset P2 is inside the bound of the memory array short offset = (short) (cmd_apdu[ISO7816.OFFSET_P2] & 0x00FF); // calculate offset if (offset >= SIZE_MEMORY) ISOException.throwIt(ISO7816.SW_WRONG_P1P2); // check if offset P2 and expected length Le is inside the bounds of the mem ory array short le = (short)(cmd_apdu[ISO7816.OFFSET_LC] & 0x00FF); // calculate Le ( expected length) if ((offset + le) > SIZE_MEMORY) ISOException.throwIt(ISO7816.SW_WRONG_LENGT H); // check if expected length Le is 0 if (le == 0) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); //----- now all preconditions are fulfilled, the data ----apdu.setOutgoing(); outgoing data apdu.setOutgoingLength((short)le); ytes to send to the IFD apdu.sendBytesLong(memory, (short)offset, (short)le); number of bytes to the IFD } // cmdREAD can be send to the IFD // set transmission to // set the number of b // send the requested

//----- program code for the APDU command WRITE ----private void cmdWRITE(APDU apdu) { byte[] cmd_apdu = apdu.getBuffer(); //----- check the preconditions ----// check if P1=0 if (cmd_apdu[ISO7816.OFFSET_P1] != 0) ISOException.throwIt(ISO7816.SW_WRONG_ P1P2); // check if offset P2 is inside the bound of the memory array short offset = (short) (cmd_apdu[ISO7816.OFFSET_P2] & 0x00FF); // calculate offset if (offset >= SIZE_MEMORY) ISOException.throwIt(ISO7816.SW_WRONG_P1P2); // check if offset P2 and expected length Le is inside the bounds of the mem ory array short lc = (short)(cmd_apdu[ISO7816.OFFSET_LC] & 0x00FF); // calculate Lc ( expected length) if ((offset + lc) > SIZE_MEMORY) ISOException.throwIt(ISO7816.SW_WRONG_LENGT H); // check if command length Lc is 0 if (lc == 0) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); receiveAPDUBody(apdu); // receive now the rest of the APDU //----- now all preconditions are fulfilled, the data can be copied to the m emory ----Util.arrayCopy(cmd_apdu, (short)((ISO7816.OFFSET_CDATA) & 0x00FF), memory, o ffset, lc); // this copy precedure is atomic ISOException.throwIt(ISO7816.SW_NO_ERROR); // command proper executed } // cmdWRITE //----- receive the body of the command APDU public void receiveAPDUBody(APDU apdu) { byte[] buffer = apdu.getBuffer(); short lc = (short)(buffer[ISO7816.OFFSET_LC] & 0x00FF); // calculate Lc (ex pected length) // check if Lc != number of received bytes of the command APDU body if (lc != apdu.setIncomingAndReceive()) ISOException.throwIt(ISO7816.SW_WRON G_LENGTH); } // receiveAPDUBody

} // class

Você também pode gostar