def LoadHMACKeys():
    req_unsolicited = conn.connect()
    if req_unsolicited:
        status, buf, uns = conn.receive()
        check_status_error(status)

    log.log("Loading the HMAC keys: host_id 6 and 7 - ver 2")

    hmackey06 = b'\xFE\xDC\xBA\x98\x76\x54\x32\x10\x01\x23\x45\x67\x89\xAB\xCD\xEF'
    hmackey06 += b'\xFE\xDC\xBA\x98\x76\x54\x32\x10\x01\x23\x45\x67\x89\xAB\xCD\xEF'
    hmackey06 += b'\xFE\xDC\xBA\x98\x76\x54\x32\x10\x01\x23\x45\x67\x89\xAB\xCD\xEF'
    hmackey06 += b'\xFE\xDC\xBA\x98\x76\x54\x32\x10\x01\x23\x45\x67\x89\xAB\xCD\xEF'
    log.log("HMAC key 06:", hexlify(hmackey06).decode('utf-8'))

    hmackey07 = b'\x01\x23\x45\x67\x89\xAB\xCD\xEF\xFE\xDC\xBA\x98\x76\x54\x32\x10'
    hmackey07 += b'\x01\x23\x45\x67\x89\xAB\xCD\xEF\xFE\xDC\xBA\x98\x76\x54\x32\x10'
    hmackey07 += b'\x01\x23\x45\x67\x89\xAB\xCD\xEF\xFE\xDC\xBA\x98\x76\x54\x32\x10'
    hmackey07 += b'\x01\x23\x45\x67\x89\xAB\xCD\xEF\xFE\xDC\xBA\x98\x76\x54\x32\x10'
    log.log("HMAC key 07:", hexlify(hmackey07).decode('utf-8'))

    c_tag = tagStorage()
    c_tag.store((0xDF, 0xEC, 0x46), 0x03)
    c_tag.store((0xDF, 0xEC, 0x2E), hmackey06)
    conn.send([0xC4, 0x0A, 0x06, 0x01], c_tag.getTemplate(0xE0))
    status, buf, uns = conn.receive()
    log.log("Received key 06 update status")
    check_status_error(status)

    c_tag = tagStorage()
    c_tag.store((0xDF, 0xEC, 0x46), 0x03)
    c_tag.store((0xDF, 0xEC, 0x2E), hmackey07)
    conn.send([0xC4, 0x0A, 0x07, 0x01], c_tag.getTemplate(0xE0))
    status, buf, uns = conn.receive()
    log.log("Received key 07 update status")
    check_status_error(status)
def demo_function():
   ''' First create connection '''
   req_unsolicited = conn.connect()
   ''' If unsolicited read it'''
   if req_unsolicited:
         status, buf, uns = conn.receive()
         check_status_error( status )
   ''' Reset display '''
   conn.send([0xD2, 0x01, 0x01, 0x00])
   status, buf, uns = conn.receive(3)
   check_status_error( status )
   ''' Store the tags for numeric entry '''
   c_tag = tagStorage()
   c_tag.store( (0xDF, 0xA2, 0x06), [0x00, 0x0D, 0x00, 0x57, 0x00, 0x00] )
   c_tag.store( (0xDF, 0xA2, 0x07), [0x30, 0x00] )
   c_tag.store( (0xDF, 0xA2, 0x08), b'123' )
   ''' Send the message '''
   conn.send( [0xD2, 0x04, 0x00, 0x01], c_tag.getTemplate( 0xE0 ) )
   ''' Receive and check '''
   status, buf, uns = conn.receive(30)
   check_status_error( status )
   '''print the buffer example '''
   '''print(buf) '''
   tlv = TLVParser(buf)
   user_input = tlv.getTag((0xDF, 0xA2, 0x08))
   log.log('User enter [', str(user_input[0], 'iso8859-1'), ']') 
Example #3
0
def request_choice_on_pinpad_demo():
    ''' First create connection '''
    req_unsolicited = conn.connect()
    ''' If unsolicited read it'''
    if req_unsolicited:
        status, buf, uns = conn.receive()
        check_status_error(status)
    ''' Reset display '''
    conn.setnad(2)
    conn.send([0xD2, 0x01, 0x01, 0x00])
    status, buf, uns = conn.receive()
    check_status_error(status)
    ''' Send data '''
    c_tag = tagStorage()
    c_tag.store((0xDF, 0xA2, 0x12), LIST_STYLE_SCROLL)
    #BUG: Unable to push the direct string not bytearray
    c_tag.store((0xDF, 0xA2, 0x11), 'Optional title')
    for i in range(1, 6):
        c_tag.store((0xDF, 0xA2, 0x02), i)
        c_tag.store((0xDF, 0xA2, 0x03), 'Item %d' % i)
    conn.send([0xD2, 0x03, 0x00, 0x01], c_tag.get())

    is_unsolicited = True
    while is_unsolicited:  # unsolicited responses come when echo mode is on
        status, buf, is_unsolicited = conn.receive()
        check_status_error(status)
    sleep(3)
Example #4
0
def execute_script(filename):
    global __SCRIPT_ROOT
    __SCRIPT_ROOT = os.path.dirname(os.path.abspath(filename))
    th_ast_parser = __create_ast_th_language_syntax()
    ast = th_ast_parser.parseFile(filename, True)
    log = getSyslog()
    conn = connection.Connection()
    req_unsolicited = conn.connect()
    abort_sw1sw2 = True
    pool = tagStorage()
    localtempl = {}
    if req_unsolicited:
        #Receive unsolicited
        status, buf, uns = conn.receive()
        if status != 0x9000:
            raise exc.invResponseException('Unsolicited message fail', status)
        log.log('Unsolicited', TLVParser(buf))
    for toks in ast:
        if toks[0] == 'setnad':
            conn.setnad(toks[1])
            log.loginfo('Set NAD to', toks[1])
        elif toks[0] == '#':
            log.loginfo("Comment:", str(toks[1]).strip())
        elif toks[0] == 'setdevice':
            log.loginfo('Set device to', toks[1])
        elif toks[0] == 'flush':
            log.loginfo('Flush comms')
        elif toks[0] == 'clearlocalpool':
            pool.clear()
            localtempl.clear()
            log.loginfo('Clear local pool')
        elif toks[0] == 'pause':
            log.loginfo('Pause for', toks[1], 'sec')
            time.sleep(toks[1])
        elif toks[0] == 'send':
            __send_command(toks, conn, pool, localtempl, log)
        elif toks[0] == 'abortsw1sw2':
            abort_sw1sw2 = toks[1]
            log.loginfo('Abort SW1SW2 =', abort_sw1sw2)
        elif toks[0] == 'wait':
            __wait_command(toks, conn, log, abort_sw1sw2)
        elif toks[0] == 'prompt':
            log.loginfo('Prompt message:', str(" ").join(toks[1].asList()))
            __wait_command(toks, conn, log, abort_sw1sw2)
        elif toks[0] == 'storelocaltag':
            pool = __storetag_command(toks, pool)
        elif toks[0] == 'appendlocal':
            tpl, data = __appendlocal_command(toks, pool)
            localtempl[tpl] = data
        elif toks[0] == 'senddirect':
            __senddirect_command(toks, conn, log)
        elif toks[0] == 'putfile':
            __putfile_command(toks, conn, log)
        elif toks[0] == 'updatefile':
            __updatefile_command(toks, conn, log)
        elif toks[0] == 'getfile':
            __getfile_command(toks, conn, log)
        else:
            log.logerr('Unknown tokens', str(toks))
            raise exc.logicalException('Unknown tokens in script')
