Ejemplo n.º 1
0
	def _tx_string(self, s):
		"""This is only safe if it's guaranteed the card won't send any data
		during the time of tx of the string !!!"""
		self._sl.write(s)
		r = self._sl.read(len(s))
		if r != s:	# TX and RX are tied, so we must clear the echo
			raise ProtocolError("Bad echo value (Expected: %s, got %s)" % (b2h(s), b2h(r)))
Ejemplo n.º 2
0
	def send_apdu_raw(self, pdu):
		"""see LinkBase.send_apdu_raw"""

		pdu = h2b(pdu)
		data_len = ord(pdu[4])	# P3

		# Send first CLASS,INS,P1,P2,P3
		self._tx_string(pdu[0:5])

		# Wait ack which can be
		#  - INS: Command acked -> go ahead
		#  - 0x60: NULL, just wait some more
		#  - SW1: The card can apparently proceed ...
		while True:
			b = self._rx_byte()
			if b == pdu[1]:
				break
			elif b != '\x60':
				# Ok, it 'could' be SW1
				sw1 = b
				sw2 = self._rx_byte()
				nil = self._rx_byte()
				if (sw2 and not nil):
					return '', b2h(sw1+sw2)

				raise ProtocolError()

		# Send data (if any)
		if len(pdu) > 5:
			self._tx_string(pdu[5:])

		# Receive data (including SW !)
		#  length = [P3 - tx_data (=len(pdu)-len(hdr)) + 2 (SW1/2) ]
		to_recv = data_len - len(pdu) + 5 + 2

		data = ''
		while (len(data) < to_recv):
			b = self._rx_byte()
			if (to_recv == 2) and (b == '\x60'): # Ignore NIL if we have no RX data (hack ?)
				continue
			if not b:
				break;
			data += b

		# Split datafield from SW
		if len(data) < 2:
			return None, None
		sw = data[-2:]
		data = data[0:-2]

		# Return value
		return b2h(data), b2h(sw)
Ejemplo n.º 3
0
 def encode_record_hex(self, abstract_data):
     """Encode abstract representation into raw (hex string) data. Overloaded by specific classes."""
     method = getattr(self, '_encode_record_hex', None)
     if callable(method):
         return method(abstract_data)
     method = getattr(self, '_encode_record_bin', None)
     if callable(method):
         raw_bin_data = method(abstract_data)
         return b2h(raww_bin_data)
     raise NotImplementedError
Ejemplo n.º 4
0
 def decode_record_bin(self, raw_bin_data):
     """Decode raw (hex string) data into abstract representation. Overloaded by specific classes."""
     method = getattr(self, '_decode_record_bin', None)
     if callable(method):
         return method(raw_bin_data)
     raw_hex_data = b2h(raw_bin_data)
     method = getattr(self, '_decode_record_hex', None)
     if callable(method):
         return method(raw_hex_data)
     return {'raw': raw_hex_data}
