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

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -