Beispiel #1
0
def process_data(data,data_type):
    dgi = Dgi()
    dgi.name = data_type
    item_list = process_tlv(data)
    for item in item_list:
        dgi.add_tag_value(item[0],item[2])
    return dgi
Beispiel #2
0
 def process_add_fixed_tag(self, dgi_name, tag, value, before_tag,
                           after_tag):
     dgis = self.cps.get_all_dgis()
     dgi_names = [dgi.name for dgi in dgis]
     if dgi_name not in dgi_names:
         new_dgi = Dgi()
         new_dgi.name = dgi_name
         new_dgi.add_tag_value(tag, value)
         self.cps.add_dgi(new_dgi)
     else:
         for item in self.cps.dgi_list:
             if item.name == dgi_name:
                 if tag in item.tag_value_dict:
                     old_value = item.get_value(tag)
                     new_value = old_value[len(tag) + 2:] + value
                     new_value = tag + utils.get_strlen(
                         new_value) + new_value
                     item.modify_value(tag, new_value)
                 else:
                     if before_tag is not '':
                         item.insert_before(before_tag, tag, value)
                     elif after_tag is not '':
                         item.insert_after(after_tag, tag, value)
                     else:
                         item.add_tag_value(tag, value)
     return self.cps
Beispiel #3
0
def get_cps(cps_file):
    '''
    通过cps文件获取cps数据
    '''
    cps = Cps()
    ini = IniParser(cps_file)
    sections = ini.get_sections()
    for section in sections:
        if section == 'AID_LIST':
            value = ini.get_value(section,section)
            aid_list = value.split(';')
            cps.pse_aid = aid_list[0]
            cps.ppse_aid = aid_list[1]
            cps.first_app_aid = aid_list[2]
            cps.second_app_aid = aid_list[3]
        elif section in ('DGI_LIST','DGI_LIST_2'):
            continue
        else:
            dgi = Dgi()
            dgi.name = section
            options = ini.get_options(section)
            for option in options:
                value = ini.get_value(section,option)
                dgi.add_tag_value(option,value)
            cps.add_dgi(dgi)
    return cps
Beispiel #4
0
def process_rule_eps(rule_file_name, cps):
    key = '0123456789ABCDEF1111111111111111'  #默认解密key
    rule_handle = RuleXml(rule_file_name)
    handle8020_node = rule_handle.get_first_node(rule_handle.root_element,
                                                 'Handle8020')
    if not handle8020_node:
        return cps
    key = rule_handle.get_attribute(handle8020_node, 'key')
    for dgi_item in cps.dgi_list:
        if dgi_item.name == '8020':
            tag8020 = ''
            tagA001 = ''
            value = dgi_item.get_value('8020')
            dgi_len = len(value)
            for i in range(0, dgi_len, 34):
                tagA001 += value[i:i + 2] + '010000FF0000'
                data = algorithm.des3_ecb_decrypt(key, value[i + 2:i + 34])
                tag8020 += data
            dgi_item.modify_value('8020', tag8020)
            dgiA001 = Dgi()
            dgiA001.name = 'A001'
            dgiA001.add_tag_value('A001', tagA001)
            cps.add_dgi(dgiA001)
        if dgi_item.name == '9020':
            tag9020 = ''
            value = dgi_item.get_value('9020')
            for i in range(0, len(value), 8):
                tag9020 += value[i + 2:i + 8]
            dgi_item.modify_value('9020', tag9020)
    return cps
Beispiel #5
0
 def process_add_tag(self, src_dgi, src_tag, dst_dgi, dst_tag):
     dst_tag_value = self._get_tag_value(dst_dgi, dst_tag)
     dgi = Dgi()
     dgi.name = src_dgi
     dgi.add_tag_value(src_tag, dst_tag_value)
     self.cps.add_dgi(dgi)
     return self.cps
Beispiel #6
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
Beispiel #7
0
def parse_A006(xml, goldpac_dgi_list):
    sddf_A006 = get_sddf_tag(xml, 'EMVDataName', 'Kidn')
    dgi = Dgi()
    dgi.name = 'A006'
    data = get_goldpac_data(goldpac_dgi_list, sddf_A006, False)
    rule_file_handle = RuleXml(xml.file_name)
    _, key = rule_file_handle.get_decrypted_attribute('A006')  #顺带解密
    data = algorithm.des3_ecb_decrypt(key, data)
    dgi.add_tag_value(dgi.name, data)
    return dgi
