Sachin D
Sachin D

Reputation: 1376

How to store data larger than 128 byte in JavaCard

I can't write data at index above 128 in byte array. code is given below.

private void Write1(APDU apdu) throws ISOException
{
    apdu.setIncomingAndReceive();
    byte[] apduBuffer = apdu.getBuffer();
    byte j = (byte)apduBuffer[4];       // Return incoming bytes lets take 160
    Buffer1 = new byte[j];              // initialize a array with size 160
    for (byte i=0; i<j; i++)
        Buffer1[(byte)i] = (byte)apduBuffer[5+i];
}

It gives me error 6F 00 (It means reach End Of file).

I am using:

Upvotes: 2

Views: 4648

Answers (4)

Steve Boo
Steve Boo

Reputation: 31

short j = (short) apdu_buffer[ISO7816.OFFSET_LC] & 0xFF

Upvotes: 3

user166390
user166390

Reputation:

Update: While the following answer is "valid" for normal Java, please refer to Roberts answer for Java Card-specific information, as well additional concerns/approaches.


In Java a byte has values in the range [-128, 127] so, when you say "160", that's not what the code is really giving you :)

Perhaps you'd like to use:

int j = apduBuffer[4] & 0xFF;

That "upcasts" the value apduBuffer[4] to an int while treating the original byte data as an unsigned value.

Likewise, i should also be an int (to avoid a nasty overflow-and-loop-forever bug), and the System.arraycopy method could be handy as well...

(I have no idea if that is the only/real problem -- or if the above is a viable solution on a Java Card -- but it sure is a problem and aligns with the "128 limit" mentioned.)

Happy coding.

Upvotes: 1

Robert
Robert

Reputation: 42734

Your code contains several problems:

  1. As already pointed out by 'pst' you are using a signed byte value which works only up to 128 - use a short instead

  2. Your are creating a new buffer Buffer1 on every call of your Write1 method. On JavaCard there is usually no automatic garbage collection - therefore memory allocation should only be done once when the app is installed. If you only want to process the data in the adpu buffer just use it from there. And if you want to copy data from one byte array into another better use javacard.framework.Util.arrayCopy(..).

  3. You are calling apdu.setIncomingAndReceive(); but ignore the return value. The return value gives you the number of bytes of data you can read.

The following code is from the API docs and shows the common way:

short bytesLeft = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF);
if (bytesLeft < (short)55) ISOException.throwIt( ISO7816.SW_WRONG_LENGTH );
short readCount = apdu.setIncomingAndReceive();
while ( bytesLeft > 0){

     // process bytes in buffer[5] to buffer[readCount+4];

     bytesLeft -= readCount;
     readCount = apdu.receiveBytes ( ISO7816.OFFSET_CDATA );
}

Upvotes: 5

Artie
Artie

Reputation: 503

Elaborating on pst's answer. A byte has 2^8 bits numbers, or rather 256. But if you are working with signed numbers, they will work in a cycle instead. So, 128 will be actually -128, 129 will be -127 and so on.

Upvotes: 1

Related Questions