thotheolh
thotheolh

Reputation: 7440

APDU throwing 6F00 on a method

I am trying to read data from an incoming smart card APDU and return the same incoming message while also appending the ASCII words "respond " to the front of the message. I am getting a 6F00 status. How should I fix the codes?

My codes:

private void repeat(APDU apdu) {
    byte[] buffer = apdu.getBuffer();
    apdu.setIncomingAndReceive();
    byte[] incomingMsg = getData(buffer);
    if ((short) incomingMsg.length != (short) 0) {
        apdu.setOutgoing();

        // Send back the "respond " + "<incoming message" back
        byte[] respMsg = {0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x20};
        byte[] outgoingMsg = new byte[(short) (incomingMsg.length + respMsg.length)];
        ArrayLogic.arrayCopyRepack(respMsg, (short) 0, (short) respMsg.length, outgoingMsg, (short) 0);
        ArrayLogic.arrayCopyRepack(incomingMsg, (short) 0, (short) incomingMsg.length, outgoingMsg, (short) respMsg.length);
        buffer = outgoingMsg;
        apdu.setOutgoingAndSend((short) 0, (short) outgoingMsg.length);
    }
}

private byte[] getData(byte[] buffer) {
    short msgLen = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF);
    short readPos = 5;
    short msgPos = 0;
    byte[] msg = new byte[msgLen];
    while (msgPos < msgLen) {
        msg[msgPos] = buffer[readPos];
        readPos++;
        msgPos++;
    }
    return msg;
}

Upvotes: 2

Views: 7890

Answers (1)

Michael Roland
Michael Roland

Reputation: 40821

Typically, the status word 6F00 means that your code throws an unhandled exception. In your case, this could be caused by the use of both apdu.setOutgoing() and apdu.setOutgoingAndSend(). You may switch to outbound data direction only once. Hence, the use of apdu.setOutgoing() and apdu.setOutgoingAndSend() is mutually exclusive. In fact, you may use only one of the apdu.setOutgoing*() methods.

If you want to use apdu.setOutgoing(), you would later send data using apdu.sendBytes() or apdu.sendBytesLong().

Other problems in your code

There is a couple of other severe coding issues in your program.

  1. Note that Java Card smartcards won't perform automatic garbage collection. Hence, allocating new byte arrays (and dropping the references to them) upon every invocation of your processing code will typically result into a memory leak (i.e. you use up all the memory of your card as the byte arrays remain allocated even if you no longer reference them).

  2. The code

    buffer = outgoingMsg;
    apdu.setOutgoingAndSend((short) 0, (short) outgoingMsg.length);
    

    will not do what you might expect. setOutgoingAndSend() (just as (sendBytes()) will send bytes from the global APDU buffer (i.e. from byte array referenced through apdu.getBuffer(). Simply setting your local buffer variable to reference to another byte array (outgoingMsg) will not change the global APDU buffer. Instead you would need to copy your outgoing data into the APDU buffer (see Util.arrayCopy*()). Alternatively, you could use apdu.sendBytesLong() to specify a byte array containing the data to send.

Upvotes: 8

Related Questions