Ejemplo n.º 5
0
	def program(self, p):

		# select MF 
		r = self._scc.select_file(['3f00'])
		
		# authenticate as SUPER ADM using default key
		self._scc.verify_chv(0x0b, h2b("3838383838383838"))

		# set ADM pin using proprietary command
		# INS: D4
		# P1: 3A for PIN, 3B for PUK
		# P2: CHV number, as in VERIFY CHV for PIN, and as in UNBLOCK CHV for PUK
		# P3: 08, CHV length (curiously the PUK is also 08 length, instead of 10)
		if p['pin_adm']:
			pin = p['pin_adm']
		else:
			pin = h2b("4444444444444444")

		pdu = 'A0D43A0508' + b2h(pin)
		data, sw = self._scc._tp.send_apdu(pdu)
		
		# authenticate as ADM (enough to write file, and can set PINs)

		self._scc.verify_chv(0x05, pin)

		# write EF.ICCID
		data, sw = self._scc.update_binary('2fe2', enc_iccid(p['iccid']))

		# select DF_GSM
		r = self._scc.select_file(['7f20'])
		
		# write EF.IMSI
		data, sw = self._scc.update_binary('6f07', enc_imsi(p['imsi']))

		# write EF.ACC
		if p.get('acc') is not None:
			data, sw = self._scc.update_binary('6f78', lpad(p['acc'], 4))

		# get size and write EF.HPLMN
		r = self._scc.select_file(['6f30'])
		size = int(r[-1][4:8], 16)
		hplmn = enc_plmn(p['mcc'], p['mnc'])
		self._scc.update_binary('6f30', hplmn + 'ff' * (size-3))

		# set COMP128 version 0 in proprietary file
		data, sw = self._scc.update_binary('0001', '001000')

		# set Ki in proprietary file
		data, sw = self._scc.update_binary('0001', p['ki'], 3)

		# select DF_TELECOM
		r = self._scc.select_file(['3f00', '7f10'])
		
		# write EF.SMSP
		data, sw = self._scc.update_record('6f42', 1, lpad(p['smsp'], 80))
Ejemplo n.º 6
0
    def program(self, p):

        # select MF
        r = self._scc.select_file(['3f00'])

        # authenticate as SUPER ADM using default key
        self._scc.verify_chv(0x0b, h2b("3838383838383838"))

        # set ADM pin using proprietary command
        # INS: D4
        # P1: 3A for PIN, 3B for PUK
        # P2: CHV number, as in VERIFY CHV for PIN, and as in UNBLOCK CHV for PUK
        # P3: 08, CHV length (curiously the PUK is also 08 length, instead of 10)
        if p['pin_adm']:
            pin = p['pin_adm']
        else:
            pin = h2b("4444444444444444")

        pdu = 'A0D43A0508' + b2h(pin)
        data, sw = self._scc._tp.send_apdu(pdu)

        # authenticate as ADM (enough to write file, and can set PINs)

        self._scc.verify_chv(0x05, pin)

        # write EF.ICCID
        data, sw = self._scc.update_binary('2fe2', enc_iccid(p['iccid']))

        # select DF_GSM
        r = self._scc.select_file(['7f20'])

        # write EF.IMSI
        data, sw = self._scc.update_binary('6f07', enc_imsi(p['imsi']))

        # write EF.ACC
        if p.get('acc') is not None:
            data, sw = self._scc.update_binary('6f78', lpad(p['acc'], 4))

        # get size and write EF.HPLMN
        r = self._scc.select_file(['6f30'])
        size = int(r[-1][4:8], 16)
        hplmn = enc_plmn(p['mcc'], p['mnc'])
        self._scc.update_binary('6f30', hplmn + 'ff' * (size - 3))

        # set COMP128 version 0 in proprietary file
        data, sw = self._scc.update_binary('0001', '001000')

        # set Ki in proprietary file
        data, sw = self._scc.update_binary('0001', p['ki'], 3)

        # select DF_TELECOM
        r = self._scc.select_file(['3f00', '7f10'])

        # write EF.SMSP
        data, sw = self._scc.update_record('6f42', 1, lpad(p['smsp'], 80))
Ejemplo n.º 7
0
def derive_milenage_opc(ki_hex, op_hex):
	"""
	Run the milenage algorithm to calculate OPC from Ki and OP
	"""
	from Crypto.Cipher import AES
	from Crypto.Util.strxor import strxor
	from pySim.utils import b2h

	# We pass in hex string and now need to work on bytes
	aes = AES.new(h2b(ki_hex))
	opc_bytes = aes.encrypt(h2b(op_hex))
	return b2h(strxor(opc_bytes, h2b(op_hex)))
