Sai Kiran
Sai Kiran

Reputation: 11

APDU Command Error - response 6C6B

I am trying to read smart card using PCSC commands in Objective-C.

  int count = 17;
unsigned char *get_cplc_command = (unsigned char *)calloc(count, sizeof(unsigned char));
get_cplc_command[1]=-92;
get_cplc_command[2]=4;
get_cplc_command[4]=12;
get_cplc_command[5]=-96;
get_cplc_command[8]=2;
get_cplc_command[9]=67;
get_cplc_command[11]=19;
get_cplc_command[15]=1;
get_cplc_command[16]=1;

receive_length = sizeof(receive_buffer);

ret = SCardTransmit(card, 
                    &sendPCI,
                    get_cplc_command, 
                    sizeof(get_cplc_command),
                    NULL,
                    receive_buffer,
                    &receive_length);

LOG(@"SCardTransmit 0x%08x", ret);

When I execute above command I am getting 6C6B response. Can you please help me to resolve the issue.

Upvotes: 1

Views: 1877

Answers (1)

vlp
vlp

Reputation: 8116

The status word 6CXX means, that the Le field of the command APDU was wrong.

Citing ISO 7816-3, Table 14:

Process aborted due to a wrong Le field (SW2 encodes Na, i.e., the exact number of available data bytes). In cases 1 and 3, the card should not use such a value. In cases 2 and 4, the card shall be ready to receive the same command with P3 = SW2.

And ISO 7816-4, Section 5.1.3:

If SW1 is set to '6C', then the process is aborted and before issuing any other command, the same command may be re-issued using SW2 (exact number of available data bytes) as short Le field.


(Although not familiar with Objective-C) My bet is that the 4th argument of SCardTransmit (i.e. sizeof(get_cplc_command)) should be count instead -- as the sizeof operator does not give you the size of allocated array, but the size of the pointer to it.

[Presuming 32-bit architecture and sizeof(unsigned char*) equal to 4]: Command sent was not 00A404000CA00000024300130000000101 as intended, but 00A40400 which was interpreted as case 1 command (see ISO 7816-3, Section 12.1.2 for command APDU cases description).

Good luck!


PS: Please consider checking your receive_length variable for the same problem.


EDIT> Regarding the 61XX status:

As @guidot wrote, you need to issue a GET RESPONSE (another command) to get the response data immediately after receiving this status word.

Citing ISO 7816-4:

If SW1 is set to '61', then the process is completed and before issuing any other command, a GET RESPONSE command may be issued with the same CLA and using SW2 (number of data bytes still available) as short Le field.

The above-mentioned GET RESPONSE command is documented in ISO 7816-4 as well (see e.g. here).

In your case the APDU exchange should probably look like this:

> 00A404000CA00000024300130000000101 // SELECT command
< 6121 // SELECT response -- 33 bytes still available
> 00C0000021 // GET RESPONSE command
< XXXX...XX9000 // GET RESPONSE response (33 bytes and a status word)

(You will have to call the SCardTransmit twice, once for 00A404000C... and then for 00C0000021.... Remember to reset the receive_length variable if re-used).


Note: You might want to try sending a 00A404000CA0000002430013000000010100 command APDU (the same command with a Le field present and set to 0x00 -- meaning you are expecting up to 256 bytes in the response data).

Upvotes: 2

Related Questions