How to send a data array to my Applet and manipulation it by Applet and return new data in response apdu? -
update 1: installed applet on javacard(i used source code accepted answer in question) .when send generatedkey command via opensc ,it returns 9000 response instead of sending xored data! created project javacard version 2.2.1 , card compattible version. why expected data not recieved opensc?
i want send random byte array including example 24 elements javacard applet , applet supposed change array using specific method. example method xor each elements 0x05
, returns result array in apdu response.
to aim above goal wrote following program far:
package keygeneratorpackage; import javacard.framework.*; public class keygeneratorpackage extends applet { private static final byte hw_cla = (byte) 0x80; private static final byte hw_ins = (byte) 0x00; public static void install(byte[] barray, short boffset, byte blength) { new keygeneratorpackage().register(barray, (short) (boffset + 1), barray[boffset]); } public void process(apdu apdu) { if (selectingapplet()) { return; } byte[] buffer = apdu.getbuffer(); byte cla = (byte) (buffer[iso7816.offset_cla] & 0xff); byte ins = (byte) (buffer[iso7816.offset_ins] & 0xff); byte[] data = new byte[] { (byte) (buffer[iso7816.offset_cdata] & 0xff) }; if (cla != hw_cla) { isoexception.throwit(iso7816.sw_cla_not_supported); } switch (ins) { case hw_ins: getkey(apdu, data); break; default: isoexception.throwit(iso7816.sw_ins_not_supported); } } private void getkey(apdu apdu, byte[] data) { byte[] buffer = apdu.getbuffer(); byte[] generatedkey = generatekey(data); short length = (short) generatedkey.length; util.arraycopynonatomic(generatedkey, (short) 0, buffer, (short) 0, (short) length); apdu.setoutgoingandsend((short) 0, length); } private byte[] generatekey(byte[] data) { byte[] key = new byte[] { (byte) 0x00 }; (int = 0; < data.length; i++) { key[i] = (byte) (data[i] ^ 5); } return key; } }
i must send following apdu command after compiling , selecting applet:
>>> 80 00 00 00 18 11 22 33 44 55 66 77 88 99 10 20 30 40 50 60 70 80 90 b1 b2 b3 b4 b5 b6 b7 26
is there wrong applet?
in method, private void getkey( apdu apdu , byte[] data)
need call,
apdu.setincomingandreceive();
remember:
this primary receive method. calling method indicates apdu has incoming data. method gets many bytes fit without buffer overflow in apdu buffer following header. gets incoming bytes if fit.
so update method this:
private void getkey( apdu apdu , byte[] data) { apdu.setincomingandreceive(); byte[] buffer = apdu.getbuffer(); byte[] generatedkey = generatekey(data); short length = (short) generatedkey.length; //short length =1; util.arraycopynonatomic(generatedkey, (short)0, buffer, (short)0, (short) length); apdu.setoutgoingandsend((short)0, length);
}
note: setincomingandreceive
method may called once in applet.process() method. more detail, read setincomingandreceive.
edit: there several problems in code. i'm mentioning of them 1 one.
problem 1:
byte[] data =new byte[] {(byte) (buffer[iso7816.offset_cdata] & 0xff)};
it creates byte[] data
of length 1 value 0x11
.
solution: new
creates space persistent eep memory data
. if don't need data
again can make transient
byte array.
rewrite (persistent):
// create byte array of length of "lc". content `0x00`. byte[] data = new byte[(byte) (buffer[iso7816.offset_lc] & 0xff)];
or (transient):
byte[] data = jcsystem.maketransientbytearray((short) (buffer[iso7816.offset_lc] & 0x00ff), jcsystem.clear_on_deselect);
problem 2:
i) generatekey()
method crash, because creating byte[] key
same byte[] data
.
ii) may not declare int i
because few cards supports it, use byte
or short
.
solution: far understand trying in generatekey()
method, rewrite this:
// byte array preparation of key callers duty private byte[] generatekey(byte[] data, byte[] key) { short i; (i = 0; < data.length; i++) { key[i] = (byte) (data[i] ^ (byte)0x05); } return key; }
the full working code is:
javacard: v.2.2.2
globalplatform: v.2.1.1
suggestion: read this document first.
package keygeneratorpackage; import javacard.framework.apdu; import javacard.framework.iso7816; import javacard.framework.applet; import javacard.framework.isoexception; import javacard.framework.jcsystem; import javacard.framework.util; /** * keygeneratorpackage <br> * * @author rakeb.void * */ public class keygeneratorpackage extends applet { private static final byte hw_cla = (byte) 0x80; private static final byte hw_ins = (byte) 0x00; public static void install(byte[] barray, short boffset, byte blength) { new keygeneratorpackage.keygeneratorpackage().register(barray, (short) (boffset + 1), barray[boffset]); } public void process(apdu apdu) { if (selectingapplet()) { return; } apdu.setincomingandreceive(); byte[] buffer = apdu.getbuffer(); byte cla = (byte) (buffer[iso7816.offset_cla] & 0xff); byte ins = (byte) (buffer[iso7816.offset_ins] & 0xff); short lc = (short) (buffer[iso7816.offset_lc] & (short)0x00ff); // byte[] data = new byte[(byte) (buffer[iso7816.offset_lc] & 0xff)]; byte[] data = jcsystem.maketransientbytearray(lc, jcsystem.clear_on_deselect); if (cla != hw_cla) { isoexception.throwit(iso7816.sw_cla_not_supported); } switch (ins) { case hw_ins: { // copying apdu data byte array data util.arraycopy(buffer, iso7816.offset_cdata, data, (short) 0, lc); getkey(apdu, data); } // forget put break here! break; default: // practice: if don't know instruction, so: isoexception.throwit(iso7816.sw_ins_not_supported); } } private void getkey(apdu apdu, byte[] data) { byte[] buffer = apdu.getbuffer(); short length = (short) data.length; //prepareing key array of same length of data byte[] key = jcsystem.maketransientbytearray(length, jcsystem.clear_on_deselect); // byte[] generatedkey = generatekey(data, key); // no need array generatedkey, passing key parameter generatekey(data, key); // length = (short) generatedkey.length; util.arraycopynonatomic(key, (short) 0, buffer, (short) 0, (short) length); apdu.setoutgoingandsend((short) 0, length); } // ..................................... private byte[] generatekey(byte[] data, byte[] key) { short i; (i = 0; < data.length; i++) { // i've no idea why use 0x05 here, // in question mentioned 0x9d key[i] = (byte) (data[i] ^ (byte)0x05); } return key; } }
apdu's sent :
select command : 00 a4 04 00 06 a1 a2 a3 a4 a5 00 00
select command response : 90 00
generatekey command : 80 00 00 00 18 11 22 33 44 55 66 77 88 99 10 20 30 40 50 60 70 80 90 b1 b2 b3 b4 b5 b6 b7
generatekey command response : 14 27 36 41 50 63 72 8d 9c 15 25 35 45 55 65 75 85 95 b4 b7 b6 b1 b0 b3 90 00
cheers!
Comments
Post a Comment