def select_application_by_aid(connection, aid):
    
    ret_data, sw1, sw2 = select_and_requery(connection=connection, cla=SELECT.cla, ins=SELECT.ins, p1=0x04, p2=0x00, data=aid, le=0x00)        
    
    if (len(ret_data) == 0):
        return None

    if DO_LOG:
        logging.info('\n' + 'SELECT (A)DF BY DF Name / AID')
        logging.info('AID = %s' % bit_tools.byte_list_to_hex_string(aid))
        for x in report_on_reply(sw1, sw2, ret_data):
            logging.info(x)
   
    # Table 45 (EMV 4.2 Book 1) - FCI Returned by ADF Selection
    #
    # FCI Template
    # 6f 17 8407a0000000041010a50c500a4d617374657243617264
        # DF Name = AID
        # 84 07 a0000000041010
        # FCI PROP TEMPLATE
        # a5 0c 500a4d617374657243617264
            # APP LABEL
            # 50 0a 4d617374657243617264   

    tlv_tree = tlv_utils.parse_tlv(ret_data, known_tags=tag_meanings.emv_tags.keys())
    
    if DO_LOG:
        logging.info('')
        for line in tlv_tree.report():
            logging.info(line)
            
    return tlv_tree
Example #2
0
def select_application_by_aid(connection, aid):
    
    ret_data, sw1, sw2 = select_and_requery(connection=connection, cla=SELECT.cla, ins=SELECT.ins, p1=0x04, p2=0x00, data=aid, le=0x00)        
    
    if (len(ret_data) == 0):
        return None

    if DO_LOG:
        logging.info('\n' + 'SELECT (A)DF BY DF Name / AID')
        logging.info('AID = %s' % bit_tools.byte_list_to_hex_string(aid))
        for x in report_on_reply(sw1, sw2, ret_data):
            logging.info(x)
   
    # Table 45 (EMV 4.2 Book 1) - FCI Returned by ADF Selection
    #
    # FCI Template
    # 6f 17 8407a0000000041010a50c500a4d617374657243617264
        # DF Name = AID
        # 84 07 a0000000041010
        # FCI PROP TEMPLATE
        # a5 0c 500a4d617374657243617264
            # APP LABEL
            # 50 0a 4d617374657243617264   

    tlv_tree = tlv_utils.parse_tlv(ret_data, known_tags=tag_meanings.emv_tags.keys())
    
    if DO_LOG:
        logging.info('')
        for line in tlv_tree.report():
            logging.info(line)
            
    return tlv_tree
Example #3
0
def parse_transaction_log_records(log_format_str, log_record_strings):
    '''
    return (csv_header_line, [csv_record_line])
    '''

    log_format_byte_list = bit_tools.hex_string_to_byte_list(log_format_str)
    log_format = tlv_utils.parse_concatted_dol_list_to_ordered_list_of_tag_and_length(
        log_format_byte_list)

    records = []
    for record_string in log_record_strings:
        records.append(bit_tools.hex_string_to_byte_list(record_string))

    parsed_records = []
    for orig_rec in records:

        rec = list(orig_rec)

        parsed = []
        for (tag_name, tag_length) in log_format:
            value = []
            for i in range(tag_length):
                value.append(rec.pop(0))
            parsed.append(value)

        parsed_records.append(parsed)

    #fname = 'c:/dev/logs/parsed_txn_log.log'
    #f = open(fname, 'w')

    csv_header = ','.join([
        tag_meanings.emv_tags[tag_name]
        for (tag_name, tag_length) in log_format
    ])
    #f.write(headers + '\n')

    csv_lines = []

    for parsed_rec in parsed_records:
        csv_string = ''
        for rec_element in parsed_rec:
            csv_string = (csv_string +
                          bit_tools.byte_list_to_hex_string(rec_element) + ',')
        csv_lines.append(csv_string)

    #for line in csv_lines:
    #    f.write(line + '\n')

    #f.close()

    return (csv_header, csv_lines)
def parse_transaction_log_records(log_format_str, log_record_strings):
    '''
    return (csv_header_line, [csv_record_line])
    '''    
    
    log_format_byte_list = bit_tools.hex_string_to_byte_list(log_format_str)
    log_format = tlv_utils.parse_concatted_dol_list_to_ordered_list_of_tag_and_length(log_format_byte_list)
    
    records = []
    for record_string in log_record_strings:
        records.append(bit_tools.hex_string_to_byte_list(record_string))
    
    parsed_records = []
    for orig_rec in records:
        
        rec = list(orig_rec)
        
        parsed = []        
        for (tag_name, tag_length) in log_format:
            value = []
            for i in range(tag_length):
                value.append(rec.pop(0))
            parsed.append(value)
        
        parsed_records.append(parsed)

    #fname = 'c:/dev/logs/parsed_txn_log.log'
    #f = open(fname, 'w')
    
    csv_header = ','.join([tag_meanings.emv_tags[tag_name] for (tag_name, tag_length) in log_format])
    #f.write(headers + '\n')
    
    csv_lines = []    
    
    for parsed_rec in parsed_records:
        csv_string = ''
        for rec_element in parsed_rec:
            csv_string = (csv_string + bit_tools.byte_list_to_hex_string(rec_element) + ',') 
        csv_lines.append(csv_string)

    #for line in csv_lines:
    #    f.write(line + '\n')

    #f.close()
    
    return (csv_header, csv_lines)