Beispiel #8
0
def process_jetco_special_dgi(xml, goldpac_dgi_list, cps):
    rule_file_handle = RuleXml(xml.file_name)
    add_tag_nodes = xml.get_nodes(xml.root_element, 'AddTag')
    for node in add_tag_nodes:
        attrs = xml.get_attributes(node)
        dgi = Dgi()
        dgi.name = attrs['srcDGI']
        if 'srcTag' not in attrs:
            attrs['srcTag'] = attrs['dstTag']
        data = ''
        is_second_app = False
        if '_2' in dgi.name:
            is_second_app = True
        # 对DF20,DF27做特殊处理
        if attrs['dstDGI'] == 'DF20':
            _, sddf_tag_DF18, _ = rule_file_handle.get_tag_link_attribute(
                'EMVTag', 'DF18')
            _, sddf_tag_DF19, _ = rule_file_handle.get_tag_link_attribute(
                'EMVTag', 'DF19')
            data_DF18 = get_goldpac_data(goldpac_dgi_list, sddf_tag_DF18,
                                         is_second_app)
            data_DF19 = get_goldpac_data(goldpac_dgi_list, sddf_tag_DF19,
                                         is_second_app)
            data = data_DF18 + data_DF19
            data = data[0:data.find('20')]
            data = utils.bcd_to_str(data)
            if len(data) // 2 > 0x7F:
                data = attrs['dstDGI'] + '81' + utils.get_strlen(data) + data
            else:
                data = attrs['dstDGI'] + utils.get_strlen(data) + data
        elif attrs['dstDGI'] == 'DF27':
            _, sddf_tag_DF16, _ = rule_file_handle.get_tag_link_attribute(
                'EMVTag', 'DF16')
            _, sddf_tag_DF17, _ = rule_file_handle.get_tag_link_attribute(
                'EMVTag', 'DF17')
            data_DF16 = get_goldpac_data(goldpac_dgi_list, sddf_tag_DF16,
                                         is_second_app)
            data_DF17 = get_goldpac_data(goldpac_dgi_list, sddf_tag_DF17,
                                         is_second_app)
            data = data_DF16 + data_DF17
            data = data[0:data.find('20')]
            data = utils.bcd_to_str(data)
            if len(data) // 2 > 0x7F:
                data = attrs['dstDGI'] + '81' + utils.get_strlen(data) + data
            else:
                data = attrs['dstDGI'] + utils.get_strlen(data) + data
        else:
            _, sddf_tag, _ = rule_file_handle.get_tag_link_attribute(
                'EMVTag', attrs['dstTag'])
            data = get_goldpac_data(goldpac_dgi_list, sddf_tag, is_second_app)
        dgi.add_tag_value(attrs['srcTag'], data)
        cps.add_dgi(dgi)
    return cps
Beispiel #9
0
def parse_pse_and_ppse(xml, pse_dgi_list, ppse_dgi_list, goldpac_dgi_list):
    pse_dgi = Dgi()
    pse_dgi.name = 'PSE'
    ppse_dgi = Dgi()
    ppse_dgi.name = 'PPSE'
    for sddf_tag in pse_dgi_list:
        tag, value = parse_pse_and_ppse_data(xml, sddf_tag, goldpac_dgi_list)
        pse_dgi.add_tag_value(tag, value)
    for sddf_tag in ppse_dgi_list:
        tag, value = parse_pse_and_ppse_data(xml, sddf_tag, goldpac_dgi_list)
        ppse_dgi.add_tag_value(tag, value)
    return pse_dgi, ppse_dgi
Beispiel #10
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
Beispiel #11
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
Beispiel #12
0
def process_pse(dgi,data):
    pse_dgi = Dgi()
    if dgi == '0098':
        pse_dgi.name = '0101'
        pse_dgi.add_tag_value(pse_dgi.name,data[4:])
    elif dgi == '0099':
        pse_dgi.name = '9102'
        pse_dgi.add_tag_value(pse_dgi.name,data)
    return pse_dgi