Ejemplo n.º 8
0
def derive_milenage_opc(ki_hex, op_hex):
	"""
	Run the milenage algorithm.
	"""
	from Crypto.Cipher import AES
	from Crypto.Util.strxor import strxor
	from pySim.utils import b2h

	# We pass in hex string and now need to work on bytes
	aes = AES.new(h2b(ki_hex))
	opc_bytes = aes.encrypt(h2b(op_hex))
	return b2h(strxor(opc_bytes, h2b(op_hex)))
Ejemplo n.º 9
0
	def program(self, p):
		# Go to dir
		self._scc.select_file(['3f00', '7f4d'])

		# Home PLMN in PLMN_Sel format
		hplmn = enc_plmn(p['mcc'], p['mnc'])

		# Operator name ( 3f00/7f4d/8f0c )
		self._scc.update_record(self._files['name'][0], 2,
			rpad(b2h(p['name']), 32)  + ('%02x' % len(p['name'])) + '01'
		)

		# ICCID/IMSI/Ki/HPLMN ( 3f00/7f4d/8f0d )
		v = ''

			# inline Ki
		if self._ki_file is None:
			v += p['ki']

			# ICCID
		v += '3f00' + '2fe2' + '0a' + enc_iccid(p['iccid'])

			# IMSI
		v += '7f20' + '6f07' + '09' + enc_imsi(p['imsi'])

			# Ki
		if self._ki_file:
			v += self._ki_file + '10' + p['ki']

			# PLMN_Sel
		v+= '6f30' + '18' +  rpad(hplmn, 36)

			# ACC
			# This doesn't work with "fake" SuperSIM cards,
			# but will hopefully work with real SuperSIMs.
		if p.get('acc') is not None:
			v+= '6f78' + '02' + lpad(p['acc'], 4)

		self._scc.update_record(self._files['b_ef'][0], 1,
			rpad(v, self._files['b_ef'][1]*2)
		)

		# SMSP ( 3f00/7f4d/8f0e )
			# FIXME

		# Write PLMN_Sel forcefully as well
		r = self._scc.select_file(['3f00', '7f20', '6f30'])
		tl = int(r[-1][4:8], 16)

		hplmn = enc_plmn(p['mcc'], p['mnc'])
		self._scc.update_binary('6f30', hplmn + 'ff' * (tl-3))
Ejemplo n.º 10
0
	def program(self, p):
		# Go to dir
		self._scc.select_file(['3f00', '7f4d'])

		# Home PLMN in PLMN_Sel format
		hplmn = enc_plmn(p['mcc'], p['mnc'])

		# Operator name ( 3f00/7f4d/8f0c )
		self._scc.update_record(self._files['name'][0], 2,
			rpad(b2h(p['name']), 32)  + ('%02x' % len(p['name'])) + '01'
		)

		# ICCID/IMSI/Ki/HPLMN ( 3f00/7f4d/8f0d )
		v = ''

			# inline Ki
		if self._ki_file is None:
			v += p['ki']

			# ICCID
		v += '3f00' + '2fe2' + '0a' + enc_iccid(p['iccid'])

			# IMSI
		v += '7f20' + '6f07' + '09' + enc_imsi(p['imsi'])

			# Ki
		if self._ki_file:
			v += self._ki_file + '10' + p['ki']

			# PLMN_Sel
		v+= '6f30' + '18' +  rpad(hplmn, 36)

			# ACC
			# This doesn't work with "fake" SuperSIM cards,
			# but will hopefully work with real SuperSIMs.
		if p.get('acc') is not None:
			v+= '6f78' + '02' + lpad(p['acc'], 4)

		self._scc.update_record(self._files['b_ef'][0], 1,
			rpad(v, self._files['b_ef'][1]*2)
		)

		# SMSP ( 3f00/7f4d/8f0e )
			# FIXME

		# Write PLMN_Sel forcefully as well
		r = self._scc.select_file(['3f00', '7f20', '6f30'])
		tl = int(r[-1][4:8], 16)

		hplmn = enc_plmn(p['mcc'], p['mnc'])
		self._scc.update_binary('6f30', hplmn + 'ff' * (tl-3))