Example #5
0
def get_vfi_certificate():
    certNo = 0x00000001
    global ux_certificates
    ux_certificates.clear()
    while True:
        c_tag = tagStorage()
        #BUG: Unable to push the direct string not bytearray
        c_tag.store( (0xDF, 0x83, 0x10), int(certNo) )
        conn.send([0xC5, 0x06, 0x00, 0x00] , c_tag.getTemplate(0xE0))
        status, buf, uns = conn.receive()
        if status == 0x9000:
            tlv = TLVParser(buf)
            if tlv.tagCount( (0xDF, 0x83, 0x11) ) == 1:
                log.log("Success")
                key = tlv.getTag( (0xDF, 0x83, 0x11) )[0]
                log.log("Key: ", hexlify(key))
                ux_certificates.append(key)
                certNo += 1
            else:
                log.logerr("Failure")
        else:
            break
        sleep(1)
    #check_status_error( status )
    log.log("We have ", len(ux_certificates), " UX certificates")
    #log.log("UX certs: ", ux_certificates)
    return len(ux_certificates)
def OnlinePIN():
    ''' First create connection '''
    req_unsolicited = conn.connect()
    ''' If unsolicited read it'''
    #status, buf, uns = conn.receive()
    #check_status_error( status )
    ''' Send data '''
    pan = b'\x54\x13\x33\x00\x89\x00\x00\x39'
    c_tag = tagStorage()
    #BUG: Unable to push the direct string not bytearray
    c_tag.store( (0xDF, 0xEC, 0x05), 0x00 )
    c_tag.store( (0xDF, 0xED, 0x05), 0x08 )
    c_tag.store( (0xDF, 0x17), '\x00\x00\x00\x00\x01\x51' )
    c_tag.store( (0xDF, 0x24), '\x08\x26' )
    c_tag.store( (0xDF, 0x1C,), 0x02 )
    c_tag.store( (0x5A), pan )
    conn.send([0xDE, 0xD6, 0x03, 0x00] , c_tag.getTemplate(0xE0))
    
    sleep(3)

    conn.send([0xD0, 0x00, 0x00, 0x32])
    status, buf, uns = conn.receive()
    check_status_error( status )

    # Wait for last package
    status, buf, uns = conn.receive()
    slog = getSyslog()
    if status == 0x9F41:
        slog.loginfo('Status is "Cancelled amount" as expected:', hex(status))
    else:
        slog.logerr('Status is not "Cancelled amount"', hex(status), buf)
        sys.exit(-1)
Example #7
0
def processCtlsMiFare():
    # Set LEDs
    leds_tag = [
        [(0xDF, 0xDF, 0x0C),
         [0x01]],  # Success - single beep (0x02 = Error - Double beep)
        [(0xDF, 0xC0, 0x18), [0xff]
         ]  # All LEDs on (0A would enable 2nd and 4th LED, it's 1010 binary)
    ]
    leds_template = (0xE0, leds_tag)
    conn.send([0xC0, 0x10, 0x00, 0x00], leds_template)
    status, buf, uns = getAnswer()
    if (status != 0x9000):
        log.logerr('UI function failed!')
        # Todo: What should we do? Let's just ignore the error and continue

    # Read some stuff
    c_read_oper = tagStorage()
    c_read_oper.store((0xDF, 0xA5, 0x01), [
        0x02
    ])  # DFA501 - Operation type (0x02 - Read, 0x03 - Write, ,0x04 - EPurse)
    c_read_oper.store(
        (0xDF, 0xA5, 0x02),
        'READ1')  # DFA502 - ID so that the output can be identified
    c_read_oper.store((0xDF, 0xC0, 0x5A), [0x00])  # DFC05A - Sector number
    c_read_oper.store(
        (0xDF, 0xC0, 0x5B),
        [0x01]),  # DFC05B - Key type (0x01 - Type A, 0x02 - Type B)
    c_read_oper.store(
        (0xDF, 0xC0, 0x5C),
        b'\xFF\xFF\xFF\xFF\xFF\xFF')  # DFC05C - Valid key (6 bytes)
    c_read_oper.store((0xDF, 0xC0, 0x5D),
                      [0x01])  # DFC05D - Starting block number
    c_read_oper.store((0xDF, 0xC0, 0x5E),
                      [0x02])  # DFC05E - Number of blocks to read
    read_oper_1 = c_read_oper.getAsBytearray()
    c_read_oper.clear()
    c_read_oper.store((0xDF, 0xA5, 0x01), [
        0x02
    ])  # DFA501 - Operation type (0x02 - Read, 0x03 - Write, ,0x04 - EPurse)
    c_read_oper.store(
        (0xDF, 0xA5, 0x02),
        'READ2')  # DFA502 - ID so that the output can be identified
    c_read_oper.store((0xDF, 0xC0, 0x5A), [0x03])  # DFC05A - Sector number
    c_read_oper.store(
        (0xDF, 0xC0, 0x5B),
        [0x01])  # DFC05B - Key type (0x00 - Type A, 0x01 - Type B)
    c_read_oper.store(
        (0xDF, 0xC0, 0x5C),
        b'\xFF\xFF\xFF\xFF\xFF\xFF')  # DFC05C - Valid key (6 bytes)
    c_read_oper.store((0xDF, 0xC0, 0x5D),
                      [0x02])  # DFC05D - Starting block number
    c_read_oper.store((0xDF, 0xC0, 0x5E),
                      [0x02])  # DFC05E - Number of blocks to read
    read_oper_2 = c_read_oper.getAsBytearray()
    c_read_oper.clear()
    c_read_oper.store((0xDF, 0xC0, 0x30), read_oper_1)
    #c_read_oper.store((0xDF, 0xC0, 0x30), read_oper_2)
    conn.send([0xC0, 0xA1, 0x00, 0x00], c_read_oper.getTemplate(0xE0))
    status, buf, uns = getAnswer()
Example #8
0
def store_certificate(filename, level):
    put_file(filename)
    c_tag = tagStorage()
    c_tag.store( (0xDF, 0x83, 0x12), os.path.basename(filename).lower() )
    c_tag.store( (0xDF, 0x83, 0x10), level )
    conn.send([0xC5, 0x07, 0x00, 0x00], c_tag.getTemplate(0xE0))
    status, buf, uns = conn.receive()
    return status == 0x9000
Example #9
0
def __appendlocal_command(toks, pool):
    newpool = tagStorage()
    newpool.clear()
    tplvalue = toks[1][0]
    for t in toks[2]:
        fdata = pool.getTagData(tuple(t))
        newpool.store(t, fdata)
    return tplvalue, newpool.getTemplate(tplvalue)
Example #10
0
def GenerateHMAC():
    req_unsolicited = conn.connect()
    if req_unsolicited:
        status, buf, uns = conn.receive()
        check_status_error(status)

    #pan = b'\x41\x11\x11\x11\x11\x11\x11\x11'
    pan = '4111111111111111'
    # expected HMAC for TC test secrets: d1f8827dd9276f9f80f8890d3e607ac03ca022ba91b8024356dcdf54ad434f83
    # pan = b'\x34\x30\x30\x35\x35\x36\x32\x32\x33\x31\x32\x31\x32\x31\x34\x39'
    c_tag = tagStorage()
    c_tag.store((0xDF, 0xEC, 0x0E), pan)  # message for MAC
    c_tag.store((0xDF, 0xEC, 0x23), 0x06)  # host ID
    #c_tag.store((0xDF, 0xEC, 0x23), 0x07)  # host ID
    conn.send([0xC4, 0x22, 0x00, 0x00], c_tag.getTemplate(0xE0))
    log.log("Generate HMAC sent")

    status, buf, uns = conn.receive()
    log.log("Generate HMAC response received")
    check_status_error(status)

    tlv = TLVParser(buf)
    tag_output_data = (0xDF, 0xEC, 0x7B)
    if (tlv.tagCount(tag_output_data) == 1):
        hmac = tlv.getTag(tag_output_data)[0]
        log.log("Generated HMAC:", hexlify(hmac).decode('utf-8'))

        c_tag = tagStorage()
        c_tag.store((0xDF, 0xEC, 0x0E), hmac)  # message for MAC
        #c_tag.store((0xDF, 0xEC, 0x23), 0x06)  # host ID
        c_tag.store((0xDF, 0xEC, 0x23), 0x07)  # host ID
        conn.send([0xC4, 0x22, 0x00, 0x00], c_tag.getTemplate(0xE0))
        log.log("Generate HMAC sent")

        status, buf, uns = conn.receive()
        log.log("Generate HMAC response received")
        check_status_error(status)

        tlv = TLVParser(buf)
        tag_output_data = (0xDF, 0xEC, 0x7B)
        if (tlv.tagCount(tag_output_data) == 1):
            hmac = tlv.getTag(tag_output_data)[0]
            log.log("Generated HMAC:", hexlify(hmac).decode('utf-8'))
