def process_pse_and_ppse(fh, dgi_name, has_template): dgi = Dgi() data = '' dgi_mark = fh.read_binary(fh.current_offset, 1) #DGI标识 if dgi_mark != '86': return next_len = get_next_len(fh) if has_template: fh.read_binary(fh.current_offset, 1) #读取70模板 next_len = get_next_len(fh) data = fh.read_binary(fh.current_offset, next_len) else: data = fh.read_binary(fh.current_offset, next_len) if dgi_name == 'Store_PSE_1': dgi.name = 'PSE' #value = dgi.assemble_tlv('0101',data) dgi.add_tag_value('0101', data) elif dgi_name == 'Store_PSE_2': dgi.name = 'PSE' value = utils.assemble_tlv('A5', '880101' + data) dgi.add_tag_value('9102', value) elif dgi_name == 'Store_PPSE': dgi.name = 'PPSE' value = utils.assemble_tlv('BF0C', data) value = utils.assemble_tlv('A5', value) dgi.add_tag_value('9102', value) else: dgi.name = 'F001' dgi.add_tag_value('F001', data) return dgi
def process_dp(dp_file, rule_file): fh = FileHandle(dp_file, 'rb+') fh.read(fh.current_offset, 8596) #reserved dgi_list = get_dgi_list(fh) file_size = fh.file_size cps_list = [] while fh.current_offset < file_size: card_seq = fh.read_int64_reverse(fh.current_offset) card_data_total_len = fh.read_int_reverse(fh.current_offset) cps = Cps() #存储单个卡片数据 cps.dp_file_path = dp_file pse_and_ppse_dgi = [ 'Store_PSE_1', 'Store_PSE_2', 'Store_PPSE', 'DGIF001' ] for dgi_name in dgi_list: dgi = Dgi() #存储单个DGI数据 if dgi_name in pse_and_ppse_dgi: if dgi_name == 'Store_PSE_1': dgi = process_pse_and_ppse(fh, dgi_name, True) else: dgi = process_pse_and_ppse(fh, dgi_name, False) cps.add_dgi(dgi) continue dgi_mark = fh.read_binary(fh.current_offset, 1) #DGI标识 if dgi_mark != '86': return next_len = get_next_len(fh) dgi_seq = fh.read_binary(fh.current_offset, 2) #读取DGI序号 dgi.name = dgi_seq next_len = get_next_len(fh) n_dgi_seq = utils.hex_str_to_int(dgi_seq) if n_dgi_seq <= 0x0B00: #认为是记录 template70 = fh.read_binary(fh.current_offset, 1) if template70 != '70': return next_len = get_next_len(fh) dgi_data = fh.read_binary(fh.current_offset, next_len) if n_dgi_seq <= 0x0B00 or (dgi_seq not in do_not_parse_tlv_list and utils.is_tlv(dgi_data)): tlvs = utils.parse_tlv(dgi_data) if len(tlvs) > 0 and tlvs[0].is_template is True: value = utils.assemble_tlv(tlvs[0].tag, tlvs[0].value) dgi.add_tag_value(dgi_seq, value) else: for tlv in tlvs: value = utils.assemble_tlv(tlv.tag, tlv.value) dgi.add_tag_value(tlv.tag, value) else: dgi.add_tag_value(dgi_seq, dgi_data) cps.add_dgi(dgi) if rule_file is not None: process_rule(rule_file, cps) process_rule_A001(rule_file, cps) process_rule_eps(rule_file, cps) cps_list.append(cps) return cps_list
def process_dp(dp_file, rule_file): cps_list = [] fh = FileHandle(dp_file, 'rb+') dp_flag = fh.read_binary(fh.current_offset, 7) data_len = utils.hex_str_to_int(fh.read_binary(fh.current_offset, 8)) dgi_count = fh.read_int64(fh.current_offset) dgi_list = [] for i in range(dgi_count): dgi_name_len = fh.read_int(fh.current_offset) dgi_name = fh.read_str(fh.current_offset, dgi_name_len) dgi_list.append(dgi_name) card_seq = fh.read_binary(fh.current_offset, 4) card_data_len = fh.read_int(fh.current_offset) while data_len > fh.current_offset: cps = Cps() cps.dp_file_path = dp_file for item in dgi_list: dgi = Dgi() start_flag = fh.read_binary(fh.current_offset, 1) if start_flag != '86': return cps_list dgi_len = get_len(fh) dgi_name = fh.read_binary(fh.current_offset, 2) dgi.name = dgi_name dgi_data_len = utils.hex_str_to_int( fh.read_binary(fh.current_offset, 1)) n_dgi_seq = utils.hex_str_to_int(dgi_name) if n_dgi_seq <= 0x0B00: #认为是记录 template70 = fh.read_binary(fh.current_offset, 1) if template70 != '70': return cps_list dgi_data_len = get_len(fh) dgi_data = fh.read_binary(fh.current_offset, dgi_data_len) if item[0:3] == 'PSE': dgi = process_pse_and_ppse(dgi_name, dgi_data, 'PSE') elif item[0:4] == 'PPSE': dgi = process_pse_and_ppse(dgi_name, dgi_data, 'PPSE') else: if n_dgi_seq <= 0x0B00 or (utils.is_rsa(dgi_name) is False and utils.is_tlv(dgi_data)): tlvs = utils.parse_tlv(dgi_data) if len(tlvs) > 0 and tlvs[0].is_template is True: value = utils.assemble_tlv(tlvs[0].tag, tlvs[0].value) dgi.add_tag_value(dgi_name, value) else: for tlv in tlvs: value = utils.assemble_tlv(tlv.tag, tlv.value) dgi.add_tag_value(tlv.tag, value) else: dgi.add_tag_value(dgi_name, dgi_data) cps.add_dgi(dgi) if rule_file is not None: process_rule(rule_file, cps) cps_list.append(cps) return cps_list
def process_card_data(fh, rule_file): cps = Cps() flag = fh.read_str(fh.current_offset, 6) if flag != '000EMV': return False, cps card_data_len = fh.read_int64(fh.current_offset) app_count = utils.hex_str_to_int(fh.read_binary(fh.current_offset, 1)) for app in range(app_count): aid_len = utils.hex_str_to_int(fh.read_binary(fh.current_offset, 1)) aid = fh.read_binary(fh.current_offset, aid_len) app_data_len = fh.read_int64(fh.current_offset) dgi_list, encrypt_dgi_list = get_dgi_list(fh) Log.info('encrypt dgi list :', encrypt_dgi_list) for item in dgi_list: card_dgi = Dgi() dgi = fh.read_binary(fh.current_offset, 2) dgi_len = utils.hex_str_to_int(fh.read_binary( fh.current_offset, 1)) dgi_data = fh.read_binary(fh.current_offset, dgi_len) n_dgi = utils.hex_str_to_int(dgi) card_dgi.dgi = dgi if dgi == '0098' or dgi == '0099': dgi = process_pse(dgi, dgi_data) elif dgi == '0100': dgi = process_ppse(dgi, dgi_data) else: if n_dgi < 0x0B01: if dgi_data[0:2] != '70': return False, cps if dgi_data[2:4] == '81': dgi_data = dgi_data[6:] else: dgi_data = dgi_data[4:] if utils.is_rsa(dgi) is False and utils.is_tlv(dgi_data): tlvs = utils.parse_tlv(dgi_data) if len(tlvs) > 0 and tlvs[0].is_template is True: value = utils.assemble_tlv(tlvs[0].tag, tlvs[0].value) card_dgi.add_tag_value(dgi, value) else: for tlv in tlvs: value = process_tag_decrypt( rule_file, tlv.tag, tlv.value) value = utils.assemble_tlv(tlv.tag, value) card_dgi.add_tag_value(tlv.tag, value) else: card_dgi.add_tag_value(dgi, dgi_data) cps.add_dgi(card_dgi) return True, cps
def _assemble_dgi(self, dgi_name, tlvs): dgi = Dgi() dgi.name = dgi_name for tlv in tlvs: if not tlv.is_template: value = utils.assemble_tlv(tlv.tag, tlv.value) #组装为TLV结构 dgi.add_tag_value(tlv.tag, value) return dgi
def _parse_tlv(dgi_name, data): dgi = Dgi() data = utils.remove_dgi(data, dgi_name) int_dgi = utils.str_to_int(dgi_name) if int_dgi < 0x0B01: if data[0:2] != '70': Log.error('数据有误,小于0B01的DGI应包含70模板') return None data = utils.remove_template70(data) if not utils.is_rsa(dgi_name) and utils.is_tlv(data): tlvs = utils.parse_tlv(data) if len(tlvs) > 0 and tlvs[0].is_template is True: value = utils.assemble_tlv(tlvs[0].tag, tlvs[0].value) dgi.add_tag_value(dgi_name, value) else: for tlv in tlvs: value = utils.assemble_tlv(tlv.tag, tlv.value) dgi.add_tag_value(tlv.tag, value) else: dgi.add_tag_value(dgi_name, data) return dgi
def _process_pse_and_ppse(dgi_name, data): dgi = Dgi() if dgi_name == 'Store_PSE_1': dgi.name = 'PSE' data = utils.remove_dgi(data, '0101') data = utils.remove_template70(data) dgi.add_tag_value('0101', data) elif dgi_name == 'Store_PSE_2': dgi.name = 'PSE' data = utils.remove_dgi(data, '9102') value = utils.assemble_tlv('A5', '880101' + data) dgi.add_tag_value('9102', value) elif dgi_name == 'Store_PPSE': dgi.name = 'PPSE' # value = dgi.assemble_tlv('BF0C',data) # value = dgi.assemble_tlv('A5',value) data = utils.remove_dgi(data, '9102') dgi.add_tag_value('9102', data) return dgi
def parse_sddf_data(xml, sddf_tag, goldpac_dgi_list=[]): sddf_data = '' for item in goldpac_dgi_list: if item.goldpac_dgi == sddf_tag: sddf_data = item.data dgi = Dgi() node_dgi, value_format = get_tag_link_attribute(xml, sddf_tag) if node_dgi == '' or value_format == '': return None need_remove_template = is_need_delete_template(node_dgi) global _aid_list_info is_second_app = False for _, aid_info in _aid_list_info.items(): if sddf_tag[4] == aid_info[0]: is_second_app = aid_info[1] break if is_second_app: #说明包含双应用 dgi.name = node_dgi + '_2' else: dgi.name = node_dgi if value_format == 'TLV': data = utils.remove_dgi(sddf_data, node_dgi) if need_remove_template: data = utils.remove_template70(data) if utils.str_to_int(node_dgi) > 0xA000 or not utils.is_tlv(data): dgi.add_tag_value(dgi.name, data) else: tlvs = utils.parse_tlv(data) if len(tlvs) > 0 and tlvs[0].is_template is True: value = utils.assemble_tlv(tlvs[0].tag, tlvs[0].value) dgi.add_tag_value(dgi.name, value) else: for tlv in tlvs: if tlv.len > 0x7F: value = tlv.tag + '81' + utils.int_to_hex_str( tlv.len) + tlv.value else: value = tlv.tag + utils.int_to_hex_str( tlv.len) + tlv.value dgi.add_tag_value(tlv.tag, value) elif value_format == 'V': dgi.add_tag_value(dgi.name, sddf_data) return dgi