Beispiel #1
0
    def wrap_native(self, native_command):
        print repr(native_command)
        if len(native_command) > 1:
            apdu = utils.C_APDU(cla=self.DEFAULT_CLA,
                                ins=native_command[0],
                                data=native_command[1:],
                                le=0)
        elif len(native_command) == 1:
            apdu = utils.C_APDU(cla=self.DEFAULT_CLA,
                                ins=native_command[0],
                                le=0)
        else:
            raise ValueError, "len(native_command) must be >= 1"

        result = self.send_apdu(apdu)

        return result.data, result.sw2
Beispiel #2
0
    def transceive(self, data):
        try:
            command = utils.C_APDU(data)
            result = []
            error = None
            response = None

            if command.cla == 0xff and command.ins == 0xca:
                if command.p1 == 0x00:
                    # Get UID/PUPI
                    if self._current_target is None:
                        error = "\x6a\x81"
                    elif self._current_target.type == utils.PN532_Target.TYPE_ISO14443A:
                        result = self._current_target.nfcid
                    elif self._current_target.type == utils.PN532_Target.TYPE_ISO14443B:
                        result = self._current_target.atqb[1:5]
                    else:
                        error = "\x6a\x81"

                elif command.p1 == 0x01:
                    # Get ATS historical bytes
                    if self._current_target is None:
                        error = "\x6a\x81"
                    elif self._current_target.type == utils.PN532_Target.TYPE_ISO14443A:
                        ats = self._current_target.ats
                        result = self._extract_historical_bytes_from_ats(ats)
                    else:
                        error = "\x6a\x81"

                else:
                    error = "\x6a\x81"

                if error is not None:
                    response = utils.R_APDU(error)
                else:
                    if command.le is 0 or command.le == len(result):
                        response = utils.R_APDU(data=result, sw1=0x90, sw2=0)
                    elif command.le < len(result):
                        response = utils.R_APDU(sw1=0x6c, sw2=len(result))
                    elif command.le > len(result):
                        response = utils.R_APDU(data=result + [0] *
                                                (command.le - len(result)),
                                                sw1=0x62,
                                                sw2=0x82)

                if response is not None:
                    return response.render()
        except:
            # Just go on and try to process the data normally
            pass

        response = self.pn532_transceive("\xd4\x40" +
                                         chr(self._current_target_number) +
                                         data)
        if response[2] != "\x00":
            # FIXME Proper error processing
            raise IOError, "Error while transceiving"
        return response[3:]
Beispiel #3
0
 def do_normal_apdu(self, *args):
     "Transmit an APDU"
     apdu_string = "".join(args)
     if not utils.C_APDU._apduregex.match(apdu_string):
         raise NotImplementedError
     
     apdu_binary = binascii.a2b_hex("".join(apdu_string.split()))
     apdu = utils.C_APDU(apdu_binary)
     
     return self.do_apdu(apdu)
Beispiel #4
0
class RFID_Storage_Card(building_blocks.Card_with_read_binary, RFID_Card):
    STOP_ATRS = []
    ATRS = []
    STATUS_MAP = dict(RFID_Card.STATUS_MAP)
    STATUS_MAP.update({
        Card.PURPOSE_RETRY: ("6C??", ),
    })

    APDU_READ_BINARY = utils.C_APDU(CLA=0xff, INS=0xb0, Le=0)
    COMMANDS = dict(building_blocks.Card_with_read_binary.COMMANDS)
    COMMANDS.update(RFID_Card.COMMANDS)
Beispiel #5
0
    def detect_bac(card):
        "Check whether BAC is active and if yes what type of card-os (select not allowed, select allowed but read not allowed)"
        result = card.open_file("\x01\x01", 0x0c)  # EF.DG1

        if result.sw == "\x90\x00":
            prefix = str(SHORT_SW_MAP[result.sw])
            result = card.send_apdu(
                utils.C_APDU(card.APDU_READ_BINARY, p1=0, p2=0, le=1))
        else:
            prefix = ""

        if SHORT_SW_MAP.has_key(result.sw):
            return prefix + str(SHORT_SW_MAP[result.sw])
        else:
            return prefix + "%s:%s" % (SHORT_SW_MAP[None],
                                       binascii.b2a_hex(result.sw))