Example #11
0
def update_key_command(conn, host_id, pvk_enc):
    log.log("Updating the PVK using Master session key, host_id is", host_id)
    #pvk_enc=b'\x65\xF3\x8A\xFD\x1B\x85\xDB\xB6\xCB\xFC\xD9\xCD\xD1\x46\xAC'

    c_tag = tagStorage()
    c_tag.store((0xDF, 0xEC, 0x46), 0x01)
    c_tag.store((0xDF, 0xEC, 0x2E), pvk_enc)
    conn.send([0xC4, 0x0A, host_id, 0x01], c_tag.getTemplate(0xE0))
    status, buf, uns = conn.receive()
    log.log("Received key update status")
    check_status_error(status)
Example #12
0
def GenerateHMAC():
    req_unsolicited = conn.connect()
    if req_unsolicited:
        status, buf, uns = conn.receive()
        check_status_error(status)

    pan = b'\x41\x11\x11\x11\x11\x11\x11\x11'
    # pan = b'\x34\x30\x30\x35\x35\x36\x32\x32\x33\x31\x32\x31\x32\x31\x34\x39'
    c_tag = tagStorage()
    c_tag.store((0xDF, 0xEC, 0x0E), pan)  # message for MAC
    c_tag.store((0xDF, 0xEC, 0x23), 0x06)  # host ID
    #c_tag.store((0xDF, 0xEC, 0x23), 0x07)  # host ID
    conn.send([0xC4, 0x22, 0x00, 0x00], c_tag.getTemplate(0xE0))
    log.log("Generate HMAC sent")

    status, buf, uns = conn.receive()
    log.log("Generate HMAC response received")
    check_status_error(status)

    tlv = TLVParser(buf)
    tag_output_data = (0xDF, 0xEC, 0x7B)
    if (tlv.tagCount(tag_output_data) == 1):
        hmac = tlv.getTag(tag_output_data)[0]
        log.log("Generated HMAC:", hexlify(hmac).decode('utf-8'))

        c_tag = tagStorage()
        c_tag.store((0xDF, 0xEC, 0x0E), hmac)  # message for MAC
        #c_tag.store((0xDF, 0xEC, 0x23), 0x06)  # host ID
        c_tag.store((0xDF, 0xEC, 0x23), 0x07)  # host ID
        conn.send([0xC4, 0x22, 0x00, 0x00], c_tag.getTemplate(0xE0))
        log.log("Generate HMAC sent")

        status, buf, uns = conn.receive()
        log.log("Generate HMAC response received")
        check_status_error(status)

        tlv = TLVParser(buf)
        tag_output_data = (0xDF, 0xEC, 0x7B)
        if (tlv.tagCount(tag_output_data) == 1):
            hmac = tlv.getTag(tag_output_data)[0]
            log.log("Generated HMAC:", hexlify(hmac).decode('utf-8'))
Example #13
0
def get_cert_file():
    c_tag = tagStorage()
    c_tag.store( (0xDF, 0x83, 0x10), 0x00000000 )
    conn.send([0xC5, 0x06, 0x01, 0x00], c_tag.getTemplate(0xE0))
    status, buf, uns = conn.receive()
    if status == 0x9000:
        tlv = TLVParser(buf)
        if tlv.tagCount( (0xDF, 0x83, 0x12 ) ) == 1:
            fname = tlv.getTag( (0xDF, 0x83, 0x12) )[0]
            log.log("Cert file ", fname)
        else:
            log.logerr("Error, no cert name!")
    else:
        log.logerr("Bad response ", status)
Example #14
0
def init_ns():
    # Initialize NS
    crypto1 = gvrsim.initiate_ns( ux_certificates )
    if len(crypto1) == 0:
        log.logerr("Init NS failed!")
        return -1
    log.log("crypto1: ", hexlify(crypto1))
    # Verify NS
    c_tag = tagStorage()
    c_tag.store( (0xDF, 0xEC, 0x0F), crypto1 )
    conn.send([0xC5, 0x0A, 0x00, 0x00], c_tag.getTemplate(0xE0))
    status, buf, uns = conn.receive()
    if status != 0x9000:
        log.logerr("Resolve NS failed!")
        return -2
    # Check crypto2
    tlv = TLVParser(buf)
    if tlv.tagCount( (0xDF, 0xEC, 0x7B) ) != 1:
        log.logerr("Crypto2 missing!")
        return -3
    log.log("Verify NS success")
    crypto2 = tlv.getTag( (0xDF, 0xEC, 0x7B) )[0]
    log.log("Crypto2: ", hexlify(crypto2))
    # Read UPM Key
    exp, mod = gvrsim.read_upm_pubkey()
    if len(mod) == 0:
        log.logerr("Read UPM public key failed")
        return -4
    # Finalize NS
    global crypto3
    crypto3 = gvrsim.finalize_ns(mod, bytes(crypto2))
    if len(crypto3) == 0:
        log.logerr("Finalize NS failed")
        return -5
    log.log("Crypto3: ", hexlify(crypto3))
    # Verify NS
    c_tag.clear()
    c_tag.store( (0xDF, 0xEC, 0x0F), crypto3 )
    conn.send([0xC5, 0x0B, 0x00, 0x00], c_tag.getTemplate(0xE0))
    status, buf, uns = conn.receive()
    if status != 0x9000:
        log.logerr("Verify NS failed!")
        return -2
    # We are done!
    return 1
def put_data_sample():
    ''' First create connection '''
    req_unsolicited = conn.connect()
    ''' If unsolicited read it'''
    if req_unsolicited:
        status, buf, uns = conn.receive()
        check_status_error(status)
    ''' Reset display '''
    conn.send([0xD2, 0x01, 0x01, 0x00])
    status, buf, uns = conn.receive()
    check_status_error(status)
    ''' Send data '''
    c_tag = tagStorage()
    #BUG: Unable to push the direct string not bytearray
    c_tag.store((0xE0), [0xDF, 0xA2, 0x0F])
    conn.send([0x00, 0xDA, 0xFF, 0xFF], c_tag.get())
    status, buf, uns = conn.receive()
    check_status_error(status)
def demo_function():
    ''' First create connection '''
    req_unsolicited = conn.connect()
    ''' If unsolicited read it'''
    if req_unsolicited:
        status, buf, uns = conn.receive()
        check_status_error(status)
    ''' Store the tags for numeric entry '''
    c_tag = tagStorage()

    #index or text, one mandatory

    # index
    #c_tag.store( (0xDF, 0xA2, 0x06), [0x00, 0x0D] )  # enter card pan
    #c_tag.store( (0xDF, 0xA2, 0x06), [0x00, 0x57] )  # press enter

    # text
    c_tag.store((0xDF, 0xA2, 0x13), [0x41, 0x42, 0x43, 0x44])
    #c_tag.store( (0xDF, 0xA2, 0x13), [0x41, 0x42, 0x43, 0x44, 0x46, 0x47, 0x48, 0x49] )
    #c_tag.store( (0xDF, 0xA2, 0x13), [0x41, 0x42, 0x43, 0x44, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x41] )

    # max len
    c_tag.store((0xDF, 0x83, 0x05), [0x0A])
    ''' Send the message '''
    NAD_PINPAD = 2
    conn.setnad(NAD_PINPAD)
    conn.send([0xD2, 0xF1, 0x00, 0x00], c_tag.getTemplate(0xE0))

    #''' abort '''
    #time.sleep(7)
    #conn.send([0xD0, 0xFF, 0x00, 0x00])
    #time.sleep(5)
    #status, buf, uns = conn.receive(3)
    #check_status_error( status )
    #return
    ''' Receive and check '''
    status, buf, uns = conn.receive(30)
    check_status_error(status)
    '''print the buffer example '''
    '''print(buf) '''
    tlv = TLVParser(buf)
    user_input = tlv.getTag((0xDF, 0x83, 0x01))
    log.log('User enter [', str(user_input[0], 'iso8859-1'), ']')
