Apdu.setIncomingAndReceive() ??

In order to receive the whole apdu commmand send to the card, we must implement apdu.setIncomingAndReceive(), right? But when i receive command like [00 A0 00 00 50] for the below method indicate that i will get 0x50(80 bytes) data out. But the apdu.setIncomingAndReceive() will wait the coming 80 bytes data but there is not any data sending in as i am requesting to get 80 bytes data. As a result a i will get a error msg of time out error. So the program will stuck here and will not proceed to send the data out. How am i going to solve this? Is there and receive method to just receive the first 5 bytes of apdu command? hope u can understand my question. Thank you!
private void getData(APDU apdu)
byte[] buffer = apdu.getBuffer();
short length = apdu.setIncomingAndReceive();
Util.arrayCopyNonAtomic(Data ,0 , buffer,(short) 5, buffer[5] );
apdu.setOutgoingAndSend((short) 5, buffer[5]);
}

Like he said the first 5 bytes should be read into the buffer automatically when the process() method receives an APDU. If you only sent 5 bytes then you have nothing left to receive so calling setIncomingAndReceive might cause it to hang. Why you would send an APDU with a non-zero data length setting if you aren't sending data might be another question.
If you are in fact sending more data you can do something like the following:
     short bytesLeft = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF);
     short readCount = apdu.setIncomingAndReceive();
     while ( bytesLeft > 0){
          // process bytes in buffer[5] to buffer[readCount+4];
          bytesLeft -= readCount;
          readCount = apdu.receiveBytes ( ISO7816.OFFSET_CDATA );
     }

