Example #1
0
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
Example #2
0
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
Example #3
0
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
Example #4
0
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
Example #5
0
 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
Example #6
0
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
Example #7
0
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
Example #8
0
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