smartcard: pyscard get remaining bytes from apdu

1.5k views Asked by At

I currently can use pyscard correctly to talk with my smartcard, however when the apdu size is above 255 bytes, i need to receive the remaining bytes for the command.

What method gets me the remaining bytes in pyscard? To my understanding sw2 should be the number of remaining bytes.

def _cmd(self, cl, ins, p1, p2, data=''):
        command = '%02x%02x%02x%02x%02x%s' % (cl, ins, p1, p2, len(data),
                                              data.encode('hex'))

        data, sw1, sw2 = self.reader.transmit(hex2cmd(command))


        return data, sw1 << 8 | sw2

    def _cmd_ok(self, *args, **kwargs):
        data, status = self._cmd(*args, **kwargs)
        if status != 0x9000:
            raise Exception('APDU error: 0x%04x' % status)
        return ''.join(map(chr, data))
3

There are 3 answers

0
Catosh On

I know that this is necroposting. Anyway:

My approach is different: 61 xx means that you need to get additional xx bytes of data. You can then send

response, sw1, sw2 = connection.transmit([0x00,0xC0,0x00,0x00,0xXX])

to get the 0xXX bytes back without polling for the 90 00 ack.

2
NoobTom On

This is how to do it:

You need to send a special APDU to ask for the remaining data and look for status 0x61xx cl, ins, p1, p2, = (0x00, 0xa5, 0x00, 0x00)

def _cmd_ok(self, *args, **kwargs):
        data, status = self._cmd(*args, **kwargs)
        #get high bits
        low = status & 0xFF;
        high = status >> 8;

        if status != 0x9000:
            if high != 0x61:
                raise Exception('APDU error: 0x%04x' % status)
            else:
                while status != 0x9000:
                    part, status = self._cmd(0x00, 0xa5, 0x00, 0x00)
                    data = data + part

        return ''.join(map(chr, data))
1
guidot On

You are probably referring to the 61xx status code, where xx denotes the number of bytes still available. Unfortunately this can only be taken for granted, if your card communicates using T=0. Then a GET RESPONSE will return the next chunk of data. Some advocate, that the same should possibly using other communication protocols too, but the are severe problems as soon as secure messaging especially using sequence counters are involved.

The cleanest way, since applicable to any command, would be to use extend length specification in your APDU, if your card supports it, but this as well as the maximum buffer size has to be found out. If LC is present, an extended length is specified using the bytes zero, high byte, low byte and then LE with high byte, low byte follows. If there is no LC, the extended length indicator (zero byte) has to precede the two byte LE specification. For details (as always) see ISO 7816-4.