Example #17
0
def transmit_password(set_new_key, password_no):
    # Get ARS password and encrypt them
    ars = get_ars_password()
    if len(ars) == 0:
        log.logerr("ARS password not entered!")
        return -2
    c_tag = tagStorage()
    if (password_no == 1): c_tag.store( (0xDF, 0xEC, 0x2E), ars )
    else: c_tag.store( (0xDF, 0xEC, 0x2F), ars )
    INS = 0x01
    if set_new_key: INS = 0x02
    conn.send([0xC5, INS, 0x00, 0x00], c_tag.getTemplate(0xE0))
    status, buf, uns = conn.receive()
    if status != 0x9000:
        log.logerr("Cannot verify ARS password(s)!")
        return -3
    if set_new_key: log.log("ARS password set correctly")
    else: log.log("ARS password verified correctly")
    return 1
def updatefile(conn, log, fn, remote_fn=None, signature=False, progress=None):
    if not os.path.isfile(fn):
        raise exc.logicalException('File ' + fn + ' doesnt exist!')
    from struct import pack
    if remote_fn == None: remote_fn = os.path.basename(fn)
    log.log('Uploading file ', fn, ' as ', remote_fn)
    fileSize = os.path.getsize(fn)
    size = hex(fileSize)[2:]
    while len(size) < 8:
        size = '0' + size
    log.log('size ', size)

    c_tag = tagStorage()
    c_tag.store((0x84), remote_fn.lower())
    c_tag.store((0x80), bytearray.fromhex(size))
    conn.send([0x00, 0xA5, 0x05, 0x81], c_tag.getTemplate(0x6F))
    status, buf, uns = conn.receive()
    if status != 0x9000:
        raise exc.invResponseException('Cannot upload file ' + fn, status)
    dataCnt = 0
    prevPercent = -1
    with open(fn, 'rb') as f:
        while True:
            readData = f.read(1024)
            readSize = len(readData)
            if (readSize == 0): break
            dataCnt += readSize
            sendData = bytearray(readData)
            conn.send_raw(sendData)
            if hasattr(progress, '__call__'):
                percent = round(dataCnt / fileSize, 2)
                if percent != prevPercent: progress(percent)
                prevPercent = percent

    log.log('Done, waiting for confirmation')
    # We're done, wait for response
    status, buf, uns = conn.receive()
Example #19
0
def get_session_key(key_type):
    global crypto3
    global session_key
    if len(crypto3) == 0:
        log.logerr("N-S not initialized!")
        return -1
    session_key = ''
    c_tag = tagStorage()
    c_tag.store( (0xDF, 0xEC, 0x0F), crypto3 )
    conn.send([0xC5, 0x00, key_type, 0x00], c_tag.getTemplate(0xE0))
    status, buf, uns = conn.receive()
    if status != 0x9000:
        log.logerr("Cannot get session key!")
        return -2
    # Got it
    tlv = TLVParser(buf)
    if tlv.tagCount( (0xDF, 0xEC, 0x2E) ) == 1:
        log.log("Session key received")
        session_key = tlv.getTag( (0xDF, 0xEC, 0x2E) )[0]
        log.log("Session key: ", hexlify(session_key))
        return 1
    else:
        log.logerr("Failure")
        return -3
Example #20
0
def AuthVerify():

    posDevCertDecodedFile = os.path.join(CERT_DIR, "pos_device_cert.dec")
    posDevCertFile = os.path.join(CERT_DIR, "pos_device_cert.enc")
    posSEKFormattedDecodedFile = os.path.join(CERT_DIR,
                                              "pos_sek_formatted.dec")
    posSEKDecodedFile = os.path.join(CERT_DIR, "pos_sek.dec")
    termSEKDecodedFile = os.path.join(CERT_DIR, "term_sek.dec")
    posSEKFile = os.path.join(CERT_DIR, "pos_sek.enc")
    posRandomFile = os.path.join(CERT_DIR, "pos.rnd")
    termRandomFile = os.path.join(CERT_DIR, "term.rnd")
    posDIDFile = os.path.join(CERT_DIR, "pos.did")
    termDIDFile = os.path.join(CERT_DIR, "term.did")
    POSKey = os.path.join(CERT_DIR, "pos.key")
    terminalPub = os.path.join(CERT_DIR, "ped.pub")
    mutualSEKFile = os.path.join(CERT_DIR, "mutual_sek.dec")

    fposRND = open(posRandomFile, 'rb')
    posRandom = fposRND.read()
    fposRND.close()

    ftermRND = open(termRandomFile, 'rb')
    termRandom = ftermRND.read()
    ftermRND.close()

    fposDID = open(posDIDFile, 'rb')
    posDID = fposDID.read()
    fposDID.close()

    ftermDID = open(termDIDFile, 'rb')
    termDID = ftermDID.read()
    ftermDID.close()

    posDevCert = bytearray(b'\x00\x01')
    for x in range(256 - 39):
        posDevCert.append(255)
    posDevCert.append(0)
    posDevCert = b"".join([posDevCert, posRandom])
    posDevCert = b"".join([posDevCert, termRandom])
    posDevCert = b"".join([posDevCert, termDID])
    posDevCert = b"".join([posDevCert, posDID])

    with open(posDevCertDecodedFile, "wb") as f:
        f.write(posDevCert)
        f.close()

    formattedPosSEK = bytearray(b'\x00\x01')
    for x in range(256 - 19):
        formattedPosSEK.append(255)
    formattedPosSEK.append(0)
    posSEK = ''.join([random.choice('0123456789ABCDEF') for x in range(32)])
    bposSEK = binascii.unhexlify(posSEK)
    formattedPosSEK = b"".join([formattedPosSEK, bposSEK])

    with open(posSEKDecodedFile, "wb") as f:
        f.write(bposSEK)
        f.close()

    with open(posSEKFormattedDecodedFile, "wb") as f:
        f.write(formattedPosSEK)
        f.close()

    log.log("Signing POS device certificate")
    opensslcmd = "openssl rsautl -sign -raw -inkey " + POSKey + " -in " + posDevCertDecodedFile + " -out " + posDevCertFile
    os.system(opensslcmd)
    if os.path.isfile(posDevCertFile):
        log.log("POS device certificate is signed")
        f = open(posDevCertFile, 'rb')
        posDevCertEnc = f.read()
        f.close()

    log.log("Encrypting POS stream encrytion key")
    opensslcmd = "openssl rsautl -verify -raw -inkey " + terminalPub + " -pubin -in " + posSEKFormattedDecodedFile + " -out " + posSEKFile
    os.system(opensslcmd)
    if os.path.isfile(posSEKFile):
        log.log("POS stream encrytion key is encrypted")
        f = open(posSEKFile, 'rb')
        formattedPosSEKEnc = f.read()
        f.close()

    f = open(posSEKDecodedFile, 'rb')
    poskey = bytearray(f.read())
    f.close()

    f = open(termSEKDecodedFile, 'rb')
    termkey = bytearray(f.read())
    f.close()

    for i in range(len(poskey)):
        termkey[i] ^= poskey[i]

    f = open(mutualSEKFile, 'wb')
    f.write(termkey)
    f.close()

    log.log("Mutual stream encryption key is saved: ", mutualSEKFile)
    ''' First create connection '''
    req_unsolicited = conn.connect()
    ''' If unsolicited read it'''
    if req_unsolicited:
        status, buf, uns = conn.receive()
    ''' Send data '''
    c_tag = tagStorage()
    c_tag.store((0xDF, 0x83, 0x14), posDevCertEnc)
    c_tag.store((0xDF, 0x83, 0x15), formattedPosSEKEnc)

    conn.send([0xDD, 0x22, 0x01, 0x00], c_tag.getTemplate(0xE0))
    status, buf, uns = conn.receive()
    check_status_error(status)
