Пример #1
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)
Пример #2
0
def chooseOneFromAIDList(aidList):
    text = ''
    itemCnt = 1
    for (adfName, AppLabel) in aidList:

        text += '\xDF\xA2\x02\01'
        text += chr(itemCnt)
        itemCnt += 1

        text += '\xDF\xA2\x03'
        text += chr(len(AppLabel))
        text += AppLabel.decode('ascii')
    log.log("chooseOneFromAIDList text options")

    conn.send([0xD2, 0x03, 0x00, 0x00], text)
    status, buf, uns = conn.receive()
    check_status_error(status)
    tlv = TLVParser(buf)
    itemNumber = tlv.getTag((0xDF, 0xA2, 0x02))
    itemNumber = itemNumber[0]  # get value of tag to bytearray
    itemNumber = int(
        itemNumber[0])  # get first element from bytearray and convert to int
    log.log("Chosen value is: ", itemNumber)
    if itemNumber > len(aidList):
        log.logerr("Returned choice value = ", itemNumber, " is out of bounds")
        return None
    itemIdx = itemNumber - 1
    log.log("This value maps to: ", aidList[itemIdx][0])
    return aidList[itemIdx][0]
def process_language(lang, is_list, is_user):
    req_unsolicited = conn.connect()
    if req_unsolicited:
        status, buf, uns = conn.receive()
        check_status_error(status)

    p1 = 0x00 if is_user else 0x01 if lang or is_list else 0x02
    p2 = 0x00 if is_list else 0x01
    conn.send([0xD2, 0xD0, p1, p2],
              [[(0xDF, 0xA2,
                 0x22), bytes(lang, encoding='utf-8')]] if lang else None)
    status, buf, uns = conn.receive()
    check_status_error(status)

    tlv = TLVParser(buf)
    languages = tlv.getTag((0xDF, 0xA2, 0x20))

    if lang: return

    if len(languages) == 0:
        log.logerr("No language returned")
        exit(1)

    log.log(
        "Available languages:" if is_list else
        "User selected language:" if is_user else "Current language:",
        ", ".join(l.decode('utf-8') for l in languages))
def get_certificates(is_return_file, level):
    req_unsolicited = conn.connect()
    if req_unsolicited:
        status, buf, uns = conn.receive()
        check_status_error(status)

    p1 = 0x01 if is_return_file else 0x00
    get_all_levels = level is None

    current_level = 0x00 if get_all_levels else level
    while True:
        conn.send([0xC5, 0x06, p1, 0x00], (0xE0, [
            [(0xDF, 0x83, 0x10),
             current_level.to_bytes(4, byteorder='big')],
        ]))
        status, buf, uns = conn.receive()
        if status == 0x9F13:
            log.log("No more certificates in the chain")
            break
        check_status_error(status)

        tlv = TLVParser(buf)
        certs = tlv.getTag((0xDF, 0x83,
                            0x12) if is_return_file else (0xDF, 0x83, 0x11))
        if len(certs) != 1:
            log.logerr("One return tag expected in response, got:", len(certs))
            exit(1)

        cert = certs[0].decode('utf-8')
        label = "file name: " if is_return_file else "content:\n"
        log.log("Certificate level %d %s%s" % (current_level, label, cert))

        if not get_all_levels: break
        current_level = current_level + 1