Beispiel #13
0
def split_rsa(xml, goldpac_dgi_list, is_second_app):
    rule_file_handle = RuleXml(xml.file_name)
    _, key = rule_file_handle.get_decrypted_attribute('RSA')
    sddf_tag = ''
    _, sddf_tag, _ = rule_file_handle.get_tag_link_attribute(
        'EMVDataName', 'Icc_KeyPair')
    if is_second_app:
        sddf_tag = sddf_tag[0:4] + get_second_app_index() + sddf_tag[5:8]
    else:
        sddf_tag = sddf_tag[0:4] + get_first_app_index() + sddf_tag[5:8]
    encrypted_data = get_goldpac_data(goldpac_dgi_list, sddf_tag,
                                      is_second_app)
    if encrypted_data is None:
        Log.error('无法获取RSA数据[tag' + sddf_tag + ']缺少数据')
    decrypted_data = algorithm.des3_ecb_decrypt(key, encrypted_data)
    if len(decrypted_data) <= 2 or decrypted_data[0:2] != '30':
        Log.error('RSA解密失败')
        return None
    decrypted_data = decrypted_data[2:]
    _, decrypted_data = get_rsa_dgi_len(decrypted_data)
    dgi_list = []
    for i in range(9):
        decrypted_data = decrypted_data[2:]  #remove flag '02'
        dgi_len, decrypted_data = get_rsa_dgi_len(decrypted_data)
        dgi_data = get_rsa_dgi_value(decrypted_data, dgi_len)
        decrypted_data = decrypted_data[dgi_len:]
        dgi = Dgi()
        if is_second_app:
            dgi.name = '_2'
        if i == 4:
            dgi.name = '8205' + dgi.name
        elif i == 5:
            dgi.name = '8204' + dgi.name
        elif i == 6:
            dgi.name = '8203' + dgi.name
        elif i == 7:
            dgi.name = '8202' + dgi.name
        elif i == 8:
            dgi.name = '8201' + dgi.name
        else:
            continue
        dgi.add_tag_value(dgi.name[0:4], dgi_data)
        dgi_list.append(dgi)
        Log.info(dgi.name[0:4] + '=' + dgi_data)
    return dgi_list
Beispiel #14
0
 def process_merge_tag(self, src_dgi, src_tag, dst_dgi, dst_tag):
     dst_item = self.cps.get_dgi(dst_dgi)
     dst_tag_value = dst_item.get_value(dst_tag)
     src_item = self.cps.get_dgi(src_dgi)
     if src_item is None:
         dgi = Dgi()
         dgi.name = src_dgi
         dgi.add_tag_value(src_tag, dst_tag_value)
         self.cps.add_dgi(dgi)
         return self.cps
     else:
         for item in self.cps.dgi_list:
             if item.name == src_dgi:
                 value = item.get_value(src_tag)
                 value += dst_tag_value
                 item.modify_value(src_tag, value)
                 return self.cps
     return self.cps
Beispiel #15
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
Beispiel #16
0
 def process_add_kcv(self, src_dgi, dst_dgi, key_type):
     item = self.cps.get_dgi(dst_dgi)
     key = item.get_value(item.name)
     key_len = len(key)
     kcv = ''
     if key_type == 'DES':
         for i in range(0, key_len, 32):
             part_key = key[i:i + 32]
             kcv += algorithm.des3_ecb_encrypt(part_key,
                                               '0000000000000000')[0:6]
     elif key_type == 'SM':
         for i in range(0, key_len, 32):
             part_key = key[i:i + 32]
             kcv += algorithm.sm4_ecb_encrypt(
                 part_key, '00000000000000000000000000000000')[0:6]
     dgi = Dgi()
     dgi.name = src_dgi
     dgi.add_tag_value(dgi.name, kcv)
     self.cps.add_dgi(dgi)
     return self.cps
Beispiel #17
0
def process_pse_and_ppse(dgi_name, dgi_data, dgi_node):
    dgi = Dgi()
    dgi.name = dgi_node
    if dgi_name == '9102':
        index = dgi_data.find('A5')
        dgi_data = dgi_data[index:len(dgi_data)]
        dgi.add_tag_value(dgi_name, dgi_data)
    else:
        dgi.add_tag_value(dgi_name, dgi_data)
    return dgi
