Search code examples
smartcardjavacardsmartcard-readerpcsc

How to change 2-step card response into 1-step?


I'm developing a program in Java Card. sometimes when I send a command to card, it responses as "0X61 0Xxx" which means there exist a response with 0Xxx length and I should answer to get it.

My question is, how can I avoid this kind of responses and get the answer at once?

Thanks in advance


Solution

  • It depends!

    Sometimes you receive 61XX because you are communicating with an applet that is written as such! I mean the applet is written in a way that returns its data with GET RESPONSE APDU command. So in this case you can't do anything other than requesting applet developer to modify the applet as you want.

    But sometimes it's not the applet that returns the data as described above, but it is the smart card. Actually the T=0 smart cards returns data as such. So you only need to change your smart card to a newer card that supports T=1 communication protocol. In this case, you have a single applet CAP file and when you install on a T=0 card it returns data in 2 steps, and when you install it on a T=1 smart card it returns data in 1 step.


    Let assume that you wrote your program as below. It has four different APDU commands (INS = 00, 01, 02, 03) to return the temp byte array contents to user:

    package soq;
    
    import javacard.framework.*;
    
    public class SOQ extends Applet
    {
        byte[] temp = {(byte)'T',(byte)'h',(byte)'i',(byte)'s',
                       (byte)'-',(byte)'I',(byte)'s',(byte)'-',
                       (byte)'A',(byte)'-',(byte)'T',(byte)'e',(byte)'s',(byte)'t'};
    
        public static void install(byte[] bArray, short bOffset, byte bLength) 
        {
            new SOQ().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
        }
    
        public void process(APDU apdu)
        {
            if (selectingApplet())
            {
                return;
            }
    
            byte[] buf = apdu.getBuffer();
            short le;
    
            switch (buf[ISO7816.OFFSET_INS])
            {
            case (byte)0x00:
                apdu.setOutgoing();
                apdu.setOutgoingLength((short)14);
                apdu.sendBytesLong(temp, (short)0, (short)14);
                break;
    
            case (byte) 0x01:
                Util.arrayCopyNonAtomic(temp, (short)0, buf, (short)0, (short)14);
                apdu.setOutgoingAndSend((short)0, (short)14);
                break;
    
            case (byte) 0x02:
                le = apdu.setOutgoing();
                if (le != (short)0x000E){
                    ISOException.throwIt((short)0x6C0E);
                }else{
                    Util.arrayCopyNonAtomic(temp, (short)0, buf, (short)0, (short)14);
                    apdu.setOutgoingLength((short)le);
                    apdu.sendBytes((short)0, le);
                }
                break;
    
            case (byte) 0x03:
                le = apdu.setOutgoing();
                if (le != (short)0x000E){
                    ISOException.throwIt((short)0x6C0E);
                }else{
                    apdu.setOutgoingLength((short)14);
                    apdu.sendBytesLong(temp, (short)0, le);
                }
                break;
            default:
                ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
            }
        }
    
    }
    

    When it is installed on a card that is communicating with user on T=1 protocol, then you have:

    Select Applet begin...
    Select Applet successful.
    
    Send: 00 00 00 00 00
    Recv: 54 68 69 73 2D 49 73 2D 41 2D 54 65 73 74 90 00
    
    Send: 00 01 00 00 00
    Recv: 54 68 69 73 2D 49 73 2D 41 2D 54 65 73 74 90 00
    
    Send: 00 02 00 00 00
    Recv: 6C 0E
    Send: 00 02 00 00 0E
    Recv: 54 68 69 73 2D 49 73 2D 41 2D 54 65 73 74 90 00
    
    Send: 00 03 00 00 00
    Recv: 6C 0E
    Send: 00 03 00 00 0E
    Recv: 54 68 69 73 2D 49 73 2D 41 2D 54 65 73 74 90 00
    

    And when it is installed on a card that is communicating with user on T=0 protocol, then you have:

    Select Applet begin...
    Select Applet successful.
    
    Send: 00 00 00 00 00
    Recv: 6C 0E
    Send: 00 00 00 00 0E
    Recv: 54 68 69 73 2D 49 73 2D 41 2D 54 65 73 74 90 00
    
    Send: 00 01 00 00 00
    Recv: 6C 0E
    Send: 00 01 00 00 0E
    Recv: 54 68 69 73 2D 49 73 2D 41 2D 54 65 73 74 90 00
    
    Send: 00 02 00 00 00
    Recv: 6C 0E
    Send: 00 02 00 00 0E
    Recv: 54 68 69 73 2D 49 73 2D 41 2D 54 65 73 74 90 00
    
    Send: 00 03 00 00 00
    Recv: 6C 0E
    Send: 00 03 00 00 0E
    Recv: 54 68 69 73 2D 49 73 2D 41 2D 54 65 73 74 90 00
    

    As you see above, APDU commands with INS=0x2 or 0x03 and Le=0x00 return 0x6C0E in both cases. It is because that the applet is written as such. But for INS=0x00 or 0x01 the return value is depends on the communication protocol. For T=1 they return 0x6C0E and for T=1 they return the data.