Ejemplo n.º 11
0
def set_phonebook(slot, name, number, capability='ff'):
        num_records = sc.record_count(['3f00','7f10','6f3a'])
        record_size = sc.record_size(['3f00','7f10','6f3a'])
        record_num = int(slot)
        if (record_num < 1) or (record_num > num_records):
                raise RuntimeError("Invalid phonebook record number")
        encoded_name = rpad(b2h(name), (record_size - 14) * 2)
        if len(encoded_name) > ((record_size - 14) * 2):
                raise RuntimeError("Name is longer than %s bytes" % ((record_size-14)))
        if len(number) > 20:
                raise RuntimeError("Number is too long")
        encoded_number = swap_nibbles(rpad(number, 20))
        record = encoded_name + ('%02x' % len(number)) + capability + encoded_number + 'ffff'
        sc.update_record(['3f00','7f10','6f3a'], record_num, record)
Ejemplo n.º 12
0
	def program(self, p):
		# Go to dir
		self._scc.select_file(['3f00', '7f4d'])

		# Home PLMN in PLMN_Sel format
		hplmn = self._e_plmn(p['mcc'], p['mnc'])

		# Operator name ( 3f00/7f4d/8f0c )
		self._scc.update_record(self._files['name'][0], 2,
			rpad(b2h(p['name']), 32)  + ('%02x' % len(p['name'])) + '01'
		)

		# ICCID/IMSI/Ki/HPLMN ( 3f00/7f4d/8f0d )
		v = ''

			# inline Ki
		if self._ki_file is None:
			v += p['ki']

			# ICCID
		v += '3f00' + '2fe2' + '0a' + self._e_iccid(p['iccid'])

			# IMSI
		v += '7f20' + '6f07' + '09' + self._e_imsi(p['imsi'])

			# Ki
		if self._ki_file:
			v += self._ki_file + '10' + p['ki']

			# PLMN_Sel
		v+= '6f30' + '18' +  rpad(hplmn, 36)

		self._scc.update_record(self._files['b_ef'][0], 1,
			rpad(v, self._files['b_ef'][1]*2)
		)

		# SMSP ( 3f00/7f4d/8f0e )
			# FIXME

		# Write PLMN_Sel forcefully as well
		r = self._scc.select_file(['3f00', '7f20', '6f30'])
		tl = int(r[-1][4:8], 16)

		hplmn = self._e_plmn(p['mcc'], p['mnc'])
		self._scc.update_binary('6f30', hplmn + 'ff' * (tl-3))
Ejemplo n.º 13
0
    def program(self, p):
        # Go to dir
        self._scc.select_file(['3f00', '7f4d'])

        # Home PLMN in PLMN_Sel format
        hplmn = self._e_plmn(p['mcc'], p['mnc'])

        # Operator name ( 3f00/7f4d/8f0c )
        self._scc.update_record(
            self._files['name'][0], 2,
            rpad(b2h(p['name']), 32) + ('%02x' % len(p['name'])) + '01')

        # ICCID/IMSI/Ki/HPLMN ( 3f00/7f4d/8f0d )
        v = ''

        # inline Ki
        if self._ki_file is None:
            v += p['ki']

            # ICCID
        v += '3f00' + '2fe2' + '0a' + self._e_iccid(p['iccid'])

        # IMSI
        v += '7f20' + '6f07' + '09' + self._e_imsi(p['imsi'])

        # Ki
        if self._ki_file:
            v += self._ki_file + '10' + p['ki']

            # PLMN_Sel
        v += '6f30' + '18' + rpad(hplmn, 36)

        self._scc.update_record(self._files['b_ef'][0], 1,
                                rpad(v, self._files['b_ef'][1] * 2))

        # SMSP ( 3f00/7f4d/8f0e )
        # FIXME

        # Write PLMN_Sel forcefully as well
        r = self._scc.select_file(['3f00', '7f20', '6f30'])
        tl = int(r[-1][4:8], 16)

        hplmn = self._e_plmn(p['mcc'], p['mnc'])
        self._scc.update_binary('6f30', hplmn + 'ff' * (tl - 3))