def get_pse_sfi(connection):
    '''
    attempt to retrieve SFI (Short File Identifier) 
    of the Directory Elementary File 
    of PSE (Payment System Environment)
    
    SUCCESS
    returns (sfi, tlv_tree, report)
    FAILURE
    returns (None, error_message)
    
    refer
    STRUCTURE OF THE PSE = 12.2.2
    APPLICATION SELECTION = EMV 4.2 Book 1 12 - page 135 / 151
    '''

    report = []

    # 3rd LSB bit-flag set => select by name    
    ref_control_param = 0x04
    
    # 00 => first-or-only-occurrence
    # 02 => next occurrence
    select_options = 0x00    
    
    data = [ord(c) for c in PSE_DDF_NAME]
    
    ret_data, sw1, sw2 = select_and_requery(connection=connection, 
        cla=SELECT.cla, ins=SELECT.ins,
        p1=ref_control_param, 
        p2=select_options, 
        data=data, 
        le=0x00)
    
    select_pse_error_tags = {
        '6A81' : 'card blocked, or select command not supported',
        '6A82' : 'no PSE / file not found',
        '6283' : 'PSE is blocked',
        }
    
    report.append('Attempting to Select PSE')
    report.append('DIRECTORY DEFINITION FILE = 1PAY.SYS.DDF01')
    for x in report_on_reply(sw1, sw2, ret_data):
        report.append(x)
    
    hex = '%00X%00X' % (sw1, sw2)
    # NO PSE
    if hex in select_pse_error_tags:
        report.append('Error - %s' % select_pse_error_tags[hex])
    # PSE FOUND
    else:
        # EMV 4.2 Book 1  - 11.3 Select Command-Response APDUs, Table 44
        # FCI Template returned by successful selection of a DDF
        # Response = 6f 19 84 0e 31 50 41 59 2e 53 59 53 2e 44 44 46 30 31 a5 07 88 01 01 9f 11 01 01
        
        # FCI Template
        # 6f 19 840e315041592e5359532e4444463031a5078801019f110101 (length = 50)
            # DF Name
            # 84 0e 315041592e5359532e4444463031
            # FCI Proprietary Template 
            # a5 07 8801019f110101
                # SFI of the Directory Elementary File
                # 88 01 01
                # Issuer Code Table Index
                # 9f11 01 01        
        
        tlv_tree = tlv_utils.parse_tlv(ret_data, known_tags=tag_meanings.emv_tags.keys())
       
        report.append('')
        for line in tlv_tree.report():
            report.append(line)    
    
        # '88':'Short File Identifier (SFI)',
        node = tlv_tree.get_nodes_for_qtag('6F.A5.88')[0]
        sfi = node.value_byte_list[0]
        
        report.append('SFI for PSE - %s' % bit_tools.byte_list_to_hex_string([sfi]))
        
        return (sfi, tlv_tree, report)
    
    return (None, select_pse_error_tags[hex], report)
Example #6
0
def get_pse_sfi(connection):
    '''
    attempt to retrieve SFI (Short File Identifier) 
    of the Directory Elementary File 
    of PSE (Payment System Environment)
    
    SUCCESS
    returns (sfi, tlv_tree, report)
    FAILURE
    returns (None, error_message)
    
    refer
    STRUCTURE OF THE PSE = 12.2.2
    APPLICATION SELECTION = EMV 4.2 Book 1 12 - page 135 / 151
    '''

    report = []

    # 3rd LSB bit-flag set => select by name
    ref_control_param = 0x04

    # 00 => first-or-only-occurrence
    # 02 => next occurrence
    select_options = 0x00

    data = [ord(c) for c in PSE_DDF_NAME]

    ret_data, sw1, sw2 = select_and_requery(connection=connection,
                                            cla=SELECT.cla,
                                            ins=SELECT.ins,
                                            p1=ref_control_param,
                                            p2=select_options,
                                            data=data,
                                            le=0x00)

    select_pse_error_tags = {
        '6A81': 'card blocked, or select command not supported',
        '6A82': 'no PSE / file not found',
        '6283': 'PSE is blocked',
    }

    report.append('Attempting to Select PSE')
    report.append('DIRECTORY DEFINITION FILE = 1PAY.SYS.DDF01')
    for x in report_on_reply(sw1, sw2, ret_data):
        report.append(x)

    hex = '%00X%00X' % (sw1, sw2)
    # NO PSE
    if hex in select_pse_error_tags:
        report.append('Error - %s' % select_pse_error_tags[hex])
    # PSE FOUND
    else:
        # EMV 4.2 Book 1  - 11.3 Select Command-Response APDUs, Table 44
        # FCI Template returned by successful selection of a DDF
        # Response = 6f 19 84 0e 31 50 41 59 2e 53 59 53 2e 44 44 46 30 31 a5 07 88 01 01 9f 11 01 01

        # FCI Template
        # 6f 19 840e315041592e5359532e4444463031a5078801019f110101 (length = 50)
        # DF Name
        # 84 0e 315041592e5359532e4444463031
        # FCI Proprietary Template
        # a5 07 8801019f110101
        # SFI of the Directory Elementary File
        # 88 01 01
        # Issuer Code Table Index
        # 9f11 01 01

        tlv_tree = tlv_utils.parse_tlv(ret_data,
                                       known_tags=tag_meanings.emv_tags.keys())

        report.append('')
        for line in tlv_tree.report():
            report.append(line)

        # '88':'Short File Identifier (SFI)',
        node = tlv_tree.get_nodes_for_qtag('6F.A5.88')[0]
        sfi = node.value_byte_list[0]

        report.append('SFI for PSE - %s' %
                      bit_tools.byte_list_to_hex_string([sfi]))

        return (sfi, tlv_tree, report)

    return (None, select_pse_error_tags[hex], report)