Beispiel #18
0
 def process_assemble_dgi(self, src_dgi, src_tag, format_str):
     data = ""
     tag_list = format_str.split(',')
     for tag in tag_list[::-1]:
         if '.' not in tag:  #说明是模板
             data = tag + utils.get_strlen(data) + data
         else:
             dst_dgi = tag.split('.')[0]
             dst_tag = tag.split('.')[1]
             if dst_dgi == '':
                 data = dst_tag + data
             elif dst_dgi[len(dst_dgi) - 1] == 'v':
                 dst_dgi = dst_dgi[0:len(dst_dgi) - 1]
                 value = self.cps.get_tag_value(dst_dgi, dst_tag)
                 if not value:
                     print('dgi %s tag %s 不存在' % (dst_dgi, dst_tag))
                 data = value + data
             else:
                 value = ''
                 if dst_dgi in ('9102', '9103'):  #对于9103,9102需要特殊处理
                     tlvs = utils.parse_tlv(
                         self.cps.get_tag_value(dst_dgi, dst_dgi))
                     for tlv in tlvs:
                         if tlv.tag == dst_tag:
                             value = tlv.value
                             break
                 else:
                     value = self.cps.get_tag_value(dst_dgi, dst_tag)
                 if not value:
                     print('dgi %s tag %s 不存在' % (dst_dgi, dst_tag))
                 tag_len = utils.get_strlen(value)
                 data = dst_tag + tag_len + value + data
     dgi = Dgi()
     dgi.name = src_dgi
     dgi.add_tag_value(src_tag, data)
     self.cps.add_dgi(dgi)
     return self.cps
Beispiel #19
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
Beispiel #20
0
def parse_9000(xml, goldpac_dgi_list, is_second_app):
    sddf_9000_ac = get_sddf_tag(xml, 'EMVDataName', 'Checksum Kac')
    sddf_9000_mac = get_sddf_tag(xml, 'EMVDataName', 'Checksum Ksmi')
    sddf_9000_enc = get_sddf_tag(xml, 'EMVDataName', 'Checksum Ksmc')
    dgi = Dgi()
    if is_second_app:
        dgi.name = '9000_2'
    else:
        dgi.name = '9000'
    data = get_goldpac_data(goldpac_dgi_list, sddf_9000_ac, is_second_app)[0:6]
    data += get_goldpac_data(goldpac_dgi_list, sddf_9000_mac,
                             is_second_app)[0:6]
    data += get_goldpac_data(goldpac_dgi_list, sddf_9000_enc,
                             is_second_app)[0:6]
    dgi.add_tag_value(dgi.name, data)
    return dgi
Beispiel #21
0
def process_mag_data(fh,rule_file_name):
    rule_file = RuleXml(rule_file_name)
    mag_node = rule_file.get_first_node(rule_file.root_element,'Magstrip')
    
    mag_flag = fh.read_str(fh.current_offset,6)
    if mag_flag != '000MAG':
        return False
    mag_data_len = fh.read_int64(fh.current_offset)
    track_flag_list = []
    track_flag_list.append(fh.read(fh.current_offset,1))
    track_flag_list.append(fh.read(fh.current_offset + 1,1))
    track_flag_list.append(fh.read(fh.current_offset + 1,1))
    mag_data = fh.read_binary(fh.current_offset,mag_data_len - 5)
    mag_data_list = [x for x in mag_data.split('7C') if len(x) > 0]
    Log.info('decrypt mag data: ',end='')
    Log.info(mag_data_list)
    dgi = Dgi()
    dgi.name = 'Magstrip'
    if mag_node is not None:
        mag_key = rule_file.get_attribute(mag_node,'key')
        decrypt_mag_list = []
        for data in mag_data_list:
            data = utils.bcd_to_str(data)
            data = algorithm.des3_ecb_decrypt(mag_key,data)
            data = utils.bcd_to_str(data)
            data_len = int(data[0:4])
            data = data[4:data_len + 4].rstrip()
            decrypt_mag_list.append(data)
        pos = 1
        for mag in decrypt_mag_list:
            for index in range(pos,4):
                pos += 1
                option = 'mag' + str(pos)
                if track_flag_list[index - 1] == '0':
                    dgi.add_tag_value(option,'')
                    continue
                dgi.add_tag_value(option,mag)
                break
        Log.info('decrypt mag data: ',end='')
        Log.info(decrypt_mag_list)
    return dgi