Example #21
0
def process_tx():
    # This just processes Start EMV transaction and executes Verify PIN afterwards!
    # Check if card is inserted
    conn.send([0xD0, 0x60, 0x00, 0x00])
    status, buf, uns = conn.receive()
    if status != 0x9000:
        log.logerr("Error checking for card presence!")
        return -1
    tlv = TLVParser(buf)
    if tlv.tagCount(0x48):
        ins_tag_val = tlv.getTag(0x48, TLVParser.CONVERT_INT)[0]
        ins_tag_val &= 0xFF00
        ins_tag_val >>= 8
        if ins_tag_val != 3:
            log.logerr("EMV card is NOT inserted!")
            return -2
    # Carry on
    date = strftime( "%y%m%d" )
    time = strftime( "%H%M%S" )
    tags = tagStorage()
    tags.store( (0x9F, 0x02), b'\x00\x00\x00\x00\x50\x00' )
    tags.store( (0x9A), bytearray.fromhex(date) )
    tags.store( (0x9F, 0x21), bytearray.fromhex(time) )
    tags.store( (0x9A), b'\x00' )
    tags.store( (0x9C), b'\x00' )
    tags.store( (0x9F,0x41), b'\x00\x01' )
    tags.store( (0x5F,0x2A), b'\x08\x26' )
    tags.store( (0xDF,0xA2,0x18), b'\x01' )
    tags.store( (0xDF,0xA2,0x14), b'\x01' )
    tags.store( (0xDF,0xA2,0x04), b'\x01' )

    #Start transaction
    conn.send([0xDE, 0xD1, 0x00, 0x00], tags.getTemplate(0xE0))
    while True:
        #sleep(1)
        #conn.send([0xD0, 0xFF, 0x00, 0x00])
        status, buf, uns = conn.receive()
        if status != 0x9000:
            if status == 0x9F28:
                log.logerr("Unsupported card!")
            else:
                log.logerr("Transaction terminated with status ", hex(status))
            return -3
        else:
            break
    # Ok, start tx processed. Get PIN, encrypt it, verify it
    while True:
        c_pin = input("Enter PIN: ")
        if len(c_pin) < 4 or len(c_pin) > 12:
            log.logerr("Invalid PIN length ", len(c_pin))
            return -4
        global session_key
        if get_session_key(0) <= 0:
            log.logerr("Cannot generate session key for PIN!")
            return -5
        enc_pin = gvrsim.encrypt_pin( bytes(session_key), c_pin )
        if len(enc_pin) == 0:
            log.logerr("Cannot encrypt PIN!")
        # Provide this to VIPA
        tags.clear()
        tags.store( (0xDF, 0xED, 0x6C), enc_pin );
        conn.send([0xDE, 0xD8, 0x01, 0x00], tags.getTemplate(0xE0))
        while True:
            status, buf, uns = conn.receive_raw()
            if uns:
                log.log("Unsolicited stuff, ignoring")
            else:
                break
        if status != 0x9000:
            log.logerr("This should NEVER happen!")
            return -6
        if len(buf) == 3:
            from struct import unpack
            pres = buf[0]
            card_status = unpack("!H",buf[1:3])[0]
            log.log("Result ", hex(pres), ", card SW1SW2 ", hex(card_status))
            if pres == 0x00:
                log.logerr("Unknown error, should never happen!")
                return -100
            elif pres == 0x01:
                log.logerr("PIN failed, card might be blocked!")
                return -101
            elif pres == 0x02:
                log.log("PIN okay!")
                break
            elif pres == 0x03:
                log.logerr("Error during Get Challenge!")
                # Retry here?
            elif pres == 0x05:
                log.logerr("Invalid card!")
                return -102
            elif pres == 0x06:
                log.logerr("Incorrect PIN entered")
                # Retry for sure
        else:
            log.logerr("Invalid response length ", len(buf))
            return -7
    return 1
def AuthVerify():
    posDevCertDecodedFile = os.path.join(CERT_DIR, "pos_device_cert.dec")
    posDevCertFile = os.path.join(CERT_DIR, "pos_device_cert.enc")
    posSEKFormattedDecodedFile = os.path.join(CERT_DIR,
                                              "pos_sek_formatted.dec")
    posSEKDecodedFile = os.path.join(CERT_DIR, "pos_sek.dec")
    termSEKDecodedFile = os.path.join(CERT_DIR, "term_sek.dec")
    posSEKFile = os.path.join(CERT_DIR, "pos_sek.enc")
    posRandomFile = os.path.join(CERT_DIR, "pos.rnd")
    termRandomFile = os.path.join(CERT_DIR, "term.rnd")
    posDIDFile = os.path.join(CERT_DIR, "pos.did")
    termDIDFile = os.path.join(CERT_DIR, "term.did")
    mutualSEKFile = os.path.join(CERT_DIR, "mutual_sek.dec")

    fposRND = open(posRandomFile, 'rb')
    posRandom = fposRND.read()
    fposRND.close()

    ftermRND = open(termRandomFile, 'rb')
    termRandom = ftermRND.read()
    ftermRND.close()

    fposDID = open(posDIDFile, 'rb')
    posDID = fposDID.read()
    fposDID.close()

    ftermDID = open(termDIDFile, 'rb')
    termDID = ftermDID.read()
    ftermDID.close()

    posDevCert = bytearray(b'\x00\x01')
    for x in range(256 - 39):
        posDevCert.append(255)
    posDevCert.append(0)
    posDevCert = b"".join([posDevCert, posRandom])
    posDevCert = b"".join([posDevCert, termRandom])
    posDevCert = b"".join([posDevCert, termDID])
    posDevCert = b"".join([posDevCert, posDID])

    with open(posDevCertDecodedFile, "wb") as f:
        f.write(posDevCert)
        f.close()

    formattedPosSEK = bytearray(b'\x00\x01')
    for x in range(256 - 19):
        formattedPosSEK.append(255)
    formattedPosSEK.append(0)
    posSEK = ''.join([random.choice('0123456789ABCDEF') for x in range(32)])
    bposSEK = unhexlify(posSEK)
    formattedPosSEK = b"".join([formattedPosSEK, bposSEK])

    with open(posSEKDecodedFile, "wb") as f:
        f.write(bposSEK)
        f.close()

    with open(posSEKFormattedDecodedFile, "wb") as f:
        f.write(formattedPosSEK)
        f.close()

    log.log("Signing POS device certificate")
    opensslcmd = "openssl rsautl -sign -raw -inkey " + POSKey + " -in " + posDevCertDecodedFile + " -out " + posDevCertFile
    os.system(opensslcmd)
    if os.path.isfile(posDevCertFile):
        log.log("POS device certificate is signed")
        f = open(posDevCertFile, 'rb')
        posDevCertEnc = f.read()
        f.close()

    log.log("Encrypting POS stream encrytion key")
    log.loginfo("openssl rsautl -verify -raw -inkey " + TermPub +
                " -pubin -in " + posSEKFormattedDecodedFile + " -out " +
                posSEKFile)
    os.system("openssl rsautl -verify -raw -inkey " + TermPub +
              " -pubin -in " + posSEKFormattedDecodedFile + " -out " +
              posSEKFile)
    if os.path.isfile(posSEKFile):
        log.log("POS stream encrytion key is encrypted")
        f = open(posSEKFile, 'rb')
        formattedPosSEKEnc = f.read()
        if not len(formattedPosSEKEnc) > 0:
            raise (Except(
                "Restored random value messed up - there is nothing, check ssl command in log above for hand verification"
            ))
        f.close()

    f = open(posSEKDecodedFile, 'rb')
    poskey = bytearray(f.read())
    f.close()

    f = open(termSEKDecodedFile, 'rb')
    termkey = bytearray(f.read())
    f.close()

    for i in range(len(poskey)):
        termkey[i] ^= poskey[i]

    f = open(mutualSEKFile, 'wb')
    f.write(termkey)
    f.close()

    log.log("Mutual stream encryption key is saved: ", mutualSEKFile)
    ''' Send data '''
    c_tag = tagStorage()
    c_tag.store((0xDF, 0x83, 0x14), posDevCertEnc)
    c_tag.store((0xDF, 0x83, 0x15), formattedPosSEKEnc)

    log.log(str(c_tag.getTemplate(0xE0)))

    conn.send([0xDD, 0x22, 0x01, 0x00], c_tag.getTemplate(0xE0))
    status, buf, uns = conn.receive()
    util.check_status_error(status)
    log.loginfo("Success stream encryption keys auth done")