Similar Messages

  • How can I read Extended APDU input to the same buffer

    The following is the code I am currently using where inBuffer is an intermediate array of 1000 length. However, I do not want to allocate any buffers at all, and just want to send a command apdu of 1000 byte length and modify it in the code and return the modified buf in the response APDU.
    // Read extended APDU input
    byte[] buf = apdu.getBuffer();
    short bytesRead = apdu.setIncomingAndReceive();
    short dataOffset = apdu.getOffsetCdata();
    // store first chunk in our intermediate byte array <-- how do i get rid of the intermediate array
    Util.arrayCopyNonAtomic(buf, dataOffset, inBuffer, (short) 0, bytesRead);
    // what is the overall length?
    short overallLength = apdu.getIncomingLength();
    short messageOffset = bytesRead;
    if (bytesRead != overallLength){ // otherwise we're finished, all bytes received
         short received = 0;
         do{
                   received = apdu.receiveBytes((short)0);
                   Util.arrayCopyNonAtomic(buf, (short)0, inBuffer, messageOffset, received);
                   messageOffset  += received;
              } while(received != 0);
    * REST OF CODE IN PROCESS METHOD
    I have also tried replacing the above code with the following
    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 );
    as shown in the javadocs API, but it does not compile.
    This is my command APDU:
    /send 800100000003E8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003E8
    As you can see:
    CLA - 80
    INS - 01
    P1 & P2 - 00
    LC - 0003E8
    Data - 1000 0s
    LE - 03E8
    I am using JavaCard 3.0 with JCOP in Eclipse. How can I read the extended length apdu to the same buffer? I have no problem in returning an extended length response APDU. Thanks a lot for the help.

    You should not call the convenience method setIncomingAndReceive() in your first code. Please find out about the different APDU states. Furthermore, your Applet should implement the ExtendedLength tagging interface.

  • Problem in APDU-case 1:No command,no response

    Hello evrybody.I have done a method in my java card applet which does not return any command data neither response data.
    I wrote in my APDU script the following(as defined the case 1 in the Zhiqun Chen's book-page 102,says that "P3(the 5th field in the APDU buffer) has to be 0"):
    //CLA INS P1 P2 P3
    0xB1 0x50 0x00 0x00 0x00;
    Howevr, the executed APDU script returns me the following:
    com.sun.javacard.apdutool.ReaderWriterError: Encountered ";" at line 105, column
    25.
    Was expecting one of: <INTEGER_LITERAL> ...
    <CHARACTER_LITERAL> ...
    <STRING_LITERAL> ...
    I have tried to add another 0x00 byte at the end of the above script line, as follwoing:
    //CLA INS P1 P2 Lc Le
    0xB1 0x50 0x00 0x00 0x00 0x00;
    //WIth the idea that Lc=0(no command data) and Le=0(no response data)
    I noticed that the method is working properly(does the work that has to do;I tested and I am definetely sure) but on the other hand the executed APDU script returns as SW1 SW2 the following:
    CLA: b1, INS: 50, P1: 00, P2: 00, Lc: 00, Le: 00, SW1: 6f, SW2: 00 (!!!!)
    Actually,I was waiting for SW1 SW2 == 90 00.
    I do not know why this is returned.
    Do you know what it is going wrong?
    I will appreciate any help and guidance.
    Thank you for you time.

    I will give the code of my function.I think the problem is in the code of this method(function).I will give you in order to have a look at it:
    private void delete_all_records(APDU apdu)
         ver_pin();
         byte[] buffer=apdu.getBuffer();
         byte get_P1=buffer[ISO7816.OFFSET_P1];
         byte P3=buffer[ISO7816.OFFSET_LC];
         //Check the appropriate syntax
         if (get_P1!=(byte)0) // || (P3!=(byte)0) )
         ISOException.throwIt (SW_SYNTAX_DEL_ERROR);
    // else
         //Delete all the record.This for loop
         //deletes all the records' ids.
         for (short i=0;i<kostas.length;i++)
         kostas[(short)i].record_id=(byte)0;
    I did not use any of the functions such as sendBytes() or apdu.setIncomingAndReceive because I did not want to take data either to return response data.Do you have any idea what's going on?
    I will really apprecitae any help.Thank you for your time.

  • Sending a byte array of greater length than the APDU data buffer

    Hello again, I am now trying to send a byte array of length 480 from the smart card. I've tried setting the outgoing length to 480 first but as i had expected, this threw an exception. Then i tried setting it to 240 and then copying from the array into the apdu buffer in two halves and calling sendBytes() twice, but this only worked the first time - it send the first 240 bytes and then threw an error. Is it possible to do what i am trying to accomplish? If so, what am I missing?

    the applet:
    H:\java_card_kit-2_2_1-win-dom\java_card_kit-2_2_1\samples\src\com\sun\javacard\samples\photocard
    the client:
    H:\java_card_kit-2_2_1-win-dom\java_card_kit-2_2_1\samples\src_client\com\sun\javacard\clientsamples\photocardclient
    here is the code i have used to store large data on card. maybe it will help you.
    i send a series of apdu, where each contains 128 bytes of data (all apdu must have the same length - except the last).
    public void writeAPDU(APDU apdu)
         byte[] buffer = apdu.getBuffer();
         short lc = (short)(buffer[ISO7816.OFFSET_LC]&0xFF);          
         short p1 = (short)(buffer[ISO7816.OFFSET_P1]&0xFF); // counter
         short p2 = (short)(buffer[ISO7816.OFFSET_P2]&0xFF); // length of send data
         short offset = (short)(p1 * p2); // calculate the offset
         apdu.setIncomingAndReceive();
         // check for first apdu (contains the total size of data)
         if(p1 == 0 && p2 == 0)
              short l = Util.getShort(buffer,ISO7816.OFFSET_CDATA);
              data = new byte[l];
         else
              // store bytes in array
              Util.arrayCopy(buffer, ISO7816.OFFSET_CDATA, data, offset, lc);
    }

  • How to generate the APDU packege in JCOP3.1 Shell (Eclipse 3.1).

    I can run the counter applete sample in JCOP3.1simulator (Eclpse 3.1) , After I selected my applet . I want to send a APDU to applet for test by JCOP Shell. But JCOP Shell always prompt the error message. for example : I want to get the counter value of the counter from applet. I use 8004000002, CLA=80 INT=04(from source code) P1=P2=00, Le=02(return short),No data Field ,no Lc; but it failed, JCOP error message:
    cm> send 8004000002
    => 80 04 00 00 02 .....
    (521016 nsec)
    <= 69 85 i.
    Status: Conditions of use not satisfied
    Any suggestion and help highly appreciated! thxs at first!
    CounterApplet code:
    public class CounterApplet extends Applet {
         private short value;
         public static void install(byte[] bArray, short bOffset, byte bLength){
              (new CounterApplet()).register(bArray, (short)(bOffset + 1), bArray[bOffset]);
         public void process(APDU apdu){
              byte[] buf = apdu.getBuffer();
              if (selectingApplet())
                   return;        
              switch(buf[ISO7816.OFFSET_INS]){
                   case (byte)0x02:
                        // set the counter to the value given in the APDU buffer
                        if (apdu.setIncomingAndReceive() != (short) 2){
                             ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
                        this.value = Util.getShort(buf, ISO7816.OFFSET_CDATA);
                        return;
                   case (byte)0x04:
                        // return the value of the counter
                        if (apdu.setIncomingAndReceive() != (short) 0){
                             ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
                        Util.setShort(buf, (short) 0, this.value);
                        apdu.setOutgoingAndSend((short) 0, (short) 2);
                        return;
                   case (byte)0x06:
                        // increment counter
                        if (apdu.setIncomingAndReceive() != (short) 0){
                             ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
                        ++this.value;
                        return;
                   case (byte)0x08:
                        // decrement counter
                        if (apdu.setIncomingAndReceive() != (short) 0){
                             ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
                        --this.value;
                        return;         
                   default:
    }

    Thanks a lot for your quick response. but I do select the applet before send the APDU .Pls read the following message. I guess whether the APDU is not correct. or JCOP3.1 is different JCOP3.0.?
    package id: |calvinpack
    applet id: | calvinapp
    cm> select |calvinpack|cavlinapp
    => 00 A4 04 00 08 A0 00 00 00 03 00 00 00 00 ..............
    (586667 nsec)
    <= 6F 10 84 08 A0 00 00 00 03 00 00 00 A5 04 9F 65 o..............e
    01 FF 90 00 ....
    Status: No Error
    cm> send 8004000002
    => 80 04 00 00 02 .....
    (442793 nsec)
    <= 69 85 i.
    Status: Conditions of use not satisfied

  • Detect SELECT APDU

    Hi everyone
    I'm writing an applet (Java Card 2.1.1) and in the process method I'm trying to detect the SELECT APDU command, but it's not working. I send a SELECT APDU to my applet, it throws a SW_CLA_NOT_SUPPORTED exception, and it is selected. Ok, the command ends up doing what it is supposed to do, but my applet throws an exception, and it shouldn't.
    Here's my code:
    public void process(APDU apdu) throws ISOException {
      byte[] buffer = apdu.getBuffer();
      byte cla  = buffer[ISO7816.OFFSET_CLA];
      byte ins = buffer[ISO7816.OFFSET_INS];
      if (cla == CLA_FUNCIONARIO) {
          try {
              switch (ins) {
                  // all my cases
                  default:
                      ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
          catch (UserException e) {
              ISOException.throwIt(e.getReason());
      else if (selectingApplet()) {
          return;
      else {
          byte tamanho_lido = (byte) apdu.setIncomingAndReceive();
          apdu.setOutgoing();
          apdu.setOutgoingLength((short) (tamanho_lido + 4));
          apdu.sendBytes((short) 0, (short) 4);
          apdu.sendBytes(ISO7816.OFFSET_CDATA, tamanho_lido);
          ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
    }First of all, I don't know what exactly does the method selectingApplet - in several source codes I've seen around, the verification for the SELECT APDU is done like this:
    (cla == ISO7816.CLA_ISO7816 && ins == ISO7816.INS_SELECT)But, there are some sample codes (like the JavaPurse on JCDK 2.1.1) that prove these two ways of checking the SELECT APDU is not equivalent. So, what's the difference between using the selectingApplet method and using the constants on the ISO7816 interface? Should I use both ways? Only one of them???
    The big problem is what is actually happening to my card. As it can be seen in the code above, if the applet is about to throw an SW_CLA_NOT_SUPPORTED exception, it writes the whole command that it received, so I can see what got there (sort of a System.out.println debugging). And here's what happens: everytime I send the command 0x00 0xA4 0x04 0x00 0x06 0x01 0x02 0x03 0x04 0x05 0x06 0x00, it returns 0x00 0xC0 0x00 0x00 as the response data and 0x6E00 as the status word!!! I googled and I found that C0 is the INS byte of the GET RESPONSE command. What is this command? It's not documented on the GlobalPlatform 2.0.1' specification. And why the hell my applet says it received this command when I send it a SELECT APDU?
    Any answer would be valuable :)
    Thanks!

    You are in the ISO7816 T=0 protocol. The 00CO000000 command is issued to receive the response to the previous SELECT command. You are not returning any data to the SELECT command, but the terminal side seems to insist on getting one.
    The GetResponse command should not be passed to the Applet by your card operating system, I consider this a bug.
    If you return data when selectingApplet() returns true, then you probably will not have any problem.

  • Exchanging APDU's with selected applet fails

    Hi all,
    1. I developed a cardlet( normal, sample one) using JCOP
    2. Installed, selected and excanged APDU's with this applet ( on Nokia 6212,6131 and JCOP cards)
    3. Now i tried it on a SE of SIM. In this case, installation and selection succeeds but exchanging APDU's with selected applet is partial. by 'partial' what i mean is:
    i am using 0x90 as CLA byte for personalisation (now i am not checking the CLA byte from cardelt code)
    private static final byte STORE=0x01;
    private static final byte GET=0x02; , and these are INS values for getting and storing personalisation data.
    if i send STORE command like */send 90010000084142434445464748* (8 data bytes ), only first 5 bytes are being transferred to applet (i tested this fact by returning the buffer(apdu.getBuffer()) length from process(APDU apdu) function ), not the actual data. ie, only CLA, INS, P1, P2, and LC fields are being transferred to applet. so, currently the actual personlisation data is not been transferred to selected applet.
    Is there any specific data format that has to be send to a selected applet ?
    or
    In which point i am going wrong ?
    This is the cardlet code i'm using
    import javacard.framework.APDU;
    import javacard.framework.ISO7816;
    import javacard.framework.Applet;
    import javacard.framework.ISOException;
    import javacard.framework.Util;
    public class TestCard extends Applet
        private static final byte STORE=0x01;
        private static final byte GET=0x02;
        private static byte personalized=0x00;
        private static byte[] value=null;
       // private static byte testByte;
        public static void install(byte[] bArray, short bOffset, byte bLength)
            // GP-compliant JavaCard applet registration
            new TestCard().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
        public void process(APDU apdu)
            // Good practice: Return 9000 on SELECT
            if (selectingApplet())
                return;
            byte[] buf = apdu.getBuffer();
            switch (buf[ISO7816.OFFSET_INS])
                case STORE:
                    value=new byte[buf[ISO7816.OFFSET_LC]];
                    //testByte=(byte)buf.length;
                    Util.arrayCopy(buf, (short)(ISO7816.OFFSET_LC+1), value, (short)0, buf[ISO7816.OFFSET_LC]);
                    personalized=(byte)0x01;
                    break;
                case GET:
                    if(personalized==0x00)
                        ISOException.throwIt((short)0x6999);
                        break;
                    //value=new byte[]{testByte};
                    apdu.setOutgoing();
                    apdu.setOutgoingLength((short)value.length);
                    apdu.sendBytesLong(value, (short)0, (short)value.length);
                    break;
                default:
                    // good practice: If you don't know the INStruction, say so:
                    ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
    }and this is the JCOP script i'm using
    /echo Opening terminal
    /terminal "winscard:4|OMNIKEY CardMan 5x21-CL 0"
    /echo Resets card
    /atr
    /echo Selecting TestCard Applet
    /select 11223344556600
    /echo Sending 8-byte Personalisation data ABCDEFGH (4142434445464748)
    /send 90010000084142434445464748
    /echo Reading personalised data
    /send 90020000and the output trace is
    /echo Opening terminal
    Opening terminal
    /terminal "winscard:4|OMNIKEY CardMan 5x21-CL 0"
    --Opening terminal
    /echo Resets card
    Resets card
    /atr
    --Waiting for card...
    ATR=3B 88 80 01 01 02 03 04 00 81 C0 00 4C             ;...........L
    /echo Selecting TestCard Applet
    Selecting TestCard Applet
    /select 11223344556600
    => 00 A4 04 00 07 11 22 33 44 55 66 00 00             ......"3DUf..
    (84234 usec)
    <= 90 00                                              ..
    Status: No Error
    /echo Sending 8-byte Personalisation data ABCDEFGH (4142434445464748)
    Sending 8-byte Personalisation data ABCDEFGH (4142434445464748)
    /send 90010000084142434445464748
    => 90 01 00 00 08 41 42 43 44 45 46 47 48             .....ABCDEFGH
    (168449 usec)
    <= 90 00                                              ..
    Status: No Error
    /echo Reading personalised data
    Reading personalised data
    /send 90020000
    => 90 02 00 00                                        ....
    (22838 usec)
    <= 00 00 00 00 00 00 00 00 90 00                      ."3DUf.... // here not getting the actual needed data.
    Status: No ErrorThanks and regards
    Sunil

    Hi all,
    after lot of trial and error and research, i found that in the above code, i am not using
    apdu.setIncomingAndReceive();this is where the problem lies. i set incoming mode after reading the apdu buffer and the problem solved.
    thanks and regards
    sunil

  • How to make apdu.getBuffer() return buf that is greater than 133 bytes.

        public void process(APDU apdu) {
          byte[] buf = new byte[256];
            buf = apdu.getBuffer();
            // GOOD PRACTICE: RETURN 9000 ON SELECT
            if (selectingApplet()) {
                return;
            apdu.setIncomingAndReceive();
            switch (buf[ISO7816.OFFSET_INS]) {
                case (byte) 0x01:
    This is my process method. I have a command APDU of length 200 bytes that I want the buffer to read and store into a local byte array. However, apdu.getBuffer() is only grabbing the first 133 bytes of data.
    According to javadocs:
    "The APDU object is owned by the Java Card runtime environment. The APDU class maintains a byte array buffer which is used to transfer incoming APDU header and data bytes as well as outgoing data. The buffer length must be at least 133 bytes ( 5 bytes of header and 128 bytes of data ). The Java Card runtime environment must zero out the APDU buffer before each new message received from the CAD."
    Since the buffer length is larger than 133 bytes, why does it not accept the remaining bytes?
    I am using jCardSim on NetBeans IDE, java card version 2.2.2.
    Also, could someone explain to me what exactly apdu.setIncomingAndReceive() does? My code is able to build/run both with and without it.
    Thanks

    I tried using that in my code, but it's still not working, I must be placing it in the wrong spot. I put it in the process method right before my switch cases. Do I actually put all of the code in the while loop? Perhaps you could explain the code to me, why do you only want the last two bytes of LC, and why 55? This is what it looks like currently:
        public void process(APDU apdu) {
            byte[] buf = apdu.getBuffer();
            // GOOD PRACTICE: RETURN 9000 ON SELECT
            if (selectingApplet()) {
                return;
           short bytesLeft = (short) (buf[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);
            // HARDCODED PARAMETERS TO PASS INTO FUNCTIONS
            byte[] O = new byte[6];
            byte[] U = new byte[3];
            byte[] N = new byte[5];
            byte[] A = new byte[4];
            Util.arrayCopy(buf, (short) (ISO7816.OFFSET_EXT_CDATA), O, (short) 0, (short) 6);
            Util.arrayCopy(buf, (short) (ISO7816.OFFSET_EXT_CDATA + 7), U, (short) 0, (short) 3);
            Util.arrayCopy(buf, (short) (ISO7816.OFFSET_EXT_CDATA + 11), N, (short) 0, (short) 5);
            Util.arrayCopy(buf, (short) (ISO7816.OFFSET_EXT_CDATA + 17), A, (short) 0, (short) 4);
            switch (buf[ISO7816.OFFSET_INS]) {
                case (byte) 0x01:
                    // CALL FUNCTION  R
                    byte[] b = R(O, U, N, A);
                    // PRINT B
                    apdu.setOutgoing();
                    apdu.setOutgoingLength((short) b.length);
                    apdu.sendBytesLong(b, (short) 0, (short) b.length);
                    break;
                case (byte) 0x02:
                    byte[] k2 = new byte[(short) 176];  
                    //29 is the offset in the command apdu that contains the parameter data
                   // THIS IS THE LINE THAT THE CODE FAILS AT - SINCE IT CAN ONLY READ 133 BYTES OF DATA, IT CAN'T ARRAY COPY 176 BYTES OF DATA FROM buf
                    Util.arrayCopy(buf, (short) 29, k2, (short) 0, (short) 176);
                    byte[] a = S(k2, O, U, N);
                    // PRINT a
                    apdu.setOutgoing();
                    apdu.setOutgoingLength((short) a.length);
                    apdu.sendBytesLong(a, (short) 0, (short) a.length);
                    break;

  • SetIncomingAndReceive and setOutgoing

    I have an applet works very smooth on JCOP card (T=1). Recently, I am trying to put this applet into Oberthur CosmopolIC Lite V1 and Gemplus GemXpresso Pro card (both T=1), and get very strange behavior on these 2 card. After my diagnosis, I found out the return code of setIncomingAndReceive and setOutgoing are different on these 3 cards.
    The logic of my applet is using setIncomingAndReceive and setOutgoing to define the lc and le. Thus, for an APDU case 2 command such as 00 86 00 00 08, the JCOP card will get lc=0 and le=8, Oberthur card will get lc=8 and le=8, and Gemplus card will get lc=8 and le=0. Anyone know the correct behavior of these 2 methods? Or I should not use these 2 methods to define the lc and le?
    A sample code can reproduce this problem is listed below for your reference, any comment will be appreciated!
    package test;
    * <p>Title: </p>
    * <p>Description: </p>
    * <p>Copyright: Copyright (c) 2003</p>
    * <p>Company: </p>
    * @author unascribed
    * @version 1.0
    import javacard.framework.*;
    import javacard.security.*;
    public class test extends Applet {
    // Class instruction type (CLA)
    static final byte TEST_CLA = (byte)0x00;
    // Instruction (INS)
    static final byte CASE2_TEST = (byte)0x86;
    // SW
    static final short SW_ERROR_1 = (short)0x6601;
    static final short SW_ERROR_2 = (short)0x6602;
    static final short SW_ERROR_3 = (short)0x6603;
    static final short SW_ERROR_4 = (short)0x6604;
    static final short SW_LE_NOT_8 = (short)0x6605;
    static final short SW_OK = (short)0x6600;
    // index of sys[]
    static final short LC = (byte)0;
    static final short LE = (byte)1;
    static final short LA = (byte)2;
    // transient objects
    private short[] sys = JCSystem.makeTransientShortArray( (short)14, JCSystem.CLEAR_ON_DESELECT );
    protected test( byte[] buffer, short offset, byte length ) {
    register();
    public static void install( byte[] bArray, short bOffset, byte bLength ) {
    new test( bArray, bOffset, bLength );
    public boolean select() {
    return true;
    public void deselect() {
    public void process( APDU apdu ) {
    byte[] apdu_buffer = apdu.getBuffer();
    sys[ LC ] = apdu.setIncomingAndReceive();
    if( selectingApplet() )
    return;
    if( apdu_buffer[ ISO7816.OFFSET_CLA ] != TEST_CLA )
    ISOException.throwIt( ISO7816.SW_CLA_NOT_SUPPORTED );
    switch( apdu_buffer[ ISO7816.OFFSET_INS ] ) {
    case CASE2_TEST:
    Case2( apdu, (short)0, (short)8 );
    return;
    default:
    ISOException.throwIt( ISO7816.SW_INS_NOT_SUPPORTED );
    private void processCase2( short lc, short le ) {
    ISOException.throwIt( (short) (Util.makeShort( (byte)sys[LC], (byte)sys [LE])));
    // if( sys[ LC ] != 0 )
    // ISOException.throwIt( SW_ERROR_1 );
    // ISOException.throwIt( (short) (sys[ LC ]) );
    if( _le == (short)0 )
    ISOException.throwIt( SW_ERROR_2 );
    if( (_lc > (short)0) && ( sys[ LC ] != _lc ) )
    ISOException.throwIt( SW_ERROR_3 );
    if( (_le > (short)0) && ( sys[ LE ] != _le ) )
    ISOException.throwIt( (short) (sys[ LE ]) );
    // ISOException.throwIt( SW_ERROR_4 );
    if( sys[ LC ] != 0 )
    // ISOException.throwIt( SW_ERROR_1 );
    ISOException.throwIt( (short) (sys[ LC ]) );
    private void Case2( APDU apdu, short lc, short le ) {
    byte[] buffer = apdu.getBuffer();
    sys[ LE ] = apdu.setOutgoing();
    apdu.setOutgoingLength( (short)8 );//sys[ LE ] );
    processCase2( lc, le );
    Util.setShort( buffer, (short)0, (short)200 );
    apdu.sendBytes( (short)0, (short)8 );

    This response involves off-card and on-card answers !
    --------------Off card
    What if the Le was 10H and middeware was expecting 20H ? I leave it up to the middleware to check the results.
    I've run into this where the card specifications changed and the middleware was "hard coded" to process the Le of a certain value. This ultimately crashed the middleware when the card spec changed. The proper design would have been for the middleware to CHECK the Le and process that amount of data.
    --------On card
    You might have an on-card design that was expecting to return data but wanted to make sure the Le was the proper size for the results.see setOutgoingLength()

  • APDU Commands - How they work ?

    Hi,
    Iam all new to the JavaCard programming and wanted to understand some basics. The APDU Commands (CLA, INS, P1, P2, ...) are they reserved commands (as in reserved words). If so, how do I get a listing of the same.
    Eg. I am looking into one of the programs which have the following few lines,
    SetLength(DataToSend, 13);
    DataToSend[0] := $88;
    DataToSend[1] := $10;
    DataToSend[2] := $11;
    DataToSend[3] := $00;
    DataToSend[4] := $08;
    DataToSend[5] := $F9;
    DataToSend[6] := $FD;
    DataToSend[7] := $CE;
    DataToSend[8] := $8B;
    DataToSend[9] := $F6;
    DataToSend[10] := $F4;
    DataToSend[11] := $14;
    DataToSend[12] := $E0;
    FSCard.SendCustomAPDU(DataToSend, ReceiveBuffer);
    I believe the above writes info. to the card.
    If Yes, how do I retrive the same from Card?
    If No, then what does the instruction stand for?
    Appreciate your help ....

    hI,
    Iam trying to write a sample code by trying to write data to card using XOR, converting the same back in the applet to the original string and retriving the same. The return value is still in XOR value and not the original i sent. Please let me know what iam doing wrong here?
    WRITING DATA:
    CLIENT PROGRAM:
    SetLength(DataToSend, 9);
    DataToSend[0] := $88;
    DataToSend[1] := $10;
    DataToSend[2] := $9A;
    DataToSend[3] := $00;
    DataToSend[4] := $4;
    DataToSend[5] := $A;
    DataToSend[6] := $B;
    DataToSend[7] := $C;
    DataToSend[8] := $D;
    DataToSend[5] := DataToSend[5] XOR DataToSend[6];
    DataToSend[6] := DataToSend[6] XOR DataToSend[7];
    DataToSend[7] := DataToSend[7] XOR DataToSend[8];
    DataToSend[8] := DataToSend[8] XOR DataToSend[5];
    FSCard.SendCustomAPDU(DataToSend, ReceiveBuffer);
    APPLET CALLS THIS PROCEDURE :
    private void SetStringSec5(APDU apdu) {
              byte buffer[] = apdu.getBuffer();
              byte size = (byte)(apdu.setIncomingAndReceive());
              byte index;
    byte indexsn;
    indexsn=0;
              // Store the length of the string and the string itself
              TheBuffer[80] = size;
              for (index = 80; index < (byte)(81+(int)(size)); index++){
                   TheBuffer[(byte)(index + 1)] = buffer[(byte)(ISO7816.OFFSET_CDATA + indexsn)];
    indexsn++;
              CalcSri();
    apdu.setOutgoing();
              apdu.setOutgoingLength((short)size);
    apdu.sendBytesLong(TheBuffer,(short)0,(short)size);
              return;
    private void CalcSri() {
              TheBuffer[(byte)(8)]=(byte)(((int)(TheBuffer[(byte)(5)])) ^ ((int)(TheBuffer[(byte)(8)])));
    TheBuffer[(byte)(7)]=(byte)(((int)(TheBuffer[(byte)(8)])) ^ ((int)(TheBuffer[(byte)(7)])));
              TheBuffer[(byte)(6)]=(byte)(((int)(TheBuffer[(byte)(7)])) ^ ((int)(TheBuffer[(byte)(6)])));
              TheBuffer[(byte)(5)]=(byte)(((int)(TheBuffer[(byte)(6)])) ^ ((int)(TheBuffer[(byte)(5)])));
              return;
    READING DATA:
    CLIENT PROGRAM :
    //Get string from the card
    SetLength(DataToSend, 5);
    DataToSend[0] := $88;
    DataToSend[1] := $10;
    DataToSend[2] := $BE;
    DataToSend[3] := $00;
    DataToSend[4] := $4;
    FSCard.SendCustomAPDU(DataToSend, ReceiveBuffer);
    APPLET CODE CALLING THE PROCEDURE:
    private void GetStr(APDU apdu) {
              byte buffer[] = apdu.getBuffer();
              byte numBytes = buffer[ISO7816.OFFSET_LC];
              apdu.setOutgoing();
              apdu.setOutgoingLength(numBytes);
              byte index;
    byte indexsn;
    indexsn=0;
              for (index = 80; index <= (byte)(80+(int)(numBytes)); index++){
                   buffer[(byte)(indexsn)] = TheBuffer[(byte)(index + 1)];
    indexsn++;
    apdu.sendBytesLong(buffer,(short)0,(short)numBytes);
              return;
    }

  • APDU buffer access

    Let’s say that I want to define the method that handles the command APDU that is located in the APDU buffer.
    I do not want for the method to have input parameter equals APDU. Instead I want the method to be without any input parameter. The method itself must be able to read the APDU buffer. Is it possible and if yes how? I saw the BACAccelerator class that has that kind of definition that suits me:
          * Unwraps (verify and decrypt) the command APDU located in the APDU buffer.
          * The command buffer has to be filled by the APDU.setIncomingAndReceive()
          * method beforehand. The verified and decrypted command data get placed at
          * the start of the APDU buffer.
         public short unwrapAPDU() throws BACAcceleratorException {
              return ((short) 0);
         }

    there is probably an application specific buffer that the APDU is copied into. This may be a field of the class that is accessed. This is just a guess though.
    Cheers,
    Shane

  • APDU LE byte

    Hi,
    it seems i do not understand the APDU. i want to send 4byte data and receive 2byte. So i sent:
    80 01 00 00 04 10 20 30 40 02
    The first 4byte are the header. LC is 4 for 4byte data (10 20 30 40) and then the LE byte follows with 02.
    But on the card this does not work:
    byte[] buffer = apdu.getBuffer();
    short length = apdu.setIncomingAndReceive(); // length = 4, thats right
    short expectedOutput = apdu.setOutgoing(); // expectedOutput = 256, why ???Iam not able to receive the LE byte. But in the ISO7816 this case (LC and LE not null) is one of the four cases which has to work with every card. Whats my fault ? :(

    I guess your card is using the T=0 protocol.
    Doc for setOutgoing states: "In T=0 (Case 4S) protocol, this method will return 256 with normal semantics."
    So everything is working as designed (I'm not saying: at is should have been designed).
    There is no problem if you know the expected length of the answer (that is the integer Ne, coded by Le) from the spec of the APDU and its input parameters excluding Le, and 0<Ne<256. In that case just set that Nr=Ne using setOutgoingLength and send Nr data bytes with sendBytes. The card will tell Nr to the reader (as part of a conventional status word), some glue code in the bowels of the Java runtime library or application should issue a Get Response command, and everything will be fine. This might work with Ne=256, coded by Le=00h, but do not bet on that without trying.
    There is no problem either if you are happy with the default behavior of truncating the Nr bytes of outgoing data to Ne coded by Le. Just do as above as if you knew Ne was the maximum it could be, and everything will be fine.
    If your in-card applet really needs (rather than know or assume) Ne, one option is to instead change the spec of the APDU and move Ne to P1,P2, or some of the ingoing data where you can get it.
    Else, well... I'd rather not dive into these messy details if the previous three simple options apply.

  • Send APDU just one time

    My application (in delphi) send Name(string), Family(string), And children (array of string)...
    then These data will convert into Hex format and will be sent to CAD via APDU...
    My question is how can I send all of these data at once via on APDU command, should I send Name and Family one by one and also send every index in my array one by one ??
    I wrote an applet which has a SetName, Set Family and SetChildren Methods and once call SetName and send Name via one APDU, then call SetFamily and send Family via other APDU, and the big problem is in array that I'm sending each index data of array via one APDU...
    I'm sure it's a foolish way and there's a better way to send these data :)
    would u please help me and guid me what can I do, this is so much urgent
    Kind Regards
    Hana

    Zip_Smart_Girl wrote:
    first a question about your last reply:
    I add this code in my applet process method, so what can i send from JCOP, can I now send Lc in 2 bytes ??The card you have is Java Card 2.2.1 which does not support extended length APDU's. As such your only choice is to implement chaining. This is also the reason why your code does not compile in Eclipse. You are building against the JC2.2.1 libraries.
    Here is some code that may help you get started. This code is not tested (apart from the fact it compiles) as I am not at work at the moment. This code comes with all the standard disclaimers and may not be fit for purpose... so use at your own risk :) There is still more validation that could go in (such as checking that the GET-RESPONSE command has the same CLA byte etc). Hopefully this code works and gets you started with command and response chaining. This may also help anyone else that needs to do something similar. If this can help just one person I will be happy.
    Cheers,
    Shane
    package chaining;
    import javacard.framework.APDU;
    import javacard.framework.Applet;
    import javacard.framework.ISO7816;
    import javacard.framework.ISOException;
    import javacard.framework.JCSystem;
    import javacard.framework.Util;
    * Very simple applet for chaining data to and from a card.
    * @author shane
    public class ChainingApplet extends Applet {
        private final static byte INS_GET_RESPONSE = (byte) 0xC0;
        private final static byte INS_PUT_DATA = 0x00;
        private final static byte INS_GET_DATA = 0x01;
        private final static byte OFFSET_SENT = 0x00;
        private final static byte OFFSET_RECV = 0x01;
        private static short[] offset;
        private static byte[] fileBuffer;
        private static short fileSize = 0;
        private final static short FILE_SIZE = 2048; // 2KB file
        private final static short MAX_APDU = 255;
         * Default constructor that initialises all memory to be used by the applet.
        public ChainingApplet() {
            offset = JCSystem.makeTransientShortArray((short) 2, JCSystem.CLEAR_ON_RESET);
            fileBuffer = new byte[FILE_SIZE];
         * {@inheritDoc}
        public static void install(byte[] bArray, short bOffset, byte bLength) {
            // GP-compliant JavaCard applet registration
            new ChainingApplet().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
         * {@inheritDoc}
        public void process(APDU apdu) {
            // Good practice: Return 9000 on SELECT
            if (selectingApplet()) {
                return;
            short len = apdu.setIncomingAndReceive(); // This is the amount of data read from the OS.
            byte[] buf = apdu.getBuffer();
            byte cla = buf[ISO7816.OFFSET_CLA];
            byte ins = buf[ISO7816.OFFSET_INS];
            short lc = (short) (buf[ISO7816.OFFSET_LC] & 0x00ff); // this is the LC from the APDU.
            // get all bytes from the buffer
            while (len < lc) {
                len += apdu.receiveBytes(len);
            // validate the INS byte (basic check that tests for valid GET-RESPONSE or GET-DATA)
            if (offset[OFFSET_SENT] > 0 && ins != INS_GET_RESPONSE) {
                ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
            } else if (ins == INS_GET_RESPONSE && offset[OFFSET_SENT] == 0) {
                ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
            switch (buf[ISO7816.OFFSET_INS]) {
                case INS_PUT_DATA:
                    saveData(buf, ISO7816.OFFSET_CDATA, offset[OFFSET_RECV], len);
                    if ((cla & 0x10) != 0x00) {
                        offset[OFFSET_RECV] += len;
                    } else {
                        // last command in the chain
                        fileSize = (short) (offset[OFFSET_RECV] + len);
                        offset[OFFSET_RECV] = 0;
                    break;
                case INS_GET_DATA:
                case INS_GET_RESPONSE:
                    sendData(apdu);
                    break;
                default:
                    // good practice: If you don't know the INStruction, say so:
                    ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
         * Simple method to save the data somewhere. Add real implementation here.
         * @param source
         *            buffer containing data to copy
         * @param sourceOff
         *            offset into source buffer to the data
         * @param destOff
         *            offset into the destination buffer
         * @param len
         *            length of the data to copy.
        private static void saveData(byte[] source, short sourceOff, short destOff, short len) {
            // prevent buffer overflow
            if ((short) (destOff + len) > FILE_SIZE) {
                ISOException.throwIt(ISO7816.SW_FILE_FULL);
            Util.arrayCopy(source, sourceOff, fileBuffer, destOff, len);
         * Simple method to send chainined data to the client application (if required).
         * @param apdu
         *            current APDU
        private void sendData(APDU apdu) {
            // work out how many bytes to send this time and how many will be left
            short remain = (short) (fileSize - offset[OFFSET_SENT]);
            boolean chain = remain > MAX_APDU;
            short sendLen = chain ? MAX_APDU : remain;
            // Get ready to send
            apdu.setOutgoing();
            apdu.setOutgoingLength(sendLen);
            apdu.sendBytesLong(fileBuffer, offset[OFFSET_SENT], sendLen);
            // Check to see if there are more APDU's to send
            if (chain) {
                offset[OFFSET_SENT] += sendLen; // count the bytes sent
                ISOException.throwIt(ISO7816.SW_BYTES_REMAINING_00); // indicate there are more bytes to come
            } else {
                offset[OFFSET_SENT] = 0; // no more bytes to send
    }

  • Unable to delete applet.....

    Hi all,
    I am unable to delete one applet which I have loaded in the card.
    There are 2 applets, one is purse and other is loyalty. And am using shareable interface in which loyalty is the server and purse is the client. I can delete the purse applet but i can't delete the loyalty from the card.
    Here is my code : There are in all 3 codes, one is purse, second is loyalty code and third is the shareable interface code. Can some one look at the code and tell me what's wrong in this programs.
    package com.gemplus.examples.loyalty;
    import javacard.framework.*;
    import visa.openplatform.*;
    public class Loyalty extends javacard.framework.Applet implements TestInterface
    static byte points ;
    protected Loyalty(byte[] buffer, short offset, byte length)
    // data offset is used for application specific parameter.
    // initialization with default offset (AID offset).
    short dataOffset = offset;
    if(length > 9) {
    // Install parameter detail. Compliant with OP 2.0.1.
    // | size | content
    // |------|---------------------------
    // | 1 | [AID_Length]
    // | 5-16 | [AID_Bytes]
    // | 1 | [Privilege_Length]
    // | 1-n | [Privilege_Bytes] (normally 1Byte)
    // | 1 | [Application_Proprietary_Length]
    // | 0-m | [Application_Proprietary_Bytes]
    // shift to privilege offset
    dataOffset += (short)(1 + buffer[offset]);
    // finally shift to Application specific offset
    dataOffset += (short)(1 + buffer[dataOffset]);
    // checks wrong data length
    if(buffer[dataOffset] != 4)
    // return received proprietary data length in the reason
    ISOException.throwIt((short)(ISO7816.SW_WRONG_LENGTH + offset + length - dataOffset));
    // go to proprietary data
    dataOffset++;
    // points = 0;
    // register this instance
    register(buffer, (short)(offset + 1), (byte)buffer[offset]);
    * Method installing the applet.
    * @param bArray the array constaining installation parameters
    * @param bOffset the starting offset in bArray
    * @param bLength the length in bytes of the data parameter in bArray
    public static void install(byte[] bArray, short bOffset, byte bLength) throws ISOException
    /* applet instance creation */
    new Loyalty (bArray, bOffset, (byte)bLength);
    * Select method returning true if applet selection is supported.
    * @return boolean status of selection.
    public boolean select()
    /* return status of selection */
    return true;
    * Deselect method.
    public void deselect()
    return;
    public void process(APDU apdu) throws ISOException
              // check valid Applet state
    if(OPSystem.getCardContentState() == OPSystem.APPLET_BLOCKED)
              ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
                   apdu.setIncomingAndReceive();
              byte[] apduBuffer = apdu.getBuffer();
    // writes the balance into the APDU buffer after the APDU command part
              creditPoints((byte)0x00);     
              apduBuffer[5] = (byte)(points >> 8) ;
              apduBuffer[6] = (byte)points ;
    // sends the APDU response
    // switches to output mode
              apdu.setOutgoing() ;
    // 2 bytes to return
              apdu.setOutgoingLength((short)2) ;
    // offset and length of bytes to return in the APDU buffer
              apdu.sendBytes((short)5, (short)2) ;
         public void creditPoints(byte pTobeCredited)
    points += pTobeCredited;
    public Shareable getShareableInterfaceObject(AID client, byte param){
              if(param != (byte)0x00)
                   return null;
         return (this);
    second code is :
    package com.gemplus.examples.oppurse;
    * Imported packages
    import javacard.framework.*;
    import visa.openplatform.*;
    import com.gemplus.examples.loyalty.*;
    public class OPPurse extends javacard.framework.Applet
    // the APDU constants for all the commands.
         private final static byte INS_GET_BALANCE = (byte)0x30 ;
         private final static byte INS_DEBIT      = (byte)0x31 ;
         private final static byte INS_CREDIT      = (byte)0x32 ;
         private final static byte INS_VERIFY_PIN = (byte)0x33 ;
         private final static byte INS_SET_NAME                    = (byte)0x34 ;
         private final static byte INS_GET_NAME                    = (byte)0x35 ;
    // the OP/VOP specific instruction set for mutual authentication
         private final static byte CLA_INIT_UPDATE = (byte)0x80 ;
         private final static byte INS_INIT_UPDATE = (byte)0x50 ;
         private final static byte CLA_EXTERNAL_AUTHENTICATE = (byte)0x84 ;
         private final static byte INS_EXTERNAL_AUTHENTICATE = (byte)0x82 ;
    // the PIN validity flag
    private boolean validPIN = false;
    // SW bytes for PIN Failed condition
         // the last nibble is replaced with the number of remaining tries
         private final static short      SW_PIN_FAILED = (short)0x63C0;
         private final static short SW_FAILED_TO_OBTAIN_SIO = (short)0x63D0;
         private final static short SW_LOYALTY_APP_NOT_EXIST = (short)0x63E0;
    // the illegal amount value for the exceptions.
    private final static short ILLEGAL_AMOUNT = 1;
    // the maximum balance in this purse.
    private static final short maximumBalance = 10000;
    // the current balance in this purse.
    private static short balance;
    /*     byte[] loyaltyAID = new byte[]{ (byte)0xA0,(byte)0x00,(byte)0x00,(byte)0x00,
              (byte)0x19,(byte)0xFF,(byte)0x00,(byte)0x00,
              (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,
              (byte)0x00,(byte)0x00,(byte)0x02,(byte)0x02};*/
    /* Security part of declarations */
    // the Security Object necessary to credit the purse
    private ProviderSecurityDomain securityObject = null;
    // the security channel number
    byte secureChannel = (byte)0xFF;
    // the authentication status
    private boolean authenticationDone = false;
    // the secure channel status
    private boolean channelOpened = false;
         private byte[] nameBuffer = new byte[6];
    * Only this class's install method should create the applet object.
    protected OPPurse(byte[] buffer, short offset, byte length)
    // data offset is used for application specific parameter.
    // initialization with default offset (AID offset).
    short dataOffset = offset;
    if(length > 9) {
    // Install parameter detail. Compliant with OP 2.0.1.
    // | size | content
    // |------|---------------------------
    // | 1 | [AID_Length]
    // | 5-16 | [AID_Bytes]
    // | 1 | [Privilege_Length]
    // | 1-n | [Privilege_Bytes] (normally 1Byte)
    // | 1 | [Application_Proprietary_Length]
    // | 0-m | [Application_Proprietary_Bytes]
    // shift to privilege offset
    dataOffset += (short)( 1 + buffer[offset]);
    // finally shift to Application specific offset
    dataOffset += (short)( 1 + buffer[dataOffset]);
    // checks wrong data length
    if(buffer[dataOffset] != 2)
    // return received proprietary data length in the reason
    ISOException.throwIt((short)(ISO7816.SW_WRONG_LENGTH + offset + length - dataOffset));
    // go to proprietary data
    dataOffset++;
    } else {
    // Install parameter compliant with OP 2.0.
    if(length != 2)
    ISOException.throwIt((short)(ISO7816.SW_WRONG_LENGTH + length));
              // retreive the balance value from the APDU buffer
    short value = (short)(((buffer[(short)(dataOffset + 1)]) & 0xFF)
              | ((buffer[dataOffset] & 0xFF) << 8));
    // checks initial balance value
    if(value > maximumBalance)
    ISOException.throwIt(ISO7816.SW_DATA_INVALID);
              // initializes the balance with the APDU buffer contents
    balance = value;
    // register this instance as an installed Applet
    register();
    // ask the system for the Security Object associated to the Applet
    securityObject = OPSystem.getSecurityDomain();
    // applet is personalized and its state can change
    OPSystem.setCardContentState(OPSystem.APPLET_PERSONALIZED);
    // build the new ATR historical bytes
    byte[] newATRHistory = new byte[]
    // put "OPPurse" in historical bytes.
    (byte)0x4F, (byte)0x50, (byte)0x50, (byte)0x75, (byte)0x72, (byte)0x73, (byte)0x65
    // !!! ACTIVATED IF INSTALL PRIVILEGE IS "Default Selected" (0x04). !!!
    // change the default ATR to a personalized's one
    OPSystem.setATRHistBytes(newATRHistory, (short)0, (byte)newATRHistory.length);
    * Method installing the applet.
    * @param installparam the array constaining installation parameters
    * @param offset the starting offset in installparam
    * @param length the length in bytes of the data parameter in installparam
    public static void install(byte[] installparam, short offset, byte length )
    throws ISOException
    // applet instance creation with the initial balance
    new OPPurse(installparam, offset, length );
    * Select method returning true if applet selection is supported.
    * @return boolean status of selection.
    public boolean select()
    validPIN = false;
    // reset security if used.
    // In case of reset deselect is not called
    reset_security();
    // return status of selection
    return true;
    * Deselect method.
    public void deselect()
    // reset security if used.
    reset_security();
    return;
    * Method processing an incoming APDU.
    * @see APDU
    * @param apdu the incoming APDU
    * @exception ISOException with the response bytes defined by ISO 7816-4
    public void process(APDU apdu) throws ISOException
    // get the APDU buffer
    // the APDU data is available in 'apduBuffer'
    byte[] apduBuffer = apdu.getBuffer();
    // the "try" is mandatory because the debit method
    // can throw a javacard.framework.UserException
    try
         switch(apduBuffer[ISO7816.OFFSET_INS])
    case INS_VERIFY_PIN :
         verifyPIN(apdu);
    break ;
    case INS_GET_BALANCE :
         getBalance(apdu) ;
    break ;
    case INS_DEBIT :
         debit(apdu) ;
    break ;
                        case INS_SET_NAME :
                             setName(apdu);
                        break;
                        case INS_GET_NAME :
                             getName(apdu);
                        break ;
    case INS_CREDIT :
         credit(apdu) ;
    break ;
    case INS_INIT_UPDATE :
    if(apduBuffer[ISO7816.OFFSET_CLA] == CLA_INIT_UPDATE)
    // call initialize/update security method
         init_update(apdu) ;
    else
    // wrong CLA received
    ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
    break ;
    case INS_EXTERNAL_AUTHENTICATE :
    if(apduBuffer[ISO7816.OFFSET_CLA] == CLA_EXTERNAL_AUTHENTICATE)
    // call external/authenticate security method
         external_authenticate(apdu) ;
    else
    // wrong CLA received
    ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
    break ;
    case ISO7816.INS_SELECT :
    break ;
    default :
    // The INS code is not supported by the dispatcher
         ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED) ;
    break ;
         }     // end of the switch
    } // end of the try
              catch(UserException e)
    // translates the UserException in an ISOException.
              if(e.getReason() == ILLEGAL_AMOUNT)
    throw new ISOException ( ISO7816.SW_DATA_INVALID ) ;
    //- P R I V A T E M E T H O D S -
         * Handles Verify Pin APDU.
         * @param apdu APDU object
         private void verifyPIN(APDU apdu)
    // get APDU data
              apdu.setIncomingAndReceive();
    // get APDU buffer
    byte[] apduBuffer = apdu.getBuffer();
    // check that the PIN is not blocked
    if(OPSystem.getTriesRemaining() == 0)
    OPSystem.setCardContentState(OPSystem.APPLET_BLOCKED);
    // Pin format for OP specification
    // |type(2),length|nible(1),nible(2)|nible(3),nible(4)|...|nible(n-1),nible(n)|
    // get Pin length
    byte length = (byte)(apduBuffer[ISO7816.OFFSET_LC] & 0x0F);
    // pad the PIN ASCII value
    for(byte i=length; i<0x0E; i++)
    // only low nibble of padding is used
    apduBuffer[ISO7816.OFFSET_CDATA + i] = 0x3F;
    // fill header TAG
    apduBuffer[0] = (byte)((0x02 << 4) | length);
    // parse ASCII Pin code
    for(byte i=0; i<0x0E; i++)
    // fill bytes with ASCII Pin nibbles
    if((i & 0x01) == 0)
    // high nibble
    apduBuffer[(i >> 1)+1] = (byte)((apduBuffer[ISO7816.OFFSET_CDATA + i] & 0x0F) << 4);
    else
    // low nibble
    apduBuffer[(i >> 1)+1] |= (byte)(apduBuffer[ISO7816.OFFSET_CDATA + i] & 0x0F);
    // verify the received PIN
    // !!! WARNING PIN HAS TO BE INITIALIZED BEFORE USE !!!
    if(OPSystem.verifyPin(apdu, (byte)0))
    // set PIN validity flag
    validPIN = true;
    // if applet state is BLOCKED then restore previous state (PERSONALIZED)
    if(OPSystem.getCardContentState() == OPSystem.APPLET_BLOCKED)
    OPSystem.setCardContentState(OPSystem.APPLET_PERSONALIZED);
    return;
         // the last nibble of returned code is the number of remaining tries
              ISOException.throwIt((short)(SW_PIN_FAILED + OPSystem.getTriesRemaining()));
    * Performs the "getBalance" operation on this counter.
    * @param apdu The APDU to process.
    private void getBalance( APDU apdu )
    // check valid Applet state
    if(OPSystem.getCardContentState() == OPSystem.APPLET_BLOCKED)
                   ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
    // get the APDU buffer
    byte[] apduBuffer = apdu.getBuffer();
    // writes the balance into the APDU buffer after the APDU command part
              apduBuffer[5] = (byte)(balance >> 8) ;
              apduBuffer[6] = (byte)balance ;
    // sends the APDU response
    // switches to output mode
              apdu.setOutgoing() ;
    // 2 bytes to return
              apdu.setOutgoingLength((short)2) ;
    // offset and length of bytes to return in the APDU buffer
              apdu.sendBytes((short)5, (short)2) ;
         private void setName(APDU apdu)
              // check valid Applet state
    if(OPSystem.getCardContentState() == OPSystem.APPLET_BLOCKED)
                   ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
              // the operation is allowed only if master pin is validated
         if(!validPIN)
    ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
              byte[] apduBuffer = apdu.getBuffer();
              apdu.setIncomingAndReceive();     
              for(short i=0,k=5;i<6;i++,k++)
                   nameBuffer[i] = apduBuffer[k];
         }//end of setName
         private void getName(APDU apdu)
              // check valid Applet state
    if(OPSystem.getCardContentState() == OPSystem.APPLET_BLOCKED)
                   ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
                   byte[] apduBuffer = apdu.getBuffer();
                   for(short i=5, k=0;i<11;i++,k++)
                        apduBuffer=nameBuffer[k];
                   apdu.setOutgoing();
                   apdu.setOutgoingLength((short)6);
                   apdu.sendBytes((short)5,(short)6);
         }//end of storeName
    * Performs the "debit" operation on this counter.
    * @param apdu The APDU to process.
    * @exception ISOException If the APDU is invalid.
    * @exception UserException If the amount to debit is invalid.
    private void debit(APDU apdu) throws ISOException, UserException
    // check valid Applet state
    if(OPSystem.getCardContentState() == OPSystem.APPLET_BLOCKED)
                   ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
    // the operation is allowed only if master pin is validated
         if(!validPIN)
    ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
    // get the APDU buffer
    byte[] apduBuffer = apdu.getBuffer();
         // Gets the length of bytes to recieved from the terminal and receives them
    // If does not receive 4 bytes throws an ISO.SW_WRONG_LENGTH exception
              if(apduBuffer[4] != 2 || apdu.setIncomingAndReceive() != 2)
              ISOException.throwIt(ISO7816.SW_WRONG_LENGTH) ;
              // Reads the debit amount from the APDU buffer
    // Starts at offset 5 in the APDU buffer since the 5 first bytes
    // are used by the APDU command part
              short amount = (short)(((apduBuffer[6]) & (short)0x000000FF)
    | ((apduBuffer[5] << 8 ) & (short)0x0000FF00));
    // tests if the debit is valid
    if((balance >= amount) && (amount > 0))
    // does the debit operation
    balance -= amount ;
    // writes the new balance into the APDU buffer
    // (writes after the debit amount in the APDU buffer)
    apduBuffer[7] = (byte)(balance >> 8) ;
    apduBuffer[8] = (byte)balance ;
    // sends the APDU response
    apdu.setOutgoing() ; // Switches to output mode
    apdu.setOutgoingLength((short)2) ; // 2 bytes to return
    // offset and length of bytes to return in the APDU buffer
    apdu.sendBytes((short)7, (short)2) ;
              /*short points = 10;
    AID loyaltyID = JCSystem.lookupAID(loyaltyAID, (short)0, (byte)loyaltyAID.length);
              if(loyaltyID == null)
                   ISOException.throwIt((short)(SW_LOYALTY_APP_NOT_EXIST));
              TestInterface sio = (TestInterface)(JCSystem.getAppletShareableInterfaceObject(loyaltyID, (byte)0x00));
              if(sio == null)
                   ISOException.throwIt((short)(SW_FAILED_TO_OBTAIN_SIO));
              sio.creditPoints(points);*/
    else
    // throw a UserException with illegal amount as reason
    throw new UserException(ILLEGAL_AMOUNT) ;
    /* byte points = (byte)0x0A;
              //short points = 10;
    AID loyaltyID = JCSystem.lookupAID(loyaltyAID, (short)0, (byte)loyaltyAID.length);
              if(loyaltyID == null)
                   ISOException.throwIt((short)(SW_LOYALTY_APP_NOT_EXIST));
              TestInterface sio = (TestInterface)JCSystem.getAppletShareableInterfaceObject(loyaltyID, (byte)0x00);
              if(sio == null)
                   ISOException.throwIt((short)(SW_FAILED_TO_OBTAIN_SIO));
              sio.creditPoints(points);*/
    * Performs the "credit" operation on this counter. The operation is allowed only
    * if master pin is validated
    * @param apdu The APDU to process.
    * @exception ISOException If the APDU is invalid or if the amount to credit
    * is invalid.
    private void credit(APDU apdu) throws ISOException
    // check valid Applet state
    if(OPSystem.getCardContentState() == OPSystem.APPLET_BLOCKED)
                   ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
    // the operation is allowed only if master pin is validated and authentication is done
         if (!validPIN || !authenticationDone)
    ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
    // get the APDU buffer
    byte[] apduBuffer = apdu.getBuffer();
              // gets the length of bytes to recieved from the terminal and receives them
    // if does not receive 2 bytes throws an ISO.SW_WRONG_LENGTH exception
              if(apduBuffer[4] != 2 || apdu.setIncomingAndReceive() != 2)
    throw new ISOException(ISO7816.SW_WRONG_LENGTH) ;
              // reads the credit amount from the APDU buffer
    // starts at offset 5 in the APDU buffer since the 5 first bytes
    // are used by the APDU command part
              short amount = (short)(((apduBuffer[6]) & (short)0x000000FF)
    | ((apduBuffer[5] << 8) & (short)0x0000FF00));
    // tests if the credit is valid
    if(((short)(balance + amount) > maximumBalance) || (amount <= (short)0))
    throw new ISOException(ISO7816.SW_DATA_INVALID) ;
    else
    // does the credit operation
    balance += amount ;
    * Performs the "init_update" security operation.
    * @param apdu The APDU to process.
    private void init_update( APDU apdu )
    // receives data
    apdu.setIncomingAndReceive();
    // checks for existing active secure channel
    if(channelOpened)
    // close the openned security channel
    try
    securityObject.closeSecureChannel(secureChannel);
    catch(CardRuntimeException cre2)
    // channel number is invalid. this case is ignored
    // set the channel flag to close
    channelOpened = false;
    try
    // open a new security channel
    secureChannel = securityObject.openSecureChannel(apdu);
    // set the channel flag to open
    channelOpened = true;
    // get expected length
    short expected = apdu.setOutgoing();
    // send authentication result
    // expected length forced to 0x1C
    apdu.setOutgoingLength((byte)0x1C);
    apdu.sendBytes(ISO7816.OFFSET_CDATA, (byte)0x1c);
    catch(CardRuntimeException cre)
    // no available channel or APDU is invalid
    ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
    * Performs the "external_authenticate" security operation.
    * @param apdu The APDU to process.
    private void external_authenticate( APDU apdu )
    // receives data
    apdu.setIncomingAndReceive();
    // checks for existing active secure channel
    if(channelOpened)
    try
    // try to authenticate the client
    securityObject.verifyExternalAuthenticate(secureChannel, apdu);
    // authentication succeed
    authenticationDone = true;
    catch(CardRuntimeException cre)
    // authentication fails
    // set authentication flag to fails
    authenticationDone = false;
    // close the openned security channel
    try {
    securityObject.closeSecureChannel(secureChannel);
    } catch(CardRuntimeException cre2) {
    // channel number is invalid. this case is ignored
    // set the channel flag to close
    channelOpened = false;
    // send authentication result
    ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
    // send authentication result
    ISOException.throwIt(ISO7816.SW_NO_ERROR);
    else
    ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
    * The "reset_security" method close an opened secure channel if exist.
    * @return void.
    public void reset_security()
    // close the secure channel if openned.
    if(secureChannel != (byte)0xFF)
    try
    // close the openned security channel
    securityObject.closeSecureChannel(secureChannel);
    catch(CardRuntimeException cre2)
    // channel number is invalid. this case is ignored
    // reset security parameters
    secureChannel = (byte)0xFF;
    channelOpened = false;
    authenticationDone = false;
    return;
    and the 3rd code is:
    package com.gemplus.examples.loyalty;
    import javacard.framework.Shareable;
    public interface TestInterface extends Shareable
    // public void creditPoints(byte points) ;
              public void creditPoints(byte points) ;
    Thanks in advance......

    Thanks. I know they are not the same thing. A package cannot be deleted if it contains one or more applets.
    I tried to delete by typing in the applet AID first, but it just doesn't work. And of course it doesn't work for package AID.
    Both the package and applet AID are generated in JBuilder, which looks like this, package AID(6D 79 70 61 63 6B 61 67 31),
    applet AID(6D 79 70 61 63 30 30 30 31),
    instance AID(6D 79 70 61 63 30 30 30 31)
    I've tried those three AIDs, it's not working.
    Thanks.

  • Can I use ISD for secure Channel?

    Hi all,
    Forgive me if this is a silly question but I am still :o( baffled by what I can and what I cannot do between a host app and JC/OP applet, with SD and without SD
    Can I do the following if this applet is associated with no SD except by default the ISD? Will this.mySD = OPSystem.getSecurityDomain(); return the ISD and will this unwrap commands sent to this applet if I send init-update255 and ext-auth mac as below?
    public boolean select()
      this.mySD = OPSystem.getSecurityDomain();
      //The applet declines to be selected if the pin is blocked
      if (pin.getTriesRemaining() == 0)
         return false;
      else
         return true;
    }// end of select method
    public void deselect()
      // reset the pin value
      pin.reset();
    }//end of deselect method
    public void process(APDU apdu)
      byte [] buffer = apdu.getBuffer();
      if(selectingApplet())
           return;
      // code to execute if applet is not yet PERSONALIZED
      if (OPSystem.getCardContentState() != OPSystem.APPLET_PERSONALIZED)
          apdu.setIncomingAndReceive();
          switch (buffer[ISO7816.OFFSET_INS] & 0xff)
            case (byte) 0x50 : // VOP INITIALIZE UPDATE
               secureChannel[0] = mySD.openSecureChannel(apdu);
               apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, buffer[ISO7816.OFFSET_LC]);
            break;
            case 0x82 : // VOP EXTERNAL AUTHENTICATE
         mySD.verifyExternalAuthenticate(secureChannel[0], apdu);
         break:
            case (byte) 0x02 :
                        OPSystem.getSecurityDomain().unwrap(secureChannel[0],apdu);
         // set key data: des-key will take 8 bytes even if we get more from
         // terminal
         desKey.setKey(buffer, ISO7816.OFFSET_CDATA);
         // finally set applet life cycle state to PERSONALIZED
         OPSystem.setCardContentState(OPSystem.APPLET_PERSONALIZED);
            break;
    } // end switch
    // else applet in PERSONALIZED state And the JCOP shell commands are
    Card Manager AID   :  A000000003000000
    Card Manager state :  OP_READY
        Application:  SELECTABLE (--------) "WalletTransact"
        Application:  SELECTABLE (--------) "WalletApplet" 
        Load File  :      LOADED (--------) A0000000620001   (java.lang)
        Load File  :      LOADED (--------) A0000000620101   (javacard.framework)
        Load File  :      LOADED (--------) A0000000620102   (javacard.security)
        Load File  :      LOADED (--------) A0000000620201   (javacardx.crypto)
        Load File  :      LOADED (--------) A0000000030000   (visa.openplatform)
        Load File  :      LOADED (--------) A000000167413001 (FIPS 140-2)
        Load File  :      LOADED (--------) A0000001320001   (org.javacardforum.javacard.biometry)
        Load File  :      LOADED (--------) A0000000035350   (Security Domain)
        Load File  :      LOADED (--------) A000000063       (PKCS15)
        Load File  :      LOADED (--------) "walletTransPack"
        Load File  :      LOADED (--------) "walletPackage"
    select |WalletApplet => 00 A4 04 00 08 A0 00 00 00 03 00 00 00 00          ..............
    (120 msec)
    <= 6F 19 84 08 A0 00 00 00 03 00 00 00 A5 0D 9F 6E    o..............n
        06 40 51 40 35 21 14 9F 65 01 FF 90 00             .@Q@5!..e....
    Status: No Error
    init-update 255 => 80 50 00 00 08 F4 AE 67 6B 70 B8 FC D1 00          .P.....gkp....
    (71 msec)
    <= 00 00 40 35 12 34 56 78 98 76 FF 01 B0 59 32 FB    [email protected].
        DE 9A C4 E9 87 04 AD 32 03 41 36 54 90 00          .......2.A6T..
    Status: No Error
    ext-auth mac => 84 82 01 00 10 79 C6 EA 2E 0F 5F D9 BD FA C7 81    .....y...._.....
        36 47 71 8B 38                                     6Gq.8
    (50 msec)
    <= 90 00                                              ..
    Status: No Error
    send 00020000081122334455667788 => 04 02 00 00 10 11 22 33 44 55 66 77 88 15 BD B4    ......"3DUfw....
        FB 79 6A C0 71                                     .yj.q
    (8322 msec)
    <= 6E 00                                              n.
    Status: CLA value not supported

    well...you cannot use the firmware for befw11s4 v4 to be upgraded on befw11s4 v2 ..

Maybe you are looking for

  • This 3 month warranty is really starting to get me angry...

    Dude, I swear they time the zen micro!!! after the 3 month warranty, it dies on you, and youre expected to pay forty bucks to get it fixed... thats really, really low of creative... I supported it by buying the zen micro on the first day, and this is

  • Replacement for Function Module 'SEND_TABLE_TO_EXCEL' in ECC 6.0

    Hi Friends, Can anybody help me to find the replacement of Function Module <b>'SEND_TABLE_TO_EXCEL'</b> in ECC 6.0. The Function Module exists in 4.6b. But it is no longer available in ECC 6.0. Regards, Vaitheeswaran.

  • Prime Infrastructure 2.0: Inventory/detailed HW reports customizing

    Hello, isn't it possible to run a/one detailed hardware report that includes the chassis information Name, the device name, the chassis serial number? Example: Chassis Information Name Device Hostname Serial Number WS-C3750V2-24PS-S switch1x2 FX31338

  • Jsf ppr - uix ppr

    Hello, This is also cross posted in the JDev forum because i'm not sure where it belongs. Jsf ppr <-> uix ppr The page is generated with JHS and the only important thing I changed was adding the partialtrigger and autosumbit/immediate on the fields,

  • Pre-order = gaurentee?

    Hi! If I pre-order my iphone 4 for pick up at the apple store, am I gaurenteed one despite what time I pick it up? Thanks!