Beispiel #22
0
def parse_8000(xml, goldpac_dgi_list, is_second_app):
    sddf_8000_ac = get_sddf_tag(xml, 'EMVDataName', 'Kac')
    sddf_8000_mac = get_sddf_tag(xml, 'EMVDataName', 'Ksmi')
    sddf_8000_enc = get_sddf_tag(xml, 'EMVDataName', 'Ksmc')
    dgi = Dgi()
    if is_second_app:
        dgi.name = '8000_2'
    else:
        dgi.name = '8000'
    data = get_goldpac_data(goldpac_dgi_list, sddf_8000_ac, is_second_app)
    data += get_goldpac_data(goldpac_dgi_list, sddf_8000_mac, is_second_app)
    data += get_goldpac_data(goldpac_dgi_list, sddf_8000_enc, is_second_app)
    rule_file_handle = RuleXml(xml.file_name)
    _, key = rule_file_handle.get_decrypted_attribute('8000')  #顺带解密
    data = algorithm.des3_ecb_decrypt(key, data)
    dgi.add_tag_value(dgi.name, data)
    return dgi
Beispiel #23
0
def process_EF02(cps):
    data_ef02 = ''
    for item in cps.dgi_list:
        if item.name == '01':
            data_ef02 = item.get_value('EF02')
    data_ef02 = data_ef02[8:]   #EF02总长度
    for i in range(8):
        bcd_item_len = data_ef02[0 : 8]
        n_item_len = int(utils.bcd_to_str(bcd_item_len)) * 2
        value = data_ef02[8 : 8 + n_item_len]
        data_ef02 = data_ef02[8 + n_item_len :]
        dgi = Dgi()
        if i == 3:
            dgi.name = '8205'
            dgi.add_tag_value(dgi.name,value)
            cps.add_dgi(dgi)
        elif i == 4:
            dgi.name = '8204'
            dgi.add_tag_value(dgi.name,value)
            cps.add_dgi(dgi)
        elif i == 5:
            dgi.name = '8203'
            dgi.add_tag_value(dgi.name,value)
            cps.add_dgi(dgi)
        elif i == 6:
            dgi.name = '8202'
            dgi.add_tag_value(dgi.name,value)
            cps.add_dgi(dgi)
        elif i == 7:
            dgi.name = '8201'
            dgi.add_tag_value(dgi.name,value)
            cps.add_dgi(dgi)
    return cps
Beispiel #24
0
def process_ppse(dgi,data):
    ppse_dgi = Dgi()
    if dgi == '0100':
        ppse_dgi.name = '9102'
        ppse_dgi.add_tag_value(ppse_dgi.name,data)
    return ppse_dgi