def Authenticate():
    termDevCert = os.path.join(CERT_DIR, "terminal_device_cert.enc")
    termDevCertDecoded = os.path.join(CERT_DIR, "terminal_device_cert.dec")
    posRandomFile = os.path.join(CERT_DIR, "pos.rnd")
    posDIDFile = os.path.join(CERT_DIR, "pos.did")
    termRandomFile = os.path.join(CERT_DIR, "term.rnd")
    termDIDFile = os.path.join(CERT_DIR, "term.did")
    termSEKFile = os.path.join(CERT_DIR, "term_sek.enc")
    termSEKFormattedDecodedFile = os.path.join(CERT_DIR,
                                               "term_sek_formatted.dec")
    termSEKDecodedFile = os.path.join(CERT_DIR, "term_sek.dec")

    posRandom = [0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78]
    posDID = [0x98, 0x76, 0x54, 0x32, 0x10, 0x98, 0x76, 0x54, 0x32, 0x10]

    posCertContent = ""
    if os.path.isfile(POSCert):
        log.loginfo("Using POSCert")
        with open(POSCert, 'r') as f:
            posCertContent = f.read()
    ''' Send data '''
    c_tag = tagStorage()
    c_tag.store((0xDF, 0x83, 0x13), posRandom)
    c_tag.store((0xDF, 0x83, 0x1A), posDID)
    if posCertContent:
        c_tag.store((0xDF, 0x83, 0x11), posCertContent)
    c_tag.store((0xDF, 0x83, 0x12), os.path.basename(POSCert))

    conn.send([0xDD, 0x21, 0x00, 0x00], c_tag.getTemplate(0xE0))
    status, buf, uns = conn.receive()
    util.check_status_error(status)
    tlv = TLVParser(buf)
    if (tlv.tagCount((0xDF, 0x83, 0x14)) == 1 and tlv.tagCount(
        (0xDF, 0x83, 0x1D)) == 1):
        encryptedDevCert = tlv.getTag((0xDF, 0x83, 0x14))[0]
        log.log("Signed Device certificate: ", hexlify(encryptedDevCert))

        clearRND = tlv.getTag((0xDF, 0x83, 0x1D))[0]
        log.log("Clear random number: ", hexlify(clearRND))

        log.log("Saving terminal device certificate: " + termDevCert)
        fTermDC = open(termDevCert, 'wb')
        fTermDC.write(encryptedDevCert)
        fTermDC.close()

        log.log("Saving POS random")
        fposRND = open(posRandomFile, 'wb')
        fposRND.write(bytearray(i for i in posRandom))
        fposRND.close()

        log.log("Saving POS DID")
        fposDID = open(posDIDFile, 'wb')
        fposDID.write(bytearray(i for i in posDID))
        fposDID.close()

        log.log("Decoding terminal device certificate")
        os.system("openssl rsautl -verify -raw -inkey " + TermPub +
                  " -pubin -in " + termDevCert + " -out " + termDevCertDecoded)
        if os.path.isfile(termDevCertDecoded):
            with open(termDevCertDecoded, "rb") as f:
                byte = f.read(2)
                log.log("byte start: ", hexlify(byte))
                byte = f.read(1)
                log.log("byte 3: ", byte)
                while byte == b'\xff':
                    byte = f.read(1)
                log.log("byte last: ", hexlify(byte))
                clearRNDRemote = f.read(8)
                RNDOwn = f.read(8)
                DIDOwn = f.read(10)
                DIDRemote = f.read(10)

            log.log("Clear random number REMOTE: ", hexlify(clearRNDRemote))
            if clearRND == clearRNDRemote:
                log.log("Random is validated")
                log.log("Saving term random")
                ftermRND = open(termRandomFile, 'wb')
                ftermRND.write(clearRNDRemote)
                ftermRND.close()
                log.log("Saving term DID")
                ftermDID = open(termDIDFile, 'wb')
                ftermDID.write(DIDRemote)
                ftermDID.close()
            else:
                log.log("Random is NOT validated")

    if (tlv.tagCount((0xDF, 0x83, 0x15)) == 1):
        encStreamEncKey = tlv.getTag((0xDF, 0x83, 0x15))[0]

        log.log("Saving terminal stream encryption key")
        fTermSEK = open(termSEKFile, 'wb')
        fTermSEK.write(encStreamEncKey)
        fTermSEK.close()

        log.log("Decoding terminal stream encryption key")
        opensslcmd = "openssl rsautl -sign -raw -inkey " + POSKey + " -in " + termSEKFile + " -out " + termSEKFormattedDecodedFile
        os.system(opensslcmd)
        if os.path.isfile(termSEKFormattedDecodedFile):
            log.log("Terminal SEK is decoded")
            with open(termSEKFormattedDecodedFile, "rb") as f:
                byte = f.read(2)
                log.log("byte start: ", hexlify(byte))
                byte = f.read(1)
                log.log("byte 3: ", byte)
                while byte == b'\xff':
                    byte = f.read(1)
                log.log("byte last: ", hexlify(byte))
                decStreamEncKey = f.read(16)

            log.log("Clear terminal SEK: ", hexlify(decStreamEncKey))
            log.log("Saving clear terminal stream encryption key")
            fTermSEK = open(termSEKDecodedFile, 'wb')
            fTermSEK.write(decStreamEncKey)
            fTermSEK.close()