def dump_logs():
   ''' 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 )

   ''' Dump logs '''
   conn.send( [0xD0, 0x05, 0x00, P2_VIPA_LOG])
   ''' Receive and check '''
   status, buf, uns = conn.receive(30)
   check_status_error( status )
   tlv = TLVParser(buf)
   template = tlv.getTag((0x6F))
   filename = TLVParser(template).getTag((0x84))[0].decode('utf-8')
   localfile = filename.split('/')[-1];
   log.log('Log file on terminal: %s, downloading as %s' % (filename, localfile))

   ''' Retrieve log file '''
   progress = partial(utility.display_console_progress_bar, utility.get_terminal_width())
   fileops.getfile(conn, log, filename, localfile, progress)
def password_entry():
    req_unsolicited = conn.connect()
    if req_unsolicited:
        status, buf, uns = conn.receive()
        check_status_error(status)

    conn.send([0xD2, 0x01, 0x01, 0x00])  # Reset display
    status, buf, uns = conn.receive(3)
    check_status_error(status)

    conn.send(
        [0xD2, 0xF3, 0x00, 0x04],
        (
            0xE0,
            [
                [(0xDF, 0xB0, 0x05), (ENTRY_UPPER | ENTRY_LOWER).to_bytes(
                    4, byteorder='big')],  # entry modes
                [(0xDF, 0xB0, 0x06), (ENTRY_UPPER).to_bytes(4, byteorder='big')
                 ],  # initial entry mode
            ]))
    status, buf, uns = conn.receive()
    check_status_error(status)

    tlv = TLVParser(buf)
    password = tlv.getTag((0xDF, 0x83, 0x01))[0].decode('utf-8')
    log.log('Password entered:', password)
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'), ']') 
def checkEncryptedPAN(tlv):
    tokenTemplate = tlv.getTag((0xFF, 0x7C))
    if len(tokenTemplate) == 0: return

    parsed = TLVPrepare().parse_received_data(tokenTemplate[0] + b'\x90\x00')
    tokenTLV = TLVParser(parsed)
    encryptedPANblock = tokenTLV.getTag((0xDF, 0x83, 0x6F))
    if len(encryptedPANblock) == 0:
        log.log("Encrypted PAN block not found")
        return

    sha1len = 20
    encryptedlen = 128
    if len(encryptedPANblock[0]) != encryptedlen + sha1len:
        log.logerr("Invalid encrypted PAN length: %s, not %s"
            % (len(encryptedPANblock[0]), encryptedlen + sha1len))
    encryptedPAN = encryptedPANblock[0][ : encryptedlen]
    fingerprint = encryptedPANblock[0][-sha1len : ]
    strFingerprint = hexlify(fingerprint).decode('utf-8')
    log.log("Encrypted PAN:", hexlify(encryptedPAN).decode('utf-8'))
    global rsaPublicKeyFingerprint
    if rsaPublicKeyFingerprint != strFingerprint:
        log.logerr("RSA public key fingerprint does not match")
        log.logerr("Ours:", rsaPublicKeyFingerprint)
        log.logerr("Came:", strFingerprint)
        exit(1)
    else:
        log.log("RSA public key fingerprint OK:", strFingerprint)
    decryptedPAN = execute('openssl', 'rsautl', '-decrypt', '-inkey', RSA_PRIVATE_KEY,
        stdinput=encryptedPAN)
    log.log("Decrypted PAN:", decryptedPAN)
def openfile( conn, log, remote_fn, progress=None ):
    from struct import pack
    #conn.send( [0x00,0xC0,0x00,0x00], remote_fn.upper() )
    conn.send( [0x00,0xC0,0x00,0x80], remote_fn.upper() )
    status, buf, uns = conn.receive()
    if status != 0x9000:
        raise exc.invResponseException( 'Cannot select file ' + remote_fn , status )
    if progress!=None:
        log.loginfo( 'INFO: Binary stream data not included in log' )
        enable_logging = False
    else:
        enable_logging = True
    tlv = TLVParser(buf)
    fileSize = tlv.getTag(0x80, tlv.CONVERT_INT)[0]
    if fileSize == 0:
        raise exc.logicalException( 'File with name ' + remote_fn + " doesn't exists")
    fileChecksum = tlv.getTag(0x88)
    return fileChecksum
Пример #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'))
Пример #11
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'))
def resetDevice(P1=0x00, P2=0x00):
    log.log('resetDevice')
    conn.send([0xD0, P1, P2, 0x01])
    status, buf, uns = getAnswer()
    tlv = TLVParser(buf)
    tid = tlv.getTag((0x9F, 0x1e))
    if len(tid):
        tid = str(tid[0], 'iso8859-1')
        log.log('Terminal TID: ', tid)
    else:
        tid = ''
        log.logerr('Invalid TID (or cannot determine TID)!')
    return tid, status, buf, uns
Пример #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)
def startUpgrade():
    log.log('startUpgrade')
    conn.send([0xD0, 0x04, 0x00, 0x00])
    status, buf, uns = getAnswer(ignoreUnsolicited=False)
    if not uns:
        log.logerr('unsolicited response expected only')
    tlv = TLVParser(buf)
    tid = tlv.getTag((0x9F, 0x1e))
    if len(tid):
        tid = str(tid[0], 'iso8859-1')
        log.log('Terminal TID: ', tid)
    else:
        tid = ''
        log.logerr('Invalid TID (or cannot determine TID)!')
    return tid, status, buf, uns
def GenerateRSAKey():
    if not os.path.exists(CERT_DIR):
        os.makedirs(CERT_DIR)

    if query_yes_no("Gen new certs?", default="no"):
        CreateCACertificate(conn, log)
        CreatePOSCertificate(log)

    log.loginfo(
        "Mutual auth cert handshake, DD 23 can take a while ( ~10sec) ")
    ''' 0x08 1024 in ~ 10 sec '''
    ''' 0x08 2048 in ~ 1 min  '''
    ''' 0x10 4096 in~ 10 min  '''

    conn.send([0xDD, 0x23, 0x00, 0x00],
              (0xE0, [[(0xDF, 0x83, 0x1C), b'\x08\x00']]))
    status, buf, uns = conn.receive()
    util.check_status_error(status)

    tlv = TLVParser(buf)
    if (tlv.tagCount((0xDF, 0x83, 0x1B)) == 1):
        certSignReq = tlv.getTag((0xDF, 0x83, 0x1B))[0]
        strCSR = toascii(certSignReq)

        csrFile = os.path.join(CERT_DIR, "ped.csr")
        terminalCert = os.path.join(CERT_DIR, "ped.pem")

        log.log("Saving CSR")
        file = open(csrFile, 'w')
        file.write(strCSR)
        file.close()

        log.log("Signing terminal CSR + save in: ", terminalCert)
        os.system("openssl x509 -req -days 360 -in " + csrFile + " -CA " +
                  CACert + " -CAkey " + CAKey + " -CAcreateserial -out " +
                  terminalCert)
        ''' Retrieve public key from ped'''
        log.log("Extracting terminal public key from terminal certificate")
        os.system("openssl x509 -pubkey -noout -in " + terminalCert + "  > " +
                  TermPub)
        log.log("Terminal public key is extracted: " + TermPub +
                " sending signed terminal certificate to terminal")
        PutFile(conn, log, terminalCert, "ped.pem")
    else:
        log.logerror("Terminal response fialure")
        exit(1)
    log.loginfo("Key generation and upload success!")
Пример #16
0
def getfile(conn, log, remote_fn, local_fn=None, progress=None):
    from struct import pack
    conn.send([0x00, 0xA4, 0x04, 0x00], remote_fn.upper())
    status, buf, uns = conn.receive()
    if status != 0x9000:
        raise exc.invResponseException('Cannot select file ' + remote_fn,
                                       status)
    if progress != None:
        log.loginfo('INFO: Binary stream data not included in log')
        enable_logging = False
    else:
        enable_logging = True
    tlv = TLVParser(buf)
    fileSize = tlv.getTag(0x80, tlv.CONVERT_INT)[0]
    if fileSize == 0:
        raise exc.logicalException('File with name ' + remote_fn +
                                   " doesn't exists")
    now = strftime("%Y%m%d%H%M%S")
    if local_fn == None:
        local_fn = remote_fn + '_' + now
    packetLen = 248
    log.log('Downloading File', remote_fn, 'Length', fileSize, 'as localfile',
            local_fn)
    prevPercent = -1
    with open(local_fn, 'wb') as f:
        offset = 0
        while offset < fileSize:
            d1 = (offset & 0xFF)
            P2 = ((offset & 0xFF00) >> 8) & 0xFF
            P1 = ((offset & 0xFF0000) >> 16) & 0xFF
            P1 |= 0x80
            sendData = pack("B", d1)
            conn.send([0x00, 0xB0, P1, P2],
                      sendData,
                      log_packet=enable_logging)
            status, buf, uns = conn.receive_raw(log_packet=enable_logging)
            if status != 0x9000:
                raise exc.invResponseException('Error during get file', status)
            offset += len(buf)
            f.write(buf)
            if hasattr(progress, '__call__'):
                percent = round(offset / fileSize, 2)
                if percent != prevPercent: progress(percent)
                prevPercent = percent
    log.log('Download done')
    return local_fn
Пример #17
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 processGetSREDStatus():
    req_unsolicited = conn.connect()
    if req_unsolicited:
        #Receive unsolicited
        log.log('Waiting for unsolicited')
        #status, buf, uns = getAnswer(False)
        #log.log('Unsolicited', TLVParser(buf) )

    #Send reset device
    conn.send([0xDD, 0x20, 0x07, 0x00])
    status, buf, uns = getAnswer()
    tlv = TLVParser(buf)
    tid = tlv.getTag((0x9F, 0x1e))
    if len(tid): 
        tid = str(tid[0], 'iso8859-1')
        log.log('Terminal TID: ', tid)
    else: 
        tid = ''
        log.logerr('Invalid TID (or cannot determine TID)!')
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'), ']')
Пример #20
0
def getdata(tag):
    req_unsolicited = conn.connect()
    if req_unsolicited:
        status, buf, uns = conn.receive()
        check_status_error(status)

    conn.send([0x00, 0xCA, 0x00, 0x00], unhexlify(tag))
    status, buf, uns = conn.receive()
    check_status_error(status)

    tlv = TLVParser(buf)
    values = tlv.getTag(tuple(unhexlify(tag)))
    if len(values) == 0:
        log.logerr("No tag found:", tag)
        exit(1)

    log.log("Value for tag", tag, ":")
    log.log(" * hex:", hexlify(values[0]).decode('utf-8'))
    log.log(" * ascii:", values[0].decode('utf-8'))
    log.log(" * int:", int.from_bytes(values[0], byteorder='big', signed=True))
def processCardStatus():
    req_unsolicited = conn.connect()
    if req_unsolicited:
        #Receive unsolicited
        log.log('Waiting for unsolicited')

    #Send reset device
    conn.send([0xD0, 0x00, 0x00, 0x01])
    status, buf, uns = getAnswer()
    tlv = TLVParser(buf)
    tid = tlv.getTag((0x9F, 0x1e))
    if len(tid):
        tid = str(tid[0], 'iso8859-1')
        log.log('Terminal TID: ', tid)
    else:
        tid = ''
        log.logerr('Invalid TID (or cannot determine TID)!')

    #Send clear display
    conn.send([0xD2, 0x01, 0x01, 0x01])
    status, buf, uns = getAnswer()

    processMagstripeFallback(tid)
Пример #22
0
def __detect_chain_size(conn, log, chain):
    global __DETECTED_CHAIN_SIZE
    global __CHAIN_FORCED_DATA_SIZE
    packetSize = 248  # const
    if chain == CHAIN_FORCED:
        packetSize = __CHAIN_FORCED_DATA_SIZE
    elif chain == CHAIN_AUTODETECT:
        if __DETECTED_CHAIN_SIZE == 0:
            # Detect chain size
            conn.send([0xD0, 0x00, 0x00, 0x00])
            status, buf, uns = conn.receive()
            tlv = TLVParser(buf)
            if (tlv.tagCount((0xDF, 0xA2, 0x1D))):
                packetSize = tlv.getTag((0xDF, 0xA2, 0x1D),
                                        TLVParser.CONVERT_INT)[0]
                __DETECTED_CHAIN_SIZE = packetSize
            else:
                log.logerr(
                    "No packet size (DFA21D tag), assuming chained messages are not supported!"
                )
                __DETECTED_CHAIN_SIZE = 248
        else:
            packetSize = __DETECTED_CHAIN_SIZE
    return packetSize
Пример #23
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
Пример #24
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 processTransaction():
    req_unsolicited = conn.connect()
    if req_unsolicited:
        #Receive unsolicited
        log.log('Waiting for unsolicited')
        #status, buf, uns = getAnswer(False)
        #log.log('Unsolicited', TLVParser(buf) )

    #Send reset device
    conn.send([0xD0, 0x00, 0x00, 0x01])
    status, buf, uns = getAnswer()
    tlv = TLVParser(buf)
    tid = tlv.getTag((0x9F, 0x1e))
    if len(tid):
        tid = str(tid[0], 'iso8859-1')
        log.log('Terminal TID: ', tid)
    else:
        tid = ''
        log.logerr('Invalid TID (or cannot determine TID)!')

    #Send clear display
    conn.send([0xD2, 0x01, 0x01, 0x01])
    status, buf, uns = getAnswer()

    #Monitor card and keyboard status
    conn.send([0xD0, 0x60, 0x1D, 0x03])
    status, buf, uns = getAnswer(False)
    cardState = EMV_CARD_REMOVED
    if uns:
        # Check for insertion unsolicited message
        tlv = TLVParser(buf)
        if tlv.tagCount(0x48):
            cardState = EMVCardState(tlv)

    ctls = initContactless()
    if (cardState != EMV_CARD_INSERTED):
        if (ctls):
            # Start Contactless transaction
            start_ctls_tag = [
                [(0x9F, 0x02), b'\x00\x00\x00\x00\x01\x00'],
                [(0x9A), b'\x12\x01\x01'],
                [(0x9C), b'\x00'],
                [(0x9F, 0x21), b'\x01\x01\x01'],
                # [(0x9F,0x41), b'\x00\x01' ],
                [(0x5F, 0x2A), b'\x08\x26'],
                [(0x9F, 0x1A), b'\x08\x26']
            ]
            start_templ = (0xE0, start_ctls_tag)
            conn.send([0xC0, 0xA0, 0x01, 0x00], start_templ)
            log.log('Starting Contactless transaction')
            status, buf, uns = getAnswer()
        else:
            promptForCard()
        log.log('**** WAIT FOR CARD INSERTION / TAP / SWIPE ****')

        tranType = 0
        result = 0
        ignoreSwipe = False
        while True:
            status, buf, uns = getAnswer(False)  # Get unsolicited ONLY
            if uns:
                # Check for insertion unsolicited message
                tlv = TLVParser(buf)
                if tlv.tagCount(0x48):
                    cardState = EMVCardState(tlv)
                    magState = MagstripeCardState(tlv)
                    if ctls and (cardState == EMV_CARD_INSERTED
                                 or magState == MAGSTRIPE_TRACKS_AVAILABLE
                                 ):  # Ignore failed swipes
                        # Cancel Contactless first
                        log.log('Cancelling contactless')
                        conn.send([0xC0, 0xC0, 0x00, 0x00])
                        status, buf, uns = getAnswer()
                        status, buf, uns = getAnswer(
                            False
                        )  # Ignore unsolicited as the answer WILL BE unsolicited...
                    if cardState == EMV_CARD_INSERTED:
                        log.log("Card inserted, process EMV transaction!")
                        result = processEMV(tid)
                        tranType = 1
                        break
                    else:
                        if cardState == ERROR_UNKNOWN_CARD:
                            log.log('Unknown card type ')
                            continue
                    if not ignoreSwipe:
                        if magState == ERROR_UNKNOWN_CARD:
                            log.logerr(
                                'Swipe has failed, there are no tracks!')
                            continue
                        else:
                            if magState == MAGSTRIPE_TRACKS_AVAILABLE:
                                log.log('Card swiped!')
                                vspDecrypt(tlv, tid)
                                tranType = 2
                                break
                    log.log("Waiting for next occurrance!")
                    continue
                # Check for unsolicited keyboard status
                if tlv.tagCount((0xDF, 0xA2, 0x05)):
                    kbd_tag_val = tlv.getTag((0xDF, 0xA2, 0x05),
                                             TLVParser.CONVERT_INT)[0]
                    log.log("Keyboard status, keypress ", hex(kbd_tag_val),
                            'h')
                    continue
                if tlv.tagCount(0xE3) or tlv.tagCount(0xE5):
                    log.log("Approved contactless EMV transaction!")
                    # todo: vsp decrypt!
                    vspDecrypt(tlv, tid)
                    tranType = 4
                    break
                if tlv.tagCount(0xE7):
                    vspDecrypt(tlv, tid)
                    processCtlsContinue()
                    tranType = 3
                    break
                if tlv.tagCount(0xE4):
                    vspDecrypt(tlv, tid)
                    processCtlsContinue()
                    tranType = 5
                    break
                if status != 0x9000:
                    if status == 0x9F33:  # Fallforward to ICC / Swipe
                        promptForCard()
                        # No need to exit the loop - swipe is not active now
                        continue
                    else:
                        if status == 0x9F34:  # Fallforward to ICC only
                            promptForCard()
                            # No need to exit the loop - ctls is not active now, but we have to disable swipes
                            ignoreSwipe = True
                            continue
            log.logerr("Invalid packet detected, ignoring it!")
            print('E4: ', tlv.tagCount(0xE4))
            print(tlv)
    else:
        log.log("Card already inserted!")
        result = processEMV(tid)
        tranType = 1

    # After loop
    if tranType == 1:
        # If card still inserted, ask for removal
        conn.send([0xD0, 0x60, 0x01, 0x00])
        status, buf, uns = getAnswer(False)  # Get unsolicited
        tlv = TLVParser(buf)
        if EMVCardState(tlv) == EMV_CARD_INSERTED:
            log.log("Card inserted, asking to remove it")
            removeEMVCard()
    #Reset display - regardless of tx type
    conn.send([0xD2, 0x01, 0x01, 0x01])
    log.log('*** RESET DISPLAY ***')
    status, buf, uns = getAnswer()
def processEMV(tid):
    #Create localtag for transaction
    start_trans_tag = [
        [(0x9F, 0x02), b'\x00\x00\x00\x00\x50\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'\x00']  # Manual app selection!!
    ]
    start_templ = (0xE0, start_trans_tag)
    #Start transaction
    conn.send([0xDE, 0xD1, 0x00, 0x00], start_templ)
    while True:
        #sleep(1)
        #conn.send([0xD0, 0xFF, 0x00, 0x00])
        status, buf, uns = getEMVAnswer()
        if status != 0x9000:
            if status == 0x9F28:
                return processMagstripeFallback(tid)
            else:
                log.logerr('Transaction terminated with status ', hex(status))
                return -1
        if uns and status == 0x9000:
            tlv = TLVParser(buf)
            if tlv.tagCount(0xE6) != 0:
                log.log('Multi application card!')
                continue
            else:
                log.log('Ignoring unsolicited packet ', tlv)
                continue
        else:
            tlv = TLVParser(buf)
            if tlv.tagCount(0x50) > 1 and tlv.tagCount((0x9F, 0x06)) > 1:
                # This is app selection stuff
                appLabels = tlv.getTag(0x50)
                appAIDs = tlv.getTag((0x9F, 0x06))
                log.log('We have ', len(appLabels), ' applications')
                if len(appLabels) != len(appAIDs):
                    log.logerr('Invalid response: AID count ', len(appAIDs),
                               ' differs from Labels count ', len(appLabels))
                    exit(-1)
                for i in range(len(appLabels)):
                    log.log('App ', i + 1, ': AID ', hexlify(appAIDs[i]),
                            ', label ', str(appLabels[i]))
                sel = -1

                while True:
                    #sels = input('Choose one app: ')
                    #try:
                    #    sel = int(sels.strip())
                    #except:
                    #    print('invalid entry!!!')
                    #if sel > 0 and sel <= len(appLabels): break
                    #print(' Invalid selection, please pick valid number! ')
                    # Note: The below will work for up to 9 apps...
                    if kbhit():
                        try:
                            sel = ord(getch())
                        except:
                            print('invalid key!')
                        #log.log('key press ', sel)
                        if sel > 0x30 and sel <= 0x30 + len(appLabels):
                            sel -= 0x30  # to number (0 .. x)
                            break
                        elif sel == 27:
                            conn.send([0xD0, 0xFF, 0x00, 0x00])
                            status, buf, uns = getAnswer()
                            log.logerr('Transaction aborted')
                            return -1
                        print(' Invalid selection, please pick valid number! ')
                    if conn.is_data_avail():
                        status, buf, uns = getEMVAnswer()
                        if status != 0x9000:
                            log.logerr('Transaction terminated with status ',
                                       hex(status))
                            return -1
                        break
                if sel >= 0:
                    sel = sel - 1
                    log.log('Selected ', sel)
                    app_sel_tags = [[(0x50), bytearray(appLabels[sel])],
                                    [(0x9F, 0x06),
                                     bytearray(appAIDs[sel])]]
                    app_sel_templ = (0xE0, app_sel_tags)
                    conn.send([0xDE, 0xD2, 0x00, 0x00], app_sel_templ)
                    log.log('App selected, waiting for response...')
                    continue
            break

    #Let's check VSP
    tlv = TLVParser(buf)
    vspDecrypt(tlv, tid)

    #print(TLVParser(buf))
    #Continue transaction
    continue_tran_tag = [[(0x9F, 0x02), [0x00, 0x00, 0x00, 0x00, 0x54, 0x00]],
                         [(0x5F, 0x2A), [0x09, 0x78]], [(0xC2), [0x36, 0x35]],
                         [(0xDF, 0xA2, 0x18), [0x00]],
                         [(0xDF, 0xA3, 0x07), [0x03, 0xE8]], [(0xC0), [0x01]],
                         [(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)

    while True:
        status, buf, uns = getEMVAnswer()
        if status != 0x9000:
            log.logerr('Transaction terminated with status ', hex(status))
            return -1
        tlv = TLVParser(buf)
        if uns and status == 0x9000:
            #print(tlv)
            if tlv.tagCount(0xE6) != 0:
                log.log('PIN Entry is being performed, waiting again')
                print(
                    'PIN Entry, press \'A\' to abort, \'B\' to bypass or \'C\' to cancel'
                )
                while True:
                    #sleep(1)
                    validKey = False
                    if kbhit():
                        key = getch()
                        log.log('key press ', key)
                        if key == 'a' or key == 'A':
                            log.logerr('aborting')
                            conn.send([0xD0, 0xFF, 0x00, 0x00])
                            validKey = True
                        if key == 'b' or key == 'B':
                            log.logerr('bypassing')
                            conn.send([0xDE, 0xD5, 0xFF, 0x01])
                            validKey = True
                        if key == 'c' or key == 'C':
                            log.logerr('cancelling')
                            conn.send([0xDE, 0xD5, 0x00, 0x00])
                            validKey = True

                        if validKey:
                            status, buf, uns = getAnswer(
                                stopOnErrors=False
                            )  # Wait for confirmation, then break to wait for response
                            if status == 0x9000: break
                            else: continue
                        else:
                            continue
                    if conn.is_data_avail():
                        break
                continue
            else:
                log.log('Ignoring unsolicited packet ', tlv)
                continue
        else:
            if tlv.tagCount(0xE3):
                log.log("Transaction approved offline")
                return 1
            else:
                if tlv.tagCount(0xE5):
                    log.log("Transaction declined offline")
                    return 2
                else:
                    break

    # If we get here, we received Online Request. Continue with positive response.
    conn.send([0xDE, 0xD2, 0x00, 0x00])
    status, buf, uns = getEMVAnswer(
        True)  # Ignore unsolicited automatically here
    if status != 0x9000:
        log.logerr('Online Request has failed', hex(status))
        return -1
    tlv = TLVParser(buf)
    if tlv.tagCount(0xE3):
        log.log("Transaction approved")
        return 1
    if tlv.tagCount(0xE5):
        log.log("Transaction declined")
        return 2
    return 3
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)
Пример #28
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!")
Пример #29
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")
Пример #30
0
def elm_init_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()
    check_status_error(status)
    ''' Check VSP Status '''
    conn.send([0xDD, 0x00, 0x03, 0x00])
    status, buf, uns = conn.receive()
    check_status_error(status)
    tlv = TLVParser(buf)
    vsp_stat = tlv.getTag((0xDF, 0xA2, 0x30), TLVParser.CONVERT_INT)[0]
    log.log('VSP status ', vsp_stat)
    if vsp_stat != 0:
        log.log('VSP Detected')
        if vsp_stat == 1:
            log.log('VSP Not active')
        else:
            if vsp_stat == 2:
                log.log('VSP Active')
            else:
                log.logerr('Unknown status!')
                return False
        ''' Get VSP version '''
        vsp_version = tlv.getTag((0xDF, 0xA2, 0x32), TLVParser.CONVERT_STR)[0]
        log.log('VSP Version ', vsp_version)
        if (vsp_version[:2] == '4.'):
            log.log('ELM Detected!')
            ''' First of all, we need TID '''
            conn.send([0xD0, 0x00, 0x00, 0x01])
            status, buf, uns = conn.receive()
            tlv = TLVParser(buf)
            tid = tlv.getTag((0x9F, 0x1e))
            if len(tid):
                tid = str(tid[0], 'iso8859-1')
                log.log('Terminal TID: ', tid)
            else:
                tid = ''
                log.logerr('Invalid TID (or cannot determine TID)!')
                return False
            ''' Trying to enable it '''
            conn.send([0xDD, 0xC1, 0x00, 0x00])
            status, buf, uns = conn.receive()
            check_status_error(status)
            status, buf, uns = conn.receive()
            check_status_error(status)
            tlv = TLVParser(buf)
            t1 = tlv.getTag((0x5F, 0x21), TLVParser.CONVERT_STR)
            if len(t1): t1 = t1[0]
            else: t1 = ''
            t2 = tlv.getTag((0x5F, 0x22), TLVParser.CONVERT_STR)
            if len(t2): t2 = t2[0]
            else: t2 = ''
            if len(t1): log.log('T1: ', t1)
            if len(t2): log.log('T2: ', t2)

            try:
                enc = semtec.encryptor()
                enc.set_TID(tid)
            except exceptions.logicalException as exc:
                log.logerr('Cannot create decryptor object! Error ', exc)
                return False
            pan = ''
            expiry = ''
            try:
                pan_d, expiry_d, t1_d, t2_d = enc.decrypt(pan, expiry, t1, t2)
                log.log('Done ok')
            except exceptions.logicalException as exc:
                if not '909' in str(exc):
                    log.logerr('Advance DDK error ', exc)
                else:
                    log.log('VSP keys advanced on Host')
            return True
        else:
            log.logerr('Not ELM (Dogwood)')
            return False
    else:
        log.log('No VSP detected!')
        return False