Beispiel #6
0
    def map_dg(card):
        "Get a map of which DGs exist and are readable/unreadable and with which SW they are unreadable"
        # Try to read 1 byte from each DG through READ BINARY with short file identifier
        responses = [
            card.send_apdu(
                utils.C_APDU(card.APDU_READ_BINARY, p1=i | 0x80, p2=0, le=1))
            for i in range(1, 17)
        ]

        result = []
        exceptional = []
        for response in responses:
            if SHORT_SW_MAP.has_key(response.sw):
                result.append(SHORT_SW_MAP[response.sw])
            else:
                result.append(SHORT_SW_MAP[None])
                exceptional.append(response.sw)

        UNIT_FORMAT = "%X"
        UNIT_LEN = 4  # For hex in "%X" format. Would be 8 for hex in "%02X" format.
        compressed = []
        current = 0
        count = 0
        for r in result:
            if count >= UNIT_LEN:
                compressed.append(current)
                current = count = 0
            current = (current << SHORT_SW_WIDTH) | r
            count = count + SHORT_SW_WIDTH

        if count > 0:
            if not count >= UNIT_LEN:
                while count < UNIT_LEN:
                    current = current << SHORT_SW_WIDTH
                    count += SHORT_SW_WIDTH
            compressed.append(current)
            current = count = 0

        return "".join([UNIT_FORMAT % r for r in compressed]) + ":".join(
            (len(exceptional) > 0 and [""] or []) +
            [binascii.b2a_hex(e) for e in exceptional])
Beispiel #7
0
class RFID_Card(ISO_Card):
    DRIVER_NAME = ["RFID"]
    APDU_GET_UID = utils.C_APDU(CLA=0xff, INS=0xCA, p1=0, p2=0, Le=0)

    ATRS = [
        # Contactless storage cards
        ("3b8f8001804f0ca000000306......00000000..", None),
        # All other cards that follow the general ATR format
        ("3b8.8001.*", None),
    ]

    STOP_ATRS = [
        # Mifare, handled below
        ("3b8f8001804f0ca000000306..000[1-3]00000000..", None),
        ("3B8180018080", None),
    ]

    def get_uid(self):
        result = self.send_apdu(utils.C_APDU(self.APDU_GET_UID))
        return result.data

    def cmd_get_uid(self):
        "Get the UID or SNR or PUPI of the currently connected card."
        uid = self.get_uid()
        print utils.hexdump(uid, short=True)

    COMMANDS = {
        "get_uid": cmd_get_uid,
    }

    STATUS_WORDS = dict(ISO_Card.STATUS_WORDS)
    STATUS_WORDS.update({
        "\x62\x82": "End of file (or UID) reached before Le bytes",
        "\x67\x00": "Wrong Length",
        "\x68\x00": "Class byte is not correct",
        "\x6a\x81": "Function not supported",
        "\x6b\x00": "Wrong parameters P1-P2",
    })
Beispiel #8
0
 def setUp(self):
     self.a4 = utils.C_APDU("\x00\xa4\x00\x00")
Beispiel #9
0
 def testCreateSequence(self):
     a4_2 = utils.C_APDU(0, 0xa4, 0, 0)
     
     self.assertEqual(self.a4.render(), a4_2.render())
Beispiel #10
0
    def testCopy(self):
        b0 = utils.C_APDU(self.a4, INS=0xb0)

        self.assertEqual("\x00\xb0\x00\x00", b0.render())
Beispiel #11
0
 def get_uid(self):
     result = self.send_apdu(utils.C_APDU(self.APDU_GET_UID))
     return result.data