Ejemplo n.º 14
0
def dec_msisdn(ef_msisdn: Hexstr) -> Optional[Tuple[int, int, Optional[str]]]:
    """
	Decode MSISDN from EF.MSISDN or EF.ADN (same structure).
	See 3GPP TS 31.102, section 4.2.26 and 4.4.2.3.
	"""

    # Convert from str to (kind of) 'bytes'
    ef_msisdn = h2b(ef_msisdn)

    # Make sure mandatory fields are present
    if len(ef_msisdn) < 14:
        raise ValueError("EF.MSISDN is too short")

    # Skip optional Alpha Identifier
    xlen = len(ef_msisdn) - 14
    msisdn_lhv = ef_msisdn[xlen:]

    # Parse the length (in bytes) of the BCD encoded number
    bcd_len = msisdn_lhv[0]
    # BCD length = length of dial num (max. 10 bytes) + 1 byte ToN and NPI
    if bcd_len == 0xff:
        return None
    elif bcd_len > 11 or bcd_len < 1:
        raise ValueError("Length of MSISDN (%d bytes) is out of range" %
                         bcd_len)

    # Parse ToN / NPI
    ton = (msisdn_lhv[1] >> 4) & 0x07
    npi = msisdn_lhv[1] & 0x0f
    bcd_len -= 1

    # No MSISDN?
    if not bcd_len:
        return (npi, ton, None)

    msisdn = swap_nibbles(b2h(msisdn_lhv[2:][:bcd_len])).rstrip('f')
    # International number 10.5.118/3GPP TS 24.008
    if ton == 0x01:
        msisdn = '+' + msisdn

    return (npi, ton, msisdn)
Ejemplo n.º 15
0
    def program(self, p):
        # Home PLMN
        r = self._scc.select_file(['3f00', '7f20', '6f30'])
        tl = int(r[-1][4:8], 16)

        hplmn = self._e_plmn(p['mcc'], p['mnc'])
        self._scc.update_binary('6f30', hplmn + 'ff' * (tl - 3))

        # Get total number of entries and entry size
        rec_cnt, rec_len = self._get_infos()

        # Set first entry
        entry = (
            '81' +  #  1b  Status: Valid & Active
            rpad(b2h(p['name'][0:14]), 28) +  # 14b  Entry Name
            self._e_iccid(p['iccid']) +  # 10b  ICCID
            self._e_imsi(p['imsi']) +  #  9b  IMSI_len + id_type(9) + IMSI
            p['ki'] +  # 16b  Ki
            lpad(p['smsp'], 80)  # 40b  SMSP (padded with ff if needed)
        )
        self._scc.update_record('000c', 1, entry)
Ejemplo n.º 16
0
	def program(self, p):
		# Home PLMN
		r = self._scc.select_file(['3f00', '7f20', '6f30'])
		tl = int(r[-1][4:8], 16)

		hplmn = self._e_plmn(p['mcc'], p['mnc'])
		self._scc.update_binary('6f30', hplmn + 'ff' * (tl-3))

		# Get total number of entries and entry size
		rec_cnt, rec_len = self._get_infos()

		# Set first entry
		entry = (
			'81' +								#  1b  Status: Valid & Active
			rpad(b2h(p['name'][0:14]), 28) +	# 14b  Entry Name
			self._e_iccid(p['iccid']) +			# 10b  ICCID
			self._e_imsi(p['imsi']) +			#  9b  IMSI_len + id_type(9) + IMSI
			p['ki'] +							# 16b  Ki
			lpad(p['smsp'], 80)					# 40b  SMSP (padded with ff if needed)
		)
		self._scc.update_record('000c', 1, entry)