Beispiel #25
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
Beispiel #26
0
def process_dp(dp_file, rule_file, is_mc_app=False):
    global _is_mc_app
    _is_mc_app = is_mc_app
    cps_list = []
    fh = FileHandle(dp_file, 'rb+')
    dp_header = fh.read_binary(fh.current_offset, 26)
    dgi_count = fh.read_int(fh.current_offset)
    goldpac_dgi_list = []
    for i in range(dgi_count):  #获取sddf dgi个数及所包含数据的长度
        item = GoldpacDgi()
        item.goldpac_dgi = fh.read_binary(fh.current_offset, 4)
        item.data_len = fh.read_int(fh.current_offset)
        goldpac_dgi_list.append(item)
    for item in goldpac_dgi_list:  #获取sddf dgi所包含的数据
        item.data = fh.read_binary(fh.current_offset, item.data_len)
        Log.info(item.goldpac_dgi + ' = ' + item.data)
    xml = XmlParser(rule_file)
    get_aid_list_info(xml)  #获取AID应用列表信息
    sddf_dgi_list = []
    sddf_element_nodes = xml.get_nodes(xml.root_element, 'SDDFElement')
    constans_second_app = has_second_app()
    for node in sddf_element_nodes:
        sddf_tag = xml.get_attribute(node, 'SDDFTag')
        sddf_value = xml.get_attribute(node, 'Value')
        sddf_elements = parse_sddf_element(sddf_tag, sddf_value)
        sddf_dgi_list.extend(sddf_elements)
    cps = Cps()
    cps.dp_file_path = dp_file
    pse_dgi_list, ppse_dgi_list = get_pse_and_ppse_dgi_list(sddf_dgi_list)
    for sddf_tag in sddf_dgi_list:
        if sddf_tag not in pse_dgi_list and sddf_tag not in ppse_dgi_list:  #解析TagLink节点,并生成cps数据
            cps_dgi = parse_sddf_data(xml, sddf_tag, goldpac_dgi_list)
            if cps_dgi != None:
                cps.add_dgi(cps_dgi)
    dgi_8000 = parse_8000(xml, goldpac_dgi_list, False)
    dgi_9000 = parse_9000(xml, goldpac_dgi_list, False)
    cps.add_dgi(dgi_8000)
    cps.add_dgi(dgi_9000)
    if is_mc_app:
        dgi_A006 = parse_A006(xml, goldpac_dgi_list)
        cps.add_dgi(dgi_A006)
        dgi_A016 = Dgi()
        dgi_A016.name = 'A016'
        dgi_A016.add_tag_value('A016', dgi_A006.get_value('A006'))
        dgi_8001 = Dgi()
        dgi_8001.name = '8001'
        dgi_8001.add_tag_value('8001', dgi_8000.get_value('8000'))
        dgi_9001 = Dgi()
        dgi_9001.name = '9001'
        dgi_9001.add_tag_value('9001', dgi_9000.get_value('9000'))
        cps.add_dgi(dgi_8001)
        cps.add_dgi(dgi_9001)
        cps.add_dgi(dgi_A016)
    rsa_dgi_list = split_rsa(xml, goldpac_dgi_list, False)
    for rsa_dgi in rsa_dgi_list:
        cps.add_dgi(rsa_dgi)
    pse_dgi, ppse_dgi = parse_pse_and_ppse(xml, pse_dgi_list, ppse_dgi_list,
                                           goldpac_dgi_list)
    if pse_dgi.is_empty() is False:
        cps.add_dgi(pse_dgi)
    if ppse_dgi.is_empty() is False:
        cps.add_dgi(ppse_dgi)
    if constans_second_app:
        cps = process_jetco_special_dgi(xml, goldpac_dgi_list, cps)
        cps.add_dgi(parse_8000(xml, goldpac_dgi_list, True))
        cps.add_dgi(parse_9000(xml, goldpac_dgi_list, True))
        rsa_dgi_list = split_rsa(xml, goldpac_dgi_list, True)
        for rsa_dgi in rsa_dgi_list:
            cps.add_dgi(rsa_dgi)
    cps_list.append(cps)
    return cps_list
Beispiel #27
0
    def parse_store_data(self,
                         app_type,
                         dgi_name,
                         data,
                         session_key=None,
                         is_encrypted=False,
                         delete80_list=[]):
        int_dgi_name = int(dgi_name, 16)
        if is_encrypted and session_key:
            data = des3_ecb_decrypt(session_key, data)
            if dgi_name in delete80_list:
                index = data.rfind('80')
                if index != -1:
                    data = data[0:index]

        #对于PSE和PPSE,不解析TLV格式
        if app_type in ('PSE', 'PPSE'):
            dgi = Dgi()
            dgi.name = app_type
            if data.startswith('70'):
                data = data[4:]  #去掉70模板
            dgi.add_tag_value(dgi_name, data)
            return dgi
        else:
            #规则如下:
            #1. 小于0x0B00的记录数据需要解析TLV结构
            #2. 如果DGI大于0B00,并且该数据可以解析成TLV,则分如下情况
            #   a. 如果是8000,9000,9102,9103等不需要分析TLV结构的,则不分析
            #   b. 如果DGI以A,B字母开头(万事达应用),不用做TLV分析
            if int_dgi_name <= 0x0B00 \
                or (dgi_name not in self.do_not_parse_tlv_list \
                    and utils.is_tlv(data)\
                    and not (dgi_name.startswith('A') or dgi_name.startswith('B')) ):
                if utils.is_tlv(data):
                    tlvs = utils.parse_tlv(data)
                    return self._assemble_dgi(dgi_name, tlvs)
                else:
                    dgi = Dgi()
                    dgi.name = dgi_name
                    dgi.add_tag_value(dgi_name, data)
                    return dgi
            else:
                dgi = Dgi()
                dgi.name = dgi_name
                if dgi_name.endswith('_2'):
                    dgi_name = dgi_name[:-2]
                dgi.add_tag_value(dgi_name, data)
                return dgi
Beispiel #28
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
Beispiel #29
0
def process_data(app_flag, card_data):
    dgi = Dgi()
    dgi.name = app_flag
    data = card_data.split('|')
    dgi.add_tag_value(data[0], data[2])
    return dgi
Beispiel #30
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