Example #24
0
def OnlinePIN_IBM3624():
    """
    This script tests implementation of PIN IBM3624 with offset.
    1. The script establishes connection to VIPA
    2. Sends the data required for PIN validation, namely the PAN and offset.
    3. The customer enters the PIN on VIPA pinpad and the pinpad responds with the information wether PIN is correct or improper
    """
    amount = b'\x00\x00\x00\x00\x00\x00'
    pin = b'\x12\x34'
    pvk = b'\x79\x73\xc0\x90\x5a\xc3\xbe\x59\xd9\xf8\x53\x80\x53\x8a\x99\x3e'
    master_key = b'\x54\x9B\x6E\x13\xB5\x45\xA8\x7F\xA4\x32\x13\xF8\xE5\xBC\x85\x0D'
    kcv = b'\x1D\x85\xE5'
    padding_char = b'\x0F'
    pvk_enc = encrypt_pvk_with_master(master_key, kcv, pvk)
    #pin_block = ibm3624_pin_block_generation(pin, pvk, padding_char)
    log.log("amount is: ", hexlify(amount))
    log.log("Valid pin is: ", hexlify(pin))
    log.log("Secret PVK formely injected is:", hexlify(pvk))
    log.log("Encrypted PVK is:", hexlify(pvk_enc))

    #log.log("pin block is: ", hexlify(pin_block))
    ''' First create connection '''
    req_unsolicited = conn.connect()
    ''' If unsolicited read it'''
    if req_unsolicited:
        status, buf, uns = conn.receive()
        check_status_error(status)

    host_id = 9

    update_key_command(conn, host_id, pvk_enc)

    c_tag = tagStorage()
    #BUG: Unable to push the direct string not bytearray
    c_tag.store((0xDF, 0xEC, 0x05), 0x00)  # pin try flag
    c_tag.store((0xDF, 0xED, 0x05), 0x04)  # max pin length
    c_tag.store((0xDF, 0xED, 0x04), 0x04)  # min pin length
    c_tag.store((0xDF, 0xDF, 0x17), amount)
    # c_tag.store( (0xDF, 0xDF, 0x24), b'PLN') # currency code
    # c_tag.store( (0xDF, 0xDF, 0x1C), 2) # currency exponent
    c_tag.store((0xDF, 0xED, 0x08), 6)  # PIN_BLOCK_FORMAT_IBM3624
    #  c_tag.store( (0xDF, 0xED, 0x12), decim_table)
    c_tag.store((0xDF, 0xED, 0x12), b'\x0F')  #Now treat it as a padding.
    # c_tag.store( (0xDF, 0xED, 0x11), ibm3624_pin_offset)

    # c_tag.store( (0x5A), pan )
    conn.send([0xDE, 0xD6, host_id, 0x00], c_tag.getTemplate(0xE0))
    log.log("Verify IBM3624 pin sent")
    status, buf, uns = conn.receive()
    log.log("Received verification status")
    check_status_error(status)

    tlv = TLVParser(buf)

    if tlv.tagCount((0xDF, 0xED, 0x6C)) == 1:
        pin_block = tlv.getTag((0xDF, 0xED, 0x6C))[0]
        log.log("Pin block is: ", bytes(pin_block))
        log.log("PVK is: ", pvk.hex())
        entered_pin = decrypt_key(pvk, bytes(pin_block))
        log.log("Entered pin is: ", entered_pin.hex())
    else:
        log.log("No valid response from Vipa")
def transtest_function():
    log = getSyslog()
    conn = connection.Connection();
    #Create ssl server
    #conn.connect_tcp_server(timeout=30)
    #conn.connect_tcp_client('localhost',16107)
    #conn.connect_serial('COM1', 57600, timeout=2 );
    req_unsolicited = conn.connect()
    if req_unsolicited:
        #Receive unsolicited
        status, buf, uns = conn.receive()
        if status != 0x9000:
            log.logerr('Unsolicited fail')
            exit(-1)
        log.log('Unsolicited', TLVParser(buf) )
    #Send reset device
    conn.send([0xD2, 0x01, 0x01, 0x00])
    status, buf, uns = conn.receive()
    if status != 0x9000:
        log.logerr('reset fail')
        exit(-1)
    #Monitor card status
    conn.send([0xD0, 0x60, 0x01, 0x00])
    status, buf, uns = conn.receive()
    if status != 0x9000:
        log.logerr('Cardstatus fail')
        exit(-1)
    #print('CardStatus',TLVParser(buf))
    #Prompt for card
    conn.send([0xD2, 0x01, 0x0D, 0x00])
    status, buf, uns = conn.receive()
    if status != 0x9000:
        log.logerr('prompt card fail')
        exit(-1)
    #Short insert card notification
    log.log('**** WAIT FOR CARD INSERTION ****')
    status, buf, uns = conn.receive()
    if status != 0x9000 and not uns:
        log.logerr('Pinpad fail!!', hex(status),uns)
        exit(-1)
    tlv = TLVParser(buf)
    ins_tag_val = tlv.getTag(0x48, tlv.CONVERT_INT)
    if ins_tag_val[0]!=0x300:
        log.logerr('PINPAD FAILED tag 0x48 is', ins_tag_val)
        exit(-1)
    #Create localtag for transaction
    start_trans_tag = [
         [(0x9F, 0x02), b'\x00\x00\x00\x10\x04\x00' ],
         [(0x9A), b'\x04\x01\x01'],
         [(0x9C), b'\x00'],
         [(0x9F,0x21), b'\x01\x01\x01'],
         [(0x9F,0x41), b'\x00\x01' ],
         [(0x5F,0x2A), b'\x08\x26' ],
         [(0xDF,0xA2,0x18), b'\x00'],
         [(0xDF,0xA2,0x14), b'\x01'],
         [(0xDF,0xA2,0x04), b'\x01']
    ]
    start_templ = ( 0xE0, start_trans_tag )
    print(start_templ)
    #Start transaction
    conn.send([0xDE, 0xD1, 0x00, 0x00], start_templ)
    status, buf, uns = conn.receive()
    if status != 0x9000:
        log.logerr('Start transaction fail', hex(status), buf)
        exit(-1)
    #print(TLVParser(buf))
    #Continue transaction
    c_tag = tagStorage()
    c_tag.store( (0x9F,0x02), [0x00, 0x00, 0x00,0x00, 0x54, 0x00 ] )
    c_tag.store( (0x5F,0x2A), [0x09, 0x78] )
    c_tag.store(  0xC2, [0x30, 0x30] )
    c_tag.store( (0xDF,0xA2,0x18), 0x00 )
    c_tag.store( (0xDF,0xA3,0x07), [0x03,0xE8] )
    c_tag.store( 0xC0, 0x01 )
    c_tag.store( 0x8A, [0x59, 0x32 ] )
    c_tag.store( 0x91, [0x37,0xDD,0x29,0x75,0xC2,0xB6,0x68,0x2D,0x00,0x12] ) 

    #continue_tran_tag = [
    #    [ (0x9F,0x02), [0x00, 0x00, 0x00,0x00, 0x54, 0x00 ] ],
    #    [ (0x5F,0x2A), [0x09, 0x78] ],
    #    [ (0xC2), [0x30, 0x30] ],
    #    [ (0xDF,0xA2,0x18), [0x00] ],
    #    [ (0xDF,0xA3,0x07), [0x03,0xE8] ],
    #    [ (0xC0), [0x01] ],
    #    [ (0x8A), [0x59, 0x32 ] ],
    #    [ (0x91), [0x37,0xDD,0x29,0x75,0xC2,0xB6,0x68,0x2D,0x00,0x12] ]
    #]
    #continue_tpl = (0xE0, continue_tran_tag )
    #conn.send([0xDE, 0xD2, 0x00, 0x00], continue_tpl)
    conn.send( [0xDE, 0xD2, 0x00, 0x00], c_tag.getTemplate(0xE0) )

    status, buf, uns = conn.receive()
    if status != 0x9000:
        log.logerr('Continue transaction fail', hex(status), buf)
        exit(-1)
    #print(TLVParser(buf))
    log.log('*** PIN ENTRY WAIT ***')
    status, buf, uns = conn.receive()
    utility.check_status_error((status, buf, uns))
    tlv = TLVParser(buf)
    #print(tlv)
    if tlv.tagCount(0xE6) != 0:
        log.logerr('Not complete response wait again')
        status, buf, uns = conn.receive()
        if status != 0x9000:
            log.logerr('Pin entry wait #2', hex(status), buf)
            exit(-1)
    # Continue with positive response
    conn.send([0xDE, 0xD2, 0x00, 0x00])
    log.log('*** ONLINE REQUEST WAIT ***')
    status, buf, uns = conn.receive()
    if status != 0x9000:
        log.logerr('Online Request wait', hex(status), buf)
        exit(-1)
    #print(TLVParser(buf))
    #Remove card
    conn.send([0xD2, 0x01, 0x0E, 0x00])
    log.log('*** REMOVE CARD PROMPT***')
    status, buf, uns = conn.receive()
    if status != 0x9000:
        log.logerr('Remove card', hex(status), buf)
        exit(-1)
    log.log('*** REMOVE CARD WAIT ***')
    status, buf, uns = conn.receive()
    if status != 0x9000:
        log.logerr('Remove card wait', hex(status), buf)
        exit(-1)
    #Reset display
    conn.send([0xD2, 0x01, 0x01, 0x00])
    log.log('*** RESET DISPLAY ***')
    status, buf, uns = conn.receive()
    if status != 0x9000:
        log.logerr('Reset display wait', hex(status), buf)
        exit(-1)
    #Disconnect
    conn.send([0xD2, 0x01, 0x01, 0x00])
    log.log('*** DISCONNECT ***')
    status, buf, uns = conn.receive()
    if status != 0x9000:
        log.logerr('Disconnect wait', hex(status), buf)
        exit(-1)
