This discussion is archived
8 Replies Latest reply: Feb 14, 2012 6:44 AM by 917156 RSS

APDU error 6Cxx

917156 Newbie
Currently Being Moderated
Hi,

I am building my first applet, and I am unable to send data from applet with method. I get error 6C (invalid length).

-> Command APDU:
80 F1 00 00 10 00 01 02 03 04 05 06 07 08 09 0A
0B 72 9F 59 10 7F
<- Response APDU:
6C 08
Command time: 220 ms

-> Command APDU:
80 F1 00 00 10 00 01 02 03 04 05 06 07 08 09 0A
0B 72 9F 59 10 08
<- Response APDU:
6C 08
Command time: 34 ms

My tool automatically detects error and changes Le parameter and repeats command with corrent Le value, but error is the same. Applet source code is simple:

....
byte myID[] = new byte[]{0x00, 0x03, (byte)0x8D, 0x7E, (byte)0xA4, (byte)0xC6, (byte)0x80, 0x01};
apdu.setOutgoing();
apdu.setOutgoingLength((short)myID.length);
apdu.sendBytesLong(myID, (short)0, (short)myID.length);
.....

If I remove last 3 lines, I get 90 00 return code. I compile with Javacard development kit 2.2.2

I tried the same code with javacard 3.0.2 and netbeans simulator. Code works fine. But when compile it with JC 2.2.2 and upload it to a card I get this error 6C08. All other methods work file as long as I do not send bytes from applet.
  • 1. Re: APDU error 6Cxx
    Umer Journeyer
    Currently Being Moderated
    Please try :
    byte[] buffer = apdu.getBuffer();
    Util.arrayCopy( myID, ( short )0, buffer, ( short )0, (short)myID.length );
    apdu.setOutgoingAndSend( (short)0, (short)myID.length);
    And also please can you post your code here ?
  • 2. Re: APDU error 6Cxx
    917156 Newbie
    Currently Being Moderated
    Hi,

    I tried your code and the result was the same. Then I created new TEST applet.
    package test;
    
    import javacard.framework.*;
    
    public class Test extends Applet {
    
        final static byte TEST_CLA =(byte)0x80;
        
        final static byte SELECT_INS = (byte)0xA4;
        final static byte GET_ID_INS = (byte)0xF1;
        final static byte STATUS_INS = (byte)0xF2;
        
        public static void install(byte[] bArray, short bOffset, byte bLength) {
            new Test();
        }
    
        protected Test() {
            register();
        }
    
        public void process(APDU apdu) {
            byte[] buffer = apdu.getBuffer();
    
            if (SELECT_INS == buffer[ISO7816.OFFSET_INS])
            {
              return;
            }
            
            if (buffer[ISO7816.OFFSET_CLA] != TEST_CLA)
                ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
            
            switch (buffer[ISO7816.OFFSET_INS]) {
    
                case GET_ID_INS:
                    getID(apdu);
                    break;
                    
                case STATUS_INS:
                    status(apdu);
                    break;
                    
                default:
                    ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
                    break;
            }
        }
        
        private void getID(APDU apdu)
        {   
            byte myID[] = new byte[]{0x00, 0x03, (byte)0x8D, 0x7E, (byte)0xA4, (byte)0xC6, (byte)0x80, 0x01};
            apdu.setOutgoing();
            apdu.setOutgoingLength((short)myID.length);
            apdu.sendBytesLong(myID, (short)0, (short)myID.length);
        }
        
        private void status(APDU apdu)
        {
            
        }
    }
    And I found out that it works and returns myID. The main difference that I do not send data to this applet (Lc and data is empty).
    // works fine
    -> 80 F1 00 00 08 
    <- 00 03 8D 7E A4 C6 80 01 90 00 
    // hangs or returns 6Cxx
    -> 80 F1 00 00 01 01 08 
    <- 
    So when I send Lc <data> this test applet hangs, strangely the first applet returns 6Cxx error (although I do not find difference in functions).
    So I added a status function, to test if problem occurs only when data is sent to applet. And I was able to send data to status function and get 90 00.
    // works fine
    --> 80 F2 00 00 04 01 02 03 04 7F
    <-- 90 00
    So my conclusion is that I can not send and receive data in one call or at least do not know how?
  • 3. Re: APDU error 6Cxx
    Umer Journeyer
    Currently Being Moderated
    user3597450 wrote:

    I tried your code and the result was the same. Then I created new TEST applet.

    And I found out that it works and returns myID. The main difference that I do not send data to this applet (Lc and data is empty).
    // works fine
    -> 80 F1 00 00 08 
    <- 00 03 8D 7E A4 C6 80 01 90 00 
    It is working because it is correct APDU
    // hangs or returns 6Cxx
    --> 80 F1 00 00 01 01 08 
    APDU is not correct as:
    LC= 1 but data is 2bytes.
    >
    So my conclusion is that I can not send and receive data in one call or at least do not know how?
    Yes you can send and receive in one row (with same APDU).
    You need to send the APDU in correct formate. If you are only getting data from the card then you just need to specify the Le byte that how much data you are wanting form the card and if you want to get all the data available just set L2 = 00. And do not send data with that command, as below
    cm>  /send 80F1000000
     => 80 F1 00 00 00                                     .....
     (941740 nsec)
     <= 00 03 8D 7E A4 C6 80 01 90 00                      ...~......
    Status: No Error
    ALso you need to change your code little bit:
    //don't use this
      if (SELECT_INS == buffer[ISO7816.OFFSET_INS])
            {
              return;
            }
    //use this one
            if (selectingApplet())
            {
                   return;
            }
    Regards
  • 4. Re: APDU error 6Cxx
    917156 Newbie
    Currently Being Moderated
    Did the code fix. Thanks for the tip.
    Yes, changing Le to 00, returns all bytes.

    You said that this is incorrect APDU:
    80 F1 00 00 01 01 08 
    I tried this APDU:
    80 F1 00 00 02 01 08 
    Result is the same, application hangs. I use JLoad application from G&D and APDU validation says that 80 F1 00 00 01 01 08 is correct APDU. I can send APDU bytes manually with that tool or use form to se CLA, INS, P1, P2, DATA, and Le. It automatically calculates Lc and and generates APDU bytes in that case my APDU was correct.

    Could this be application issue?
  • 5. Re: APDU error 6Cxx
    917156 Newbie
    Currently Being Moderated
    I googled a little bit and found GPShell. I downloaded it and tried the same APDU. And I got the same error.
    send_apdu -APDU 80F10000010108
    Command --> 80F10000010108
    Wrapped command --> 80F10000010108
    send_APDU() returns 0x0000045D (The request could not be performed because of an I/O device error.
    )
    send_apdu -APDU 80F10000020108
    Command --> 80F10000020108
    Wrapped command --> 80F10000020108
    send_APDU() returns 0x0000045D (The request could not be performed because of an I/O device error.
    )
    Wrapped command --> 80F1000008
    Response <-- 8301F8EF282A40019000
    send_APDU() returns 0x80209000 (9000: Success. No error.)
    I will try another reader later....
  • 6. Re: APDU error 6Cxx
    917156 Newbie
    Currently Being Moderated
    It was the reader problem. The same GPShell script on another reader works without error.
    Command --> 80F10000010108
    Wrapped command --> 80F10000010108
    Response <-- 01F8EF282A40019000
    send_APDU() returns 0x80209000 (9000: Success. No error.)
  • 7. Re: APDU error 6Cxx
    Umer Journeyer
    Currently Being Moderated
    Use the code below:
    package test;
    
    import javacard.framework.APDU;
    import javacard.framework.Applet;
    import javacard.framework.ISO7816;
    import javacard.framework.ISOException;
     
    public class Test extends Applet {
     
        final static byte TEST_CLA =(byte)0x80;
        
        final static byte SELECT_INS = (byte)0xA4;
        final static byte GET_ID_INS = (byte)0xF1;
        final static byte STATUS_INS = (byte)0x01;
        
        public static void install(byte[] bArray, short bOffset, byte bLength) {
            new Test();
        }
     
        protected Test() {
            register();
        }
     
        public void process(APDU apdu) {
            byte[] buffer = apdu.getBuffer();
     
            if (selectingApplet())
            {
              return;
            }
            
            if (buffer[ISO7816.OFFSET_CLA] != TEST_CLA)
                ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
            
            switch (buffer[ISO7816.OFFSET_INS]) {
     
                case GET_ID_INS:
                    getID(apdu);
                    break;
                    
                case STATUS_INS:
                     getMyData(apdu);
                    break;
                    
                default:
                    ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
                    break;
            }
        }
        
        private void getID(APDU apdu)
        {   
            byte myID[] = new byte[]{0x00, 0x03, (byte)0x8D, 0x7E, (byte)0xA4, (byte)0xC6, (byte)0x80, 0x01};
            apdu.setOutgoing();
            apdu.setOutgoingLength((short)myID.length);
            apdu.sendBytesLong(myID, (short)0, (short)myID.length);
        }
        
        private void getMyData(APDU apdu)
        {
            byte[] buffer = apdu.getBuffer();
            byte[] reverse = new byte[buffer[ISO7816.OFFSET_LC]];
            for (short i = 0; i < buffer[ISO7816.OFFSET_LC]  ; i++ )
            {
                 reverse[(reverse.length-1)-i] = buffer[(buffer[ISO7816.OFFSET_LC])+i];//buffer;
    }

    apdu.setOutgoing();
    apdu.setOutgoingLength((short)reverse.length);
    apdu.sendBytesLong(reverse, (short)0, (short)reverse.length);
    }
    }


    Now you can send and receive data with a single APDU.

    Trace:
    cm>  /select |test.app
     => 00 A4 04 00 08 74 65 73 74 2E 61 70 70 00          .....test.app.
     (593092 nsec)
     <= 90 00                                              ..
    Status: No Error
    cm>  /send 80010000050102030405
     => 80 01 00 00 05 01 02 03 04 05                      ..........
     (823009 nsec)
     <= 05 04 03 02 01 90 00                               .......
    Status: No Error
    Whatever the data you will send within the command the card will send back that data in reverse order in the same APDU.
    Hope it helps

    Regards
  • 8. Re: APDU error 6Cxx
    917156 Newbie
    Currently Being Moderated
    As I mentioned it was reader related issue. I will investigate it later, but thank you for your help.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points