Ejemplo n.º 17
0
def s2h(s: str) -> Hexstr:
    """convert from an ASCII string to a string of hex nibbles"""
    b = bytearray()
    b.extend(map(ord, s))
    return b2h(b)
Ejemplo n.º 18
0
 def default(self, o):
     if isinstance(o, BytesIO) or isinstance(o, bytes) or isinstance(
             o, bytearray):
         return b2h(o)
     return json.JSONEncoder.default(self, o)
Ejemplo n.º 19
0
    sl.send_apdu_checksw('0026000108' + args.disable_pin.encode("hex") + 'ff' *
                         (8 - len(args.disable_pin)))

if args.dump_phonebook:
    num_records = sc.record_count(['3f00', '7f10', '6f3a'])
    print("Phonebook: %d records available" % num_records)
    for record_id in range(1, num_records + 1):
        print sc.read_record(['3f00', '7f10', '6f3a'], record_id)

if args.set_phonebook_entry:
    num_records = sc.record_count(['3f00', '7f10', '6f3a'])
    record_size = sc.record_size(['3f00', '7f10', '6f3a'])
    record_num = int(args.set_phonebook_entry[0])
    if (record_num < 1) or (record_num > num_records):
        raise RuntimeError("Invalid phonebook record number")
    encoded_name = rpad(b2h(args.set_phonebook_entry[1]),
                        (record_size - 14) * 2)
    if len(encoded_name) > ((record_size - 14) * 2):
        raise RuntimeError("Name is too long")
    if len(args.set_phonebook_entry[2]) > 20:
        raise RuntimeError("Number is too long")
    encoded_number = swap_nibbles(rpad(args.set_phonebook_entry[2], 20))
    record = encoded_name + (
        '%02x' % len(args.set_phonebook_entry[2])
    ) + args.set_phonebook_entry[3] + encoded_number + 'ffff'
    sc.update_record(['3f00', '7f10', '6f3a'], record_num, record)