Example #26
0
def OnlinePIN():
    ''' First create connection '''
    req_unsolicited = conn.connect()
    ''' If unsolicited read it'''
    if req_unsolicited:
        status, buf, uns = conn.receive()
        check_status_error(status)

    #host_id = 5;	# Alter from default of 2 to VSS Script index 2 (host_id=3)
    host_id = 2
    # Alter from default of 2 to VSS Script index 2 (host_id=3)
    ''' Send data '''

    pan = b'\x54\x13\x33\x00\x89\x00\x00\x39'
    amount = b'\x00\x00\x00\x01\x23\x00'
    c_tag = tagStorage()
    #BUG: Unable to push the direct string not bytearray
    c_tag.store((0xDF, 0xEC, 0x05), 0x00)  # pin try flag
    c_tag.store((0xDF, 0xED, 0x05), 0x08)  # max pin length
    c_tag.store((0xDF, 0xED, 0x04), 0x04)  # min pin length
    c_tag.store((0xDF, 0xDF, 0x17), amount)
    #    c_tag.store( (0xDF, 0xDF, 0x24), b'PLN')
    c_tag.store((0xDF, 0xDF, 0x24), (0x08, 0x26))
    c_tag.store((0xDF, 0xDF, 0x1C), 2)
    c_tag.store((0x5A), pan)
    conn.send([0xDE, 0xD6, host_id, 0x01], c_tag.getTemplate(0xE0))
    log.log("Get online PIN sent")
    log.log('*** PIN ENTRY WAIT ***')
    #    possible_cancel(conn,log,host_id)
    status, buf, uns = conn.receive()
    log.log("Get online PIN received")
    check_status_error(status)
    tlv = TLVParser(buf)
    if (tlv.tagCount((0xDF, 0xED, 0x6C)) == 1 and tlv.tagCount(
        (0xDF, 0xED, 0x03)) == 1):
        #encryptedPIN = tlv.getTag((0xDF, 0xED, 0x6C), TLVParser.CONVERT_HEX_STR)[0].upper()
        encryptedPIN = tlv.getTag((0xDF, 0xED, 0x6C))[0]
        ksn = tlv.getTag((0xDF, 0xED, 0x03),
                         TLVParser.CONVERT_HEX_STR)[0].upper()
        log.log("Encrypted PIN: ", hexlify(encryptedPIN))
        log.log("KSN: ", ksn)
        # We have KSN, let's find key
        keyTable = {
            'FFFF9876543210E00001': '042666B49184CF5C68DE9628D0397B36',
            'FFFF9876543210E00002': 'C46551CEF9FD244FAA9AD834130D3B38',
            'FFFF9876543210E00003': '0DF3D9422ACA561A47676D07AD6BAD05',
            'FFFF9876543210E00004': '279C0F6AEED0BE9A2B2C733E1383AE6E',
            'FFFF9876543210E00005': '5F8DC6D2C845C1DA508DDC048093B8C0',
            'FFFF9876543210E00006': '5E415CB0BAF9F0C3D0C14B63FB62FFBC',
            'FFFF9876543210E00007': '0C8F780B7C8B492FAE84A9EB2A6CE69F',
            'FFFF9876543210E00008': '27F66D5244FF621EAA6F6120EDEB427F',
            'FFFF9876543210E00009': '27E31064FDC565968900E2057F658E81',
            'FFFF9876543210E0000A': '6CF2500A22507C83C776CEADC1E330EB',
            'FFFF9876543210E0000B': '3E8260BA04B2D6DFC01482B3819A1848',
            'FFFF9876543210E0000C': 'B716E1E11CF53D7F726CAEE75C3A62B0',
            'FFFF9876543210E0000D': 'E072EDF9534053A0B6C581C58FBF25CC',
            'FFFF9876543210E0000E': 'A80046087F5B8FDB5AAD95E1842908B0',
            'FFFF9876543210E0000F': '93DD5B956C4878B82E453AAEFD32A555',
            'FFFF9876543210E00010': '59598DCBD9BD943F94165CE453585FA8',
            'FFFF9876543210E00011': '2B5F01F4F0CC0515639D523231BF1B5D',
            'FFFF9876543210E00012': '9CF640F279C2AE1915F725EEEAC2CB50',
            'FFFF9876543210E00013': 'C3DF489FDF11534BF03DE97C27DC4CD0',
            'FFFF9876543210E00014': '658488507721B30E4737FA93F923CB2D',
            'FFFF9876543210E00015': 'E161D1956A61F62DF37AFD7F9CC36965',
        }
        if not ksn in keyTable:
            raise exceptions.logicalException(
                "Cannot find key in static table - please inject Security keys again!!!"
            )
        key = keyTable[ksn]
        log.log("Key: ", key)
        #encryptedPIN = unhexlify(encryptedPIN)
        open("pin.dat", "wb").write(encryptedPIN)
        if os.path.isfile("pindec.dat"):
            os.remove("pindec.dat")

        vscmd = "openssl"
        #args = ' ' + "des-ede -nosalt -nopad -d -in pin.dat -out pindec.dat -k " + key
        args = ' ' + "des-ede -p -nosalt -nopad -d -in pin.dat -out pindec.dat -K " + key + " -iv 0000000000000000"
        log.log("calling openssl ", vscmd, ", params: ", args)
        if os.system(vscmd + args):
            raise exceptions.logicalException("Openssl call failed.")

        dec = open("pindec.dat", "rb").read()
        log.log("Decrypted PIN block: ", hexlify(dec))
        pinLen = dec[0] & 0x0F
        log.log("PIN length detected: ", pinLen)
        if (pinLen < 4 or pinLen > 12):
            raise exceptions.logicalException("Invalid PIN Block length!")
        if (pinLen % 2): pinLen += 1
        pinLen = (int)(pinLen / 2)

        #pan = bytearray(pan[-6:]) # Take last 12 PAN digits
        pan = bytearray(unhexlify((hexlify(bytearray(pan))[-13:])[:12]))
        pan.reverse()
        encodedPIN = bytearray(dec)
        encodedPIN.reverse()
        appendCnt = len(encodedPIN) - len(pan)
        #print('encoded pin: ', hexlify(encodedPIN))
        #print('pan: ', hexlify(pan))
        clearPIN = bytearray()
        for idx in range(len(pan)):
            #print('encpin val ', encodedPIN[idx], '; pan val ', pan[idx])
            val = encodedPIN[idx]
            val ^= pan[idx]
            clearPIN.append(val)

        encodedPIN.reverse()
        while (appendCnt > 0):
            appendCnt -= 1
            clearPIN.append(encodedPIN[appendCnt])
        clearPIN.reverse()
        log.log("PIN block: ", hexlify(clearPIN))
        clearPIN = clearPIN[1:pinLen + 1]
        PIN = str(hexlify(clearPIN)).replace("f", "")
        log.loginfo('PIN entered: ', PIN)
        os.remove("pin.dat")
        os.remove("pindec.dat")

    else:
        log.logerr("Invalid data!")