def activate(clf, target): log.debug("check if authenticate command is available") try: rsp = clf.exchange(b'\x1A\x00', timeout=0.01) if clf.sense(target) is None: return if rsp.startswith(b"\xAF"): return MifareUltralightC(clf, target) except nfc.clf.TimeoutError: if clf.sense(target) is None: return except nfc.clf.CommunicationError as error: log.debug(repr(error)) return log.debug("check if version command is available") try: rsp = bytes(clf.exchange(b'\x60', timeout=0.01)) if rsp in VERSION_MAP: return VERSION_MAP[rsp](clf, target) if rsp == b"\x00": if clf.sense(target) is None: return None else: return NTAG203(clf, target) log.debug("no match for version %s", hexlify(rsp).upper()) return except nfc.clf.TimeoutError: if clf.sense(target) is None: return except nfc.clf.CommunicationError as error: log.debug(repr(error)) return return MifareUltralight(clf, target)
def activate(clf, target): try: log.debug("check if authenticate command is available") rsp = clf.exchange('\x1A\x00', timeout=0.01) if clf.sense(target) is None: return None if rsp.startswith("\xAF"): return MifareUltralightC(clf, target) if rsp == "\x00": return NTAG203(clf, target) except nfc.clf.TimeoutError: log.debug("nope, authenticate command is not supported") if clf.sense(target) is None: return None except nfc.clf.CommunicationError as error: log.debug(repr(error)) return try: log.debug("check if version command is available") version = clf.exchange('\x60', timeout=0.01) except nfc.clf.TimeoutError: log.debug("nope, version command is not supported") if clf.sense(target) is None: return None version = None except nfc.clf.CommunicationError as error: log.debug(repr(error)) return if version is not None: log.debug("version = " + ' '.join(["%02X" % x for x in version])) if version == "\x00\x04\x03\x01\x01\x00\x0B\x03": return MifareUltralightEV1(clf, target, "MF0UL11", 16) if version == "\x00\x04\x03\x02\x01\x00\x0B\x03": return MifareUltralightEV1(clf, target, "MF0ULH11", 16) if version == "\x00\x04\x03\x01\x01\x00\x0E\x03": return MifareUltralightEV1(clf, target, "MF0UL21", 37) if version == "\x00\x04\x03\x02\x01\x00\x0E\x03": return MifareUltralightEV1(clf, target, "MF0ULH21", 37) if version == "\x00\x04\x04\x01\x01\x00\x0B\x03": return NTAG210(clf, target) if version == "\x00\x04\x04\x01\x01\x00\x0E\x03": return NTAG212(clf, target) if version == "\x00\x04\x04\x02\x01\x00\x0F\x03": return NTAG213(clf, target) if version == "\x00\x04\x04\x02\x01\x00\x11\x03": return NTAG215(clf, target) if version == "\x00\x04\x04\x02\x01\x00\x13\x03": return NTAG216(clf, target) log.debug("no match for this version number") return else: return MifareUltralight(clf, target)
def listen_ttf(timeout, clf, args): try: bitrate = (int(args['--bitrate']) if args['--bitrate'] else 212) except ValueError: assert 0, "the '--bitrate' argument must be an integer" assert bitrate >= 0, "the '--bitrate' argument must be a positive integer" try: idm = bytearray.fromhex(args['--idm'][0:16]) except ValueError: assert 0, "the '--idm' argument must be hexadecimal" idm += os.urandom(8 - len(idm)) try: pmm = bytearray.fromhex(args['--pmm'][0:16]) except ValueError: assert 0, "the '--pmm' argument must be hexadecimal" pmm += (8 - len(pmm)) * b"\xFF" try: _sys = bytearray.fromhex(args['--sys'][0:4]) except ValueError: assert 0, "the '--sys' argument must be hexadecimal" _sys += (2 - len(_sys)) * b"\xFF" target = nfc.clf.LocalTarget(str(bitrate) + 'F') target.sensf_res = b"\x01" + idm + pmm + _sys target = clf.listen(target, timeout) if target and target.tt3_cmd: if target.tt3_cmd[0] == 0x06: response = struct.pack("B", 29) + b"\7" + idm + b"\0\0\1" + \ bytearray(16) clf.exchange(response, timeout=0) elif target.tt3_cmd[0] == 0x0C: response = struct.pack("B", 13) + b"\x0D" + idm + b"\x01" + _sys else: logging.warning("communication not verified") return target try: clf.exchange(response, timeout=1) return target except nfc.clf.CommunicationError: logging.error("communication failure after activation")
def listen_tta(timeout, clf, args): try: bitrate = (int(args['--bitrate']) if args['--bitrate'] else 106) except ValueError: assert 0, "the '--bitrate' argument must be an integer" assert bitrate >= 0, "the '--bitrate' argument must be a positive integer" try: uid = bytearray.fromhex(args['--uid']) except ValueError: assert 0, "the '--uid' argument must be hexadecimal" assert len(uid) in (4, 7, 10), "the '--uid' must be 4, 7, or 10 bytes" target = nfc.clf.LocalTarget(str(bitrate) + 'A') target.sens_res = bytearray(b"\x01\x01") target.sdd_res = uid target.sel_res = bytearray(b"\x00" if args['tt2'] else b"\x20") target = clf.listen(target, timeout) if target and target.tt2_cmd: logging.debug("rcvd TT2_CMD %s", hexlify(target.tt2_cmd).decode()) # Verify that we can send a response. if target.tt2_cmd == b"\x30\x00": data = bytearray.fromhex("046FD536 11127A00 79C80000 E110060F") elif target.tt2_cmd[0] == 0x30: data = bytearray(16) else: logging.warning("communication not verified") return target try: clf.exchange(data, timeout=1) return target except nfc.clf.CommunicationError: logging.error("communication failure after activation") if target and target.tt4_cmd: logging.debug("rcvd TT4_CMD %s", hexlify(target.tt4_cmd).decode()) logging.warning("communication not verified") return target
def listen_dep(timeout, clf, args): try: id3 = bytearray.fromhex(args['--id3'][0:20]) except ValueError: assert 0, "the '--id3' argument must be hexadecimal" id3 += os.urandom(10 - len(id3)) try: gbt = bytearray.fromhex(args['--gbt']) except ValueError: assert 0, "the '--gbt' argument must be hexadecimal" target = nfc.clf.LocalTarget() target.sensf_res = bytearray.fromhex("01") + id3[0:8] + bytearray(10) target.sens_res = bytearray.fromhex("0101") target.sdd_res = bytearray.fromhex("08") + id3[-3:] target.sel_res = bytearray.fromhex("60" if args['--hce'] else "40") target.atr_res = b"\xD5\x01" + id3 + b"\0\0\0\x08" + ( b"\x32" if gbt else b"\0") + gbt target = clf.listen(target, timeout) if target and target.dep_req: logging.debug("rcvd DEP_REQ %s", hexlify(target.dep_req).decode()) # Verify that we can indeed send a response. Note that we do # not handle a DID, but nobody is sending them anyway. Further # note that target.dep_req is without the frame length byte # but exchange() works on frames and so it has to be added. if target.dep_req.startswith(b"\xD4\x06\x80"): # older phones start with attention dep_res = bytearray.fromhex("04 D5 07 80") elif target.dep_req.startswith(b"\xD4\x06\x00"): # newer phones send information packet dep_res = bytearray.fromhex("06 D5 07 00 00 00") else: logging.warning("communication not verified") return target logging.debug("send DEP_RES %s", hexlify(memoryview(dep_res)[1:]).decode()) try: data = clf.exchange(dep_res, timeout=1) assert data and data[0] == len(data) except (nfc.clf.CommunicationError, AssertionError): logging.error("communication failure after activation") return None logging.debug("rcvd DEP_REQ %s", hexlify(memoryview(data)[1:]).decode()) mode = "passive" if target.sens_res or target.sensf_res else "active" logging.debug("activated in %s communication mode", mode) return target
def listen_tta(timeout, clf, args): try: bitrate = (int(args['--bitrate']) if args['--bitrate'] else 106) except ValueError: assert 0, "the '--bitrate' argument must be an integer" assert bitrate >= 0, "the '--bitrate' argument must be a positive integer" try: uid = bytearray.fromhex(args['--uid']) except ValueError: assert 0, "the '--uid' argument must be hexadecimal" assert len(uid) in (4,7,10), "the '--uid' must be 4, 7, or 10 bytes" target = nfc.clf.LocalTarget(str(bitrate) + 'A') target.sens_res = bytearray("\x01\x01") target.sdd_res = uid target.sel_res = bytearray("\x00" if args['tt2'] else "\x20") target = clf.listen(target, timeout) if target and target.tt2_cmd: logging.debug("rcvd TT2_CMD %s", hexlify(target.tt2_cmd)) # Verify that we can send a response. if target.tt2_cmd == "\x30\x00": data = bytearray.fromhex("046FD536 11127A00 79C80000 E110060F") elif target.tt2_cmd[0] == 0x30: data = bytearray(16) else: logging.warning("communication not verified") return target try: clf.exchange(data, timeout=1) return target except nfc.clf.CommunicationError: logging.error("communication failure after activation") if target and target.tt4_cmd: logging.debug("rcvd TT4_CMD %s", hexlify(target.tt4_cmd)) logging.warning("communication not verified") return target
def listen_ttf(timeout, clf, args): try: bitrate = (int(args['--bitrate']) if args['--bitrate'] else 212) except ValueError: assert 0, "the '--bitrate' argument must be an integer" assert bitrate >= 0, "the '--bitrate' argument must be a positive integer" try: idm = bytearray.fromhex(args['--idm'][0:16]) except ValueError: assert 0, "the '--idm' argument must be hexadecimal" idm += os.urandom(8-len(idm)) try: pmm = bytearray.fromhex(args['--pmm'][0:16]) except ValueError: assert 0, "the '--pmm' argument must be hexadecimal" pmm += (8-len(pmm)) * "\xFF" try: sys = bytearray.fromhex(args['--sys'][0:4]) except ValueError: assert 0, "the '--sys' argument must be hexadecimal" sys += (2-len(sys)) * "\xFF" target = nfc.clf.LocalTarget(str(bitrate) + 'F') target.sensf_res = "\x01" + idm + pmm + sys target = clf.listen(target, timeout) if target and target.tt3_cmd: if target.tt3_cmd[0] == 0x06: response = chr(29) + "\7" + idm + "\0\0\1" + bytearray(16) clf.exchange(response, timeout=0) elif target.tt3_cmd[0] == 0x0C: response = chr(13) + "\x0D" + idm + "\x01" + sys else: logging.warning("communication not verified") return target try: clf.exchange(response, timeout=1) return target except nfc.clf.CommunicationError: logging.error("communication failure after activation")
def listen_dep(timeout, clf, args): try: id3 = bytearray.fromhex(args['--id3'][0:20]) except ValueError: assert 0, "the '--id3' argument must be hexadecimal" id3 += os.urandom(10-len(id3)) try: gbt = bytearray.fromhex(args['--gbt']) except ValueError: assert 0, "the '--gbt' argument must be hexadecimal" target = nfc.clf.LocalTarget() target.sensf_res = bytearray.fromhex("01") + id3[0:8] + bytearray(10) target.sens_res = bytearray.fromhex("0101") target.sdd_res = bytearray.fromhex("08") + id3[-3:] target.sel_res = bytearray.fromhex("60" if args['--hce'] else "40") target.atr_res = "\xD5\x01"+id3+"\0\0\0\x08"+("\x32" if gbt else "\0")+gbt target = clf.listen(target, timeout) if target and target.dep_req: logging.debug("rcvd DEP_REQ %s", hexlify(target.dep_req)) # Verify that we can indeed send a response. Note that we do # not handle a DID, but nobody is sending them anyway. Further # note that target.dep_req is without the frame length byte # but exchange() works on frames and so it has to be added. if target.dep_req.startswith("\xD4\x06\x80"): # older phones start with attention dep_res = bytearray.fromhex("04 D5 07 80") elif target.dep_req.startswith("\xD4\x06\x00"): # newer phones send information packet dep_res = bytearray.fromhex("06 D5 07 00 00 00") else: logging.warning("communication not verified") return target logging.debug("send DEP_RES %s", hexlify(buffer(dep_res, 1))) try: data = clf.exchange(dep_res, timeout=1) assert data and data[0]==len(data) except (nfc.clf.CommunicationError, AssertionError): logging.error("communication failure after activation") return None logging.debug("rcvd DEP_REQ %s", hexlify(buffer(data, 1))) mode = "passive" if target.sens_res or target.sensf_res else "active" logging.debug("activated in %s communication mode", mode) return target
def main(args): if args.debug: loglevel = logging.DEBUG - (1 if args.verbose else 0) logging.getLogger("nfc.clf").setLevel(loglevel) logging.getLogger().setLevel(loglevel) if args.atr and len(args.atr) < 16: print("--atr must supply at least 16 byte") clf = nfc.ContactlessFrontend() if clf.open(args.device): targets = list() for target in args.targets: target_pattern_match = target_pattern.match(target) if not target_pattern_match: logging.error("invalid target pattern {!r}".format(target)) else: brty, attributes = target_pattern_match.groups() target = nfc.clf.RemoteTarget(brty) if attributes: for attr in map(str.strip, attributes.split(' ')): name, value = map(str.strip, attr.split('=')) value = bytearray.fromhex(value) setattr(target, name, value) logging.debug("add to target list: %s", target) targets.append(target) try: while True: target = clf.sense(*targets, iterations=args.iterations, interval=args.interval) print("{0} {1}".format(time.strftime("%X"), target)) if (target and args.atr and target.brty in brty_for_dep and ( (target.sel_res and target.sel_res[0] & 0x40) or (target.sensf_res and target.sensf_res[1:3] == '\1\xFE'))): atr_req = args.atr[:] if atr_req[0] == 0xFF: atr_req[0] = 0xD4 for i in (1, 12, 13, 14): if atr_req[i] == 0xFF: atr_req[i] = 0x00 if target.sensf_res: for i in range(2, 10): if atr_req[i] == 0xFF: atr_req[i] = target.sensf_res[i - 1] if atr_req[15] == 0xFF: atr_req[15] = 0x30 | (len(atr_req) > 16) << 1 try: data = chr(len(atr_req) + 1) + atr_req if target.brty == "106A": data.insert(0, 0xF0) data = clf.exchange(data, 1.0) if target.brty == "106A": assert data.pop(0) == 0xF0 assert len(data) == data.pop(0) target.atr_res = data target.atr_req = atr_req except nfc.clf.CommunicationError as error: print(repr(error) + " for NFC-DEP ATR_REQ") except AssertionError: print("invalid ATR_RES: %r" % str(data.encode("hex"))) if target and target.atr_res: did = target.atr_req[12] psl = "06D404%02x1203" % did # PSL_REQ rls = ("04D40A%02x" % did) if did else "03D40A" if target.brty == "106A": psl = "F0" + psl psl, rls = map(bytearray.fromhex, (psl, rls)) try: clf.exchange(psl, 1.0) except nfc.clf.CommunicationError as error: print(repr(error) + " for NFC-DEP PSL_REQ") else: target.brty = "424F" try: clf.exchange(rls, 1.0) except nfc.clf.CommunicationError as error: print(repr(error) + " for NFC-DEP RLS_REQ") if (target and target.sensf_res and target.sensf_res[1:3] != '\x01\xFE'): request_system_code = "\x0A\x0C" + target.sensf_res[1:9] try: clf.exchange(request_system_code, timeout=1.0) except nfc.clf.CommunicationError as error: print(repr(error) + " for Request System Code Command") if not args.repeat: break time.sleep(args.waittime) except IOError as error: if error.errno == errno.EIO: print("lost connection to local device") else: print(error) except nfc.clf.UnsupportedTargetError as error: print error except KeyboardInterrupt: pass finally: clf.close()
def test_exchange_without_target(self, clf): assert clf.exchange(HEX(''), 1.0) is None
def test_exchange_without_device(self, clf): clf.device = None with pytest.raises(IOError) as excinfo: clf.exchange(HEX(''), 1.0) assert excinfo.value.errno == errno.ENODEV
def main(args): if args.debug: loglevel = logging.DEBUG - (1 if args.verbose else 0) logging.getLogger("nfc.clf").setLevel(loglevel) if args.atr and len(args.atr) < 16: print("--atr must supply at least 16 byte") clf = nfc.ContactlessFrontend() if clf.open(args.device): targets = list() for target in args.targets: target_pattern_match = target_pattern.match(target) if not target_pattern_match: logging.error("invalid target pattern {!r}".format(target)) else: brty, attributes = target_pattern_match.groups() target = nfc.clf.RemoteTarget(brty) if attributes: for attr in map(str.strip, attributes.split(' ')): name, value = map(str.strip, attr.split('=')) value = bytearray.fromhex(value) setattr(target, name, value) targets.append(target) try: while True: target = clf.sense(*targets, iterations=args.iterations, interval=args.interval) print("{0} {1}".format(time.strftime("%X"), target)) if (target and args.atr and target.brty in brty_for_dep and ((target.sel_res and target.sel_res[0] & 0x40) or (target.sensf_res and target.sensf_res[1:3]=='\1\xFE'))): atr_req = args.atr[:] if atr_req[0] == 0xFF: atr_req[0] = 0xD4 for i in (1, 12, 13, 14): if atr_req[i] == 0xFF: atr_req[i] = 0x00 if target.sensf_res: for i in range(2, 10): if atr_req[i] == 0xFF: atr_req[i] = target.sensf_res[i-1] if atr_req[15] == 0xFF: atr_req[15] = 0x30 | (len(atr_req)>16)<<1 try: data = chr(len(atr_req)+1) + atr_req if target.brty == "106A": data.insert(0, 0xF0) data = clf.exchange(data, 1.0) if target.brty == "106A": assert data.pop(0) == 0xF0 assert len(data) == data.pop(0) target.atr_res = data target.atr_req = atr_req except nfc.clf.CommunicationError as error: print(repr(error) + " for NFC-DEP ATR_REQ") except AssertionError: print("invalid ATR_RES: %r" % str(data.encode("hex"))) if target and target.atr_res: did = target.atr_req[12] psl = "06D404%02x1203" % did # PSL_REQ rls = ("04D40A%02x"%did) if did else "03D40A" if target.brty == "106A": psl = "F0" + psl psl, rls = map(bytearray.fromhex, (psl, rls)) try: clf.exchange(psl, 1.0) except nfc.clf.CommunicationError as error: print(repr(error) + " for NFC-DEP PSL_REQ") else: target.brty = "424F" try: clf.exchange(rls, 1.0) except nfc.clf.CommunicationError as error: print(repr(error) + " for NFC-DEP RLS_REQ") if (target and target.sensf_res and target.sensf_res[1:3] != '\x01\xFE'): request_system_code = "\x0A\x0C"+target.sensf_res[1:9] try: clf.exchange(request_system_code, timeout=1.0) except nfc.clf.CommunicationError as error: print(repr(error) + " for Request System Code Command") if not args.repeat: break time.sleep(args.waittime) except IOError as error: if error.errno == errno.EIO: print("lost connection to local device") else: print(error) except nfc.clf.UnsupportedTargetError as error: print error except KeyboardInterrupt: pass finally: clf.close()