0% found this document useful (0 votes)
230 views

APDU ReadWriteJava

The document describes a Java Card applet that provides read and write functionality to access data stored in a byte array on the card. It includes code for the applet class with methods to process APDU commands for reading and writing data, and code to handle the command processing and data transfer. Test strategies are also outlined to test different cases around reading and writing data.

Uploaded by

lilux519
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
230 views

APDU ReadWriteJava

The document describes a Java Card applet that provides read and write functionality to access data stored in a byte array on the card. It includes code for the applet class with methods to process APDU commands for reading and writing data, and code to handle the command processing and data transfer. Test strategies are also outlined to test different cases around reading and writing data.

Uploaded by

lilux519
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 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

You might also like