if args.list_applets:
    (data, status) = ac.send_wrapped_apdu_ram('80f21000024f0000c0000000')
    while status == '6310':
        (partData,
Ejemplo n.º 20
0
	def verify_chv(self, chv_no, code):
		fc = rpad(b2h(code), 16)
		return self._tp.send_apdu_checksw(self.cla_byte + '2000' + ('%02X' % chv_no) + '08' + fc)
Ejemplo n.º 21
0
	def verify_chv(self, chv_no, code):
		fc = rpad(b2h(code), 16)
		return self._tp.send_apdu_checksw(self.cla_byte + '2000' + ('%02X' % chv_no) + '08' + fc)
Ejemplo n.º 22
0
	def change_chv(self, chv_no:int, pin_code:str, new_pin_code:str):
		"""Change a given CHV (Card Holder Verification == PIN)"""
		fc = rpad(b2h(pin_code), 16) + rpad(b2h(new_pin_code), 16)
		data, sw = self._tp.send_apdu(self.cla_byte + '2400' + ('%02X' % chv_no) + '10' + fc)
		self._chv_process_sw('change', chv_no, pin_code, sw)
		return (data, sw)
Ejemplo n.º 23
0
	def _chv_process_sw(self, op_name, chv_no, pin_code, sw):
		if sw_match(sw, '63cx'):
			raise RuntimeError('Failed to %s chv_no 0x%02X with code 0x%s, %i tries left.' %
							   (op_name, chv_no, b2h(pin_code).upper(), int(sw[3])))
		elif (sw != '9000'):
			raise SwMatchError(sw, '9000')
Ejemplo n.º 24
0
def s2h(s):
	b = bytearray()
	b.extend(map(ord, s))
	return b2h(b)
Ejemplo n.º 25
0
if args.disable_pin:
	sl.send_apdu_checksw('0026000108' + args.disable_pin.encode("hex") + 'ff' * (8 - len(args.disable_pin)))

if args.dump_phonebook:
	num_records = sc.record_count(['3f00','7f10','6f3a'])
	print ("Phonebook: %d records available" % num_records)
	for record_id in range(1, num_records + 1):
		print sc.read_record(['3f00','7f10','6f3a'], record_id)

if args.set_phonebook_entry:
	num_records = sc.record_count(['3f00','7f10','6f3a'])
	record_size = sc.record_size(['3f00','7f10','6f3a'])
	record_num = int(args.set_phonebook_entry[0])
	if (record_num < 1) or (record_num > num_records):
		raise RuntimeError("Invalid phonebook record number")
	encoded_name = rpad(b2h(args.set_phonebook_entry[1]), (record_size - 14) * 2)
	if len(encoded_name) > ((record_size - 14) * 2):
		raise RuntimeError("Name is too long")
	if len(args.set_phonebook_entry[2]) > 20:
		raise RuntimeError("Number is too long")
	encoded_number = swap_nibbles(rpad(args.set_phonebook_entry[2], 20))
	record = encoded_name + ('%02x' % len(args.set_phonebook_entry[2])) + args.set_phonebook_entry[3] + encoded_number + 'ffff'
	sc.update_record(['3f00','7f10','6f3a'], record_num, record)

if args.list_applets:
	(data, status) = ac.send_wrapped_apdu_ram('80f21000024f0000c0000000')
	while status == '6310':
		(partData, status) = ac.send_wrapped_apdu_ram('80f21001024f0000c0000000')
		data = data + partData

	while len(data) > 0:
Ejemplo n.º 26
0
 def _decode(self, obj, context, path):
     return swap_nibbles(b2h(obj))
Ejemplo n.º 27
0
 def _decode(self, obj, context, path):
     return b2h(obj)
Ejemplo n.º 28
0
	def verify_chv(self, chv_no:int, code:str):
		"""Verify a given CHV (Card Holder Verification == PIN)"""
		fc = rpad(b2h(code), 16)
		data, sw = self._tp.send_apdu(self.cla_byte + '2000' + ('%02X' % chv_no) + '08' + fc)
		self._chv_process_sw('verify', chv_no, code, sw)
		return (data, sw)
Ejemplo n.º 29
0
	def unblock_chv(self, chv_no:int, puk_code:str, pin_code:str):
		"""Unblock a given CHV (Card Holder Verification == PIN)"""
		fc = rpad(b2h(puk_code), 16) + rpad(b2h(pin_code), 16)
		data, sw = self._tp.send_apdu(self.cla_byte + '2C00' + ('%02X' % chv_no) + '10' + fc)
		self._chv_process_sw('unblock', chv_no, pin_code, sw)
		return (data, sw)
Ejemplo n.º 30
0
    def export(self, filename, context):
        """ Select and export a single file """
        context['COUNT'] += 1
        df = self._cmd.rs.selected_file

        if not isinstance(df, CardDF):
            raise RuntimeError(
                "currently selected file %s is not a DF or ADF" % str(df))

        df_path_list = df.fully_qualified_path(True)
        df_path_list_fid = df.fully_qualified_path(False)

        file_str = '/'.join(df_path_list) + "/" + str(filename)
        self._cmd.poutput(boxed_heading_str(file_str))

        self._cmd.poutput("# directory: %s (%s)" %
                          ('/'.join(df_path_list), '/'.join(df_path_list_fid)))
        try:
            fcp_dec = self._cmd.rs.select(filename, self._cmd)
            self._cmd.poutput("# file: %s (%s)" %
                              (self._cmd.rs.selected_file.name,
                               self._cmd.rs.selected_file.fid))

            fd = fcp_dec['file_descriptor']
            structure = fd['structure']
            self._cmd.poutput("# structure: %s" % str(structure))

            for f in df_path_list:
                self._cmd.poutput("select " + str(f))
            self._cmd.poutput("select " + self._cmd.rs.selected_file.name)

            if structure == 'transparent':
                result = self._cmd.rs.read_binary()
                self._cmd.poutput("update_binary " + str(result[0]))
            elif structure == 'cyclic' or structure == 'linear_fixed':
                num_of_rec = fd['num_of_rec']
                for r in range(1, num_of_rec + 1):
                    result = self._cmd.rs.read_record(r)
                    self._cmd.poutput("update_record %d %s" %
                                      (r, str(result[0])))
            elif structure == 'ber_tlv':
                tags = self._cmd.rs.retrieve_tags()
                for t in tags:
                    result = self._cmd.rs.retrieve_data(t)
                    (tag, l, val, remainer) = bertlv_parse_one(h2b(result[0]))
                    self._cmd.poutput("set_data 0x%02x %s" % (t, b2h(val)))
            else:
                raise RuntimeError('Unsupported structure "%s" of file "%s"' %
                                   (structure, filename))
        except Exception as e:
            bad_file_str = '/'.join(df_path_list) + "/" + str(
                filename) + ", " + str(e)
            self._cmd.poutput("# bad file: %s" % bad_file_str)
            context['ERR'] += 1
            context['BAD'].append(bad_file_str)

        # When reading the file is done, make sure the parent file is
        # selected again. This will be the usual case, however we need
        # to check before since we must not select the same DF twice
        if df != self._cmd.rs.selected_file:
            self._cmd.rs.select(df.fid or df.aid, self._cmd)

        self._cmd.poutput("#")
Ejemplo n.º 31
0
	def enable_chv(self, chv_no:int, pin_code:str):
		"""Enable a given CHV (Card Holder Verification == PIN)"""
		fc = rpad(b2h(pin_code), 16)
		data, sw = self._tp.send_apdu(self.cla_byte + '2800' + ('%02X' % chv_no) + '08' + fc)
		self._chv_process_sw('enable', chv_no, pin_code, sw)
		return (data, sw)
Ejemplo n.º 32
0
def s2h(s):
	return b2h(s)
Ejemplo n.º 33
0
if args.disable_pin:
	sl.send_apdu_checksw('0026000108' + args.disable_pin.encode("hex") + 'ff' * (8 - len(args.disable_pin)))

if args.dump_phonebook:
	num_records = sc.record_count(['3f00','7f10','6f3a'])
	print ("Phonebook: %d records available" % num_records)
	for record_id in range(1, num_records + 1):
		print sc.read_record(['3f00','7f10','6f3a'], record_id)

if args.set_phonebook_entry:
	num_records = sc.record_count(['3f00','7f10','6f3a'])
	record_size = sc.record_size(['3f00','7f10','6f3a'])
	record_num = int(args.set_phonebook_entry[0])
	if (record_num < 1) or (record_num > num_records):
		raise RuntimeError("Invalid phonebook record number")
	encoded_name = rpad(b2h(args.set_phonebook_entry[1]), (record_size - 14) * 2)
	if len(encoded_name) > ((record_size - 14) * 2):
		raise RuntimeError("Name is too long")
	if len(args.set_phonebook_entry[2]) > 20:
		raise RuntimeError("Number is too long")
	encoded_number = swap_nibbles(rpad(args.set_phonebook_entry[2], 20))
	record = encoded_name + ('%02x' % len(args.set_phonebook_entry[2])) + args.set_phonebook_entry[3] + encoded_number + 'ffff'
	sc.update_record(['3f00','7f10','6f3a'], record_num, record)

if args.list_applets:
	(data, status) = ac.send_wrapped_apdu('80f21000024f0000c0000000')
	while status == '6310':
		(partData, status) = ac.send_wrapped_apdu('80f21001024f0000c0000000')
		data = data + partData

	while len(data) > 0: