appletjavacardapdugpshell

Java Card applet returns 6700, I can't figure out why


I can't figure out why my applet returns 6700 in response to the command 00 40 00 00 0A 0102030405060708090A.

00 - CLA, 40 - INS, 00 00 - P1 and P2, 0A - Lc, 0102030405060708090A - Data

If I understand correctly, 6700 means that I am forming the APDU command incorrectly (6700 - wrong length). In my opinion, the command corresponds to case 2 (for example https://stackoverflow.com/a/40673167/4449456). Where am I wrong?

APDU processing:

    public void process(APDU apdu) {
        if (selectingApplet()) {
            return; // return 9000 on SELECT
        }

        byte[] buf = apdu.getBuffer();
        switch (buf[ISO7816.OFFSET_INS]) {
            case (byte) 0x40:
                byte numBytes = (byte)(buf[ISO7816.OFFSET_LC]);
                byte byteRead = (byte)(apdu.setIncomingAndReceive());
                if ( ( numBytes != PayloadSize ) || (byteRead != 1) )
                    ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);

                Util.arrayCopy(buf, buf[ISO7816.OFFSET_CDATA], data, (short) 0, PayloadSize);
                break;
            case (byte) 0x41:
                Util.arrayCopy(data, (short) 0, buf, ISO7816.OFFSET_CDATA, PayloadSize);
                apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, PayloadSize);
                break;
            default:
                ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        }

    }

gpshell output


Solution

  • Found my mistake. setIncomingAndReceive() returns the size of the transferred array (10 bytes in my case), i.e. instead of if ( ( numBytes != PayloadSize ) || (byteRead != 1) ) there should be if ( ( numBytes != PayloadSize ) || (byteRead != PayloadSize) ).

    And in addition, I also specified the offset inside the buffer incorrectly (should be Util.arrayCopy(buf, ISO7816.OFFSET_CDATA, data, (short) 0, PayloadSize)).