예제 #1
0
    def setUp(self):
        transport = config.TRANSPORT(*config.TRANSPORT_ARGS,
                                     **config.TRANSPORT_KWARGS)
        if hasattr(config, 'DEBUG_TRANSPORT'):
            debug_transport = config.DEBUG_TRANSPORT(
                *config.DEBUG_TRANSPORT_ARGS, **config.DEBUG_TRANSPORT_KWARGS)
            self.client = TrezorDebugClient(transport)
            self.client.set_debuglink(debug_transport)
        else:
            self.client = TrezorClient(transport)
        self.client.set_tx_api(tx_api.TxApiBitcoin)
        # self.client.set_buttonwait(3)

        #                     1      2     3    4      5      6      7     8      9    10    11    12
        self.mnemonic12 = 'alcohol woman abuse must during monitor noble actual mixed trade anger aisle'
        self.mnemonic18 = 'owner little vague addict embark decide pink prosper true fork panda embody mixture exchange choose canoe electric jewel'
        self.mnemonic24 = 'dignity pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic'
        self.mnemonic_all = ' '.join(['all'] * 12)

        self.pin4 = '1234'
        self.pin6 = '789456'
        self.pin8 = '45678978'

        self.client.wipe_device()

        print("Setup finished")
        print("--------------")
예제 #2
0
def choose_device(devices):
    if not len(devices):
        raise RuntimeError("No TREZOR connected!")

    if len(devices) == 1:
        try:
            return devices[0]
        except IOError:
            raise RuntimeError("Device is currently in use")

    i = 0
    sys.stderr.write("----------------------------\n")
    sys.stderr.write("Available devices:\n")
    for d in devices:
        try:
            client = TrezorClient(d, ui=ClickUI())
        except IOError:
            sys.stderr.write("[-] <device is currently in use>\n")
            continue

        if client.features.label:
            sys.stderr.write("[%d] %s\n" % (i, client.features.label))
        else:
            sys.stderr.write("[%d] <no label>\n" % i)
        client.close()
        i += 1

    sys.stderr.write("----------------------------\n")
    sys.stderr.write("Please choose device to use:")

    try:
        device_id = int(input())
        return devices[device_id]
    except Exception:
        raise ValueError("Invalid choice, exiting...")
예제 #3
0
    def setUp(self):
        transport = config.TRANSPORT(*config.TRANSPORT_ARGS, **config.TRANSPORT_KWARGS)
        if hasattr(config, 'DEBUG_TRANSPORT'):
            debug_transport = config.DEBUG_TRANSPORT(*config.DEBUG_TRANSPORT_ARGS, **config.DEBUG_TRANSPORT_KWARGS)
            self.client = TrezorDebugClient(transport)
            self.client.set_debuglink(debug_transport)
        else:
            self.client = TrezorClient(transport)
        self.client.set_tx_api(tx_api.TxApiBitcoin)
        # self.client.set_buttonwait(3)

        #                     1      2     3    4      5      6      7     8      9    10    11    12
        self.mnemonic12 = 'alcohol woman abuse must during monitor noble actual mixed trade anger aisle'
        self.mnemonic18 = 'owner little vague addict embark decide pink prosper true fork panda embody mixture exchange choose canoe electric jewel'
        self.mnemonic24 = 'dignity pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic'
        self.mnemonic_all = ' '.join(['all'] * 12)

        self.pin4 = '1234'
        self.pin6 = '789456'
        self.pin8 = '45678978'

        self.client.wipe_device()

        print("Setup finished")
        print("--------------")
예제 #4
0
def main():
    # List all debuggable TREZORs
    devices = [device for device in enumerate_devices() if hasattr(device, 'find_debug')]

    # Check whether we found any
    if len(devices) == 0:
        print('No TREZOR found')
        return

    # Use first connected device
    transport = devices[0]
    debug_transport = devices[0].find_debug()

    # Creates object for manipulating TREZOR
    client = TrezorClient(transport)
    debug = DebugLink(debug_transport)

    sector = int(sys.argv[1])
    f = open(sys.argv[2], "rb")
    content = f.read(sectorlens[sector])
    if (len(content) != sectorlens[sector]):
        print("Not enough bytes in file")
        return

    debug.flash_erase(sector)
    step = 0x400
    for offset in range(0, sectorlens[sector], step):
        debug.memory_write(sectoraddrs[sector] + offset, content[offset:offset + step], flash=True)
    client.close()
예제 #5
0
def Choose_device(devices):
    if not len(devices):
        raise Exception("No TREZOR connected!")

    if len(devices) == 1:
        try:
            return HidTransport(devices[0])
        except OSError:
            raise Exception("Device is currently in use, try reconnect the device")

    i = 0
    print("----------------------------\n")
    print("Available devices:\n")
    for d in devices:
        try:
            client = TrezorClient(d)
        except OSError:
            sys.stderr.write("[-] <device is currently in use>\n")
            continue

        if client.features.label:
            print("[%d] %s\n" % (i, client.features.label))
        else:
            print("[%d] <no label>\n" % i)
        client.close()
        i += 1
        

    print("----------------------------\n")

    try:
        device_id = int(input("Please choose device to use:"))
        return HidTransport(devices[device_id])
    except:
        raise Exception("Invalid choice, exiting...")
예제 #6
0
def get_tz_priv(coin, path):
    session_id = bytes.fromhex(environ.get('TZ_SESSIONID', ''))
    if trezor and len(session_id) == 32:
        device = get_transport()
        client = TrezorClient(transport=device,
                              ui=ClickUI(),
                              session_id=session_id)
        n_path = parse_path(
            "m/10065'/0'")  # Logical path for BIP0065 operation
        info = get_public_node(client, n_path, coin_name=coin)
        side, pubkey = (info.node.public_key[0], info.node.public_key[1:])
        left = True if side == 2 else False
        print("seed", b2x(pubkey), side)
        priv = encrypt_keyvalue(client,
                                n_path,
                                path,
                                pubkey,
                                ask_on_decrypt=side,
                                ask_on_encrypt=False)
        client.close()
        print("priv", b2x(priv), left)
        is_valid(priv)
        return CBitcoinSecret.from_secret_bytes(priv)
    else:
        print("trezorlib must be available")
        print("see: https://pypi.org/project/trezor/")
        print("TZ_SESSIONID enviroinment variable required")
        print("See: trezorctl get-session --help")
        sys.exit(2)
예제 #7
0
def decrypt(type, domain, secret):
    transport = get_transport()
    client = TrezorClient(transport, ClickUI())
    dom = type.upper() + ": " + domain
    dec = decrypt_keyvalue(client, BIP32_PATH, dom, secret, False, True)
    client.close()
    return dec
예제 #8
0
def Create_wallet_file():
    # create the clinet object
    devices = Wait_for_devices()
    transport = Choose_device(devices)
    client = TrezorClient(transport)
    
    
    # Label your wallet, something like 'lumen'.
    print('Please provide label for new drive: ')
    label = input()
    
    print('Computer asked TREZOR for new strong password.\n')
    print('Please confirm action on your device.\n')
    trezor_entropy = client.get_entropy(32)
    urandom_entropy = os.urandom(32)
    passw = hashlib.sha256(trezor_entropy + urandom_entropy).digest()
    
    if len(passw) != 32:
        raise Exception("32 bytes password expected")
        
    bip32_path = [10, 0]
    passw_encrypted = client.encrypt_keyvalue(bip32_path, label, passw, False, True)

    wallet_info = {'label': label,
            'bip32_path': bip32_path,
            'password_encrypted_hex': binascii.hexlify(passw_encrypted).decode(),
            'Address':Keypair.from_raw_seed(passw).address().decode()}
    
    #Store the wallet Information
    with open('Stellar_wallet.json', 'w') as fp:
        json.dump(wallet_info, fp)
        
    print('Please disconnect your Trezor hardware wallet.')
예제 #9
0
def main():
    # List all connected TREZORs on USB
    devices = HidTransport.enumerate()

    # Check whether we found any
    if len(devices) == 0:
        print('No TREZOR found')
        return

    # Use first connected device
    transport = devices[0]
    debug_transport = devices[0].find_debug()

    # Creates object for manipulating TREZOR
    client = TrezorClient(transport)
    debug = DebugLink(debug_transport)

    arg1 = int(sys.argv[1], 16)
    arg2 = int(sys.argv[2], 16)
    step = 0x400 if arg2 >= 0x400 else arg2

    f = open('memory.dat', 'wb')

    for addr in range(arg1, arg1 + arg2, step):
        mem = debug.memory_read(addr, step)
        f.write(mem)

    f.close()

    client.close()
예제 #10
0
def choose_device(devices: Sequence["Transport"]) -> "Transport":
    if not len(devices):
        raise RuntimeError("No Trezor connected!")

    if len(devices) == 1:
        try:
            return devices[0]
        except IOError:
            raise RuntimeError("Device is currently in use")

    i = 0
    sys.stderr.write("----------------------------\n")
    sys.stderr.write("Available devices:\n")
    for d in devices:
        try:
            client = TrezorClient(d, ui=ClickUI())
        except IOError:
            sys.stderr.write("[-] <device is currently in use>\n")
            continue

        if client.features.label:
            sys.stderr.write(f"[{i}] {client.features.label}\n")
        else:
            sys.stderr.write(f"[{i}] <no label>\n")
        client.close()
        i += 1

    sys.stderr.write("----------------------------\n")
    sys.stderr.write("Please choose device to use:")

    try:
        device_id = int(input())
        return devices[device_id]
    except Exception:
        raise ValueError("Invalid choice, exiting...")
def main():
    try:
        # List all connected TREZORs on USB
        devices = HidTransport.enumerate()

        # Check whether we found any
        if len(devices) == 0:
            input('No TREZOR found. Press any key...')
            return

        # Use first connected device
        transport = HidTransport(devices[0])

        # Creates object for manipulating TREZOR
        client = TrezorClient(transport)

        # Print out TREZOR's features and settings
        print(client.features)

        # # Get the first address of first BIP44 account
        # # (should be the same address as shown in wallet.trezor.io)
        # bip32_path = client.expand_path("44'/0'/0'/0/0")
        # address = client.get_address('Bitcoin', bip32_path)
        # print('Bitcoin address:', address)

        client.close()
        input('Press any key...')
    except Exception as e:
        print(str(e))
        traceback.print_exc(file=sys.stdout)
        input('Press any key...')
예제 #12
0
class TrezorIdentityProvider(IdentityProvider):
    def __init__(self, w3, index):
        self.w3 = w3
        self.client = TrezorClient(HidTransport.enumerate()[0])
        self.index = index
        self.address = self.w3.toChecksumAddress("0x" + bytes(
            self.client.ethereum_get_address([
                44 + bip32utils.BIP32_HARDEN, 60 +
                bip32utils.BIP32_HARDEN, bip32utils.BIP32_HARDEN, 0, index
            ])).hex())

    def get_address(self):
        return self.address

    def transact(self, transaction, out_f):
        print("Sending transaction to trezor for signature...\n", file=out_f)
        signature = self.client.ethereum_sign_tx(
            n=[
                44 + bip32utils.BIP32_HARDEN, 60 + bip32utils.BIP32_HARDEN,
                bip32utils.BIP32_HARDEN, 0, self.index
            ],
            nonce=transaction["nonce"],
            gas_price=transaction["gasPrice"],
            gas_limit=transaction["gas"],
            to=bytearray.fromhex(transaction["to"][2:]),
            value=transaction["value"],
            data=bytearray.fromhex(transaction["data"][2:]))

        transaction.pop("from")
        unsigned_transaction = serializable_unsigned_transaction_from_dict(
            transaction)
        raw_transaction = encode_transaction(unsigned_transaction,
                                             vrs=(signature[0],
                                                  int(signature[1].hex(), 16),
                                                  int(signature[2].hex(), 16)))

        print("Submitting transaction...\n", file=out_f)
        txn_hash = self.w3.eth.sendRawTransaction(raw_transaction)

        # Wait for transaction to be mined
        receipt = None
        while receipt is None:
            time.sleep(1)
            receipt = self.w3.eth.getTransactionReceipt(txn_hash)

        return receipt

    # Currently broken (see https://github.com/ethereum/go-ethereum/issues/14794)
    def sign_message(self, message, out_f):
        # n = self.client._convert_prime([44 + bip32utils.BIP32_HARDEN,
        #                                 60 + bip32utils.BIP32_HARDEN,
        #                                 bip32utils.BIP32_HARDEN,
        #                                 0,
        #                                 self.index])
        # print("Sending message to trezor for signature...\n", file=out_f)
        # return self.client.call(proto.EthereumSignMessage(address_n=n, message=web3.Web3.sha3(hexstr=message)))
        raise RuntimeError(
            "Trezor's dogmatic developers have chosen to break message signing compatibility with no "
            "security benefit to end users. Buy a ledger wallet here: https://www.ledgerwallet.com/"
        )
예제 #13
0
def main():
    # List all connected TREZORs on USB
    devices = HidTransport.enumerate()

    # Check whether we found any
    if len(devices) == 0:
        print 'No TREZOR found'
        return

    # Use first connected device
    transport = HidTransport(devices[0])

    # Creates object for manipulating TREZOR
    client = TrezorClient(transport)

    # Print out TREZOR's features and settings
    print client.features

    # Get the first address of first BIP44 account
    # (should be the same address as shown in mytrezor.com)
    bip32_path = client.expand_path("44'/0'/0'/0/0")
    address = client.get_address('Bitcoin', bip32_path)
    print 'Bitcoin address:', address

    client.close()
예제 #14
0
def decrypt(type, domain, secret):
    transport = get_transport()
    client = TrezorClient(transport, ClickUI())
    dom = type.upper() + ": " + domain
    dec = decrypt_keyvalue(client, BIP32_PATH, dom, secret, False, True)
    client.close()
    return dec
예제 #15
0
def encrypt(type, domain, secret):
    transport = get_transport()
    client = TrezorClient(transport, ClickUI())
    dom = type.upper() + ": " + domain
    enc = encrypt_keyvalue(client, BIP32_PATH, dom, secret.encode(), False, True)
    client.close()
    return enc.hex()
def choose_device(devices):
    if not len(devices):
        raise RuntimeError("No TREZOR connected!")

    if len(devices) == 1:
        try:
            return devices[0]
        except IOError:
            raise RuntimeError("Device is currently in use")

    i = 0
    sys.stderr.write("----------------------------\n")
    sys.stderr.write("Available devices:\n")
    for d in devices:
        try:
            client = TrezorClient(d)
        except IOError:
            sys.stderr.write("[-] <device is currently in use>\n")
            continue

        if client.features.label:
            sys.stderr.write("[%d] %s\n" % (i, client.features.label))
        else:
            sys.stderr.write("[%d] <no label>\n" % i)
        client.close()
        i += 1

    sys.stderr.write("----------------------------\n")
    sys.stderr.write("Please choose device to use:")

    try:
        device_id = int(input())
        return devices[device_id]
    except:
        raise ValueError("Invalid choice, exiting...")
예제 #17
0
class TrezorIdentityProvider(IdentityProvider):
    def __init__(self, w3, index):
        self.w3 = w3
        self.client = TrezorClient(HidTransport.enumerate()[0])
        self.index = index
        self.address = self.w3.toChecksumAddress("0x" + bytes(
            self.client.ethereum_get_address([
                44 + bip32utils.BIP32_HARDEN, 60 +
                bip32utils.BIP32_HARDEN, bip32utils.BIP32_HARDEN, 0, index
            ])).hex())

    def get_address(self):
        return self.address

    def transact(self, transaction, out_f):
        print("Sending transaction to trezor for signature...\n", file=out_f)
        signature = self.client.ethereum_sign_tx(
            n=[
                44 + bip32utils.BIP32_HARDEN, 60 + bip32utils.BIP32_HARDEN,
                bip32utils.BIP32_HARDEN, 0, self.index
            ],
            nonce=transaction["nonce"],
            gas_price=transaction["gasPrice"],
            gas_limit=transaction["gas"],
            to=bytearray.fromhex(transaction["to"][2:]),
            value=transaction["value"],
            data=bytearray.fromhex(transaction["data"][2:]))

        transaction.pop("from")
        unsigned_transaction = serializable_unsigned_transaction_from_dict(
            transaction)
        raw_transaction = encode_transaction(unsigned_transaction,
                                             vrs=(signature[0],
                                                  int(signature[1].hex(), 16),
                                                  int(signature[2].hex(), 16)))

        print("Submitting transaction...\n", file=out_f)
        txn_hash = self.w3.eth.sendRawTransaction(raw_transaction)

        # Wait for transaction to be mined
        receipt = None
        while receipt is None:
            time.sleep(1)
            receipt = self.w3.eth.getTransactionReceipt(txn_hash)

        return receipt

    def sign_message(self, message, out_f, agent_version=2):
        n = self.client._convert_prime([
            44 + bip32utils.BIP32_HARDEN, 60 + bip32utils.BIP32_HARDEN,
            bip32utils.BIP32_HARDEN, 0, self.index
        ])
        print("Sending message to trezor for signature...\n", file=out_f)
        if agent_version == 1:
            message = self.w3.sha3(hexstr=message)
        else:
            message = message.lower().encode("utf-8")
        return self.client.call(
            proto.EthereumSignMessage(address_n=n, message=message)).signature
def main():

    if 'encfs_root' not in os.environ:
        sys.stderr.write(
            '\nThis is not a standalone script and is not meant to be run independently.\n'
        )
        sys.stderr.write(
            '\nUsage: encfs --standard --extpass=./encfs_aes_getpass.py ~/.crypt ~/crypt\n'
        )
        sys.exit(1)

    devices = wait_for_devices()
    transport = choose_device(devices)
    client = TrezorClient(transport)

    rootdir = os.environ['encfs_root']  # Read "man encfs" for more
    passw_file = os.path.join(rootdir, 'password.dat')

    if not os.path.exists(passw_file):
        # New encfs drive, let's generate password

        sys.stderr.write('Please provide label for new drive: ')
        label = input()

        sys.stderr.write('Computer asked TREZOR for new strong password.\n')
        sys.stderr.write('Please confirm the action on your device ...\n')

        # 32 bytes, good for AES
        trezor_entropy = client.get_entropy(32)
        urandom_entropy = os.urandom(32)
        passw = hashlib.sha256(trezor_entropy + urandom_entropy).digest()

        if len(passw) != 32:
            raise ValueError("32 bytes password expected")

        bip32_path = [10, 0]
        passw_encrypted = client.encrypt_keyvalue(bip32_path, label, passw,
                                                  False, True)

        data = {
            'label':
            label,
            'bip32_path':
            bip32_path,
            'password_encrypted_hex':
            binascii.hexlify(passw_encrypted).decode('ascii')
        }

        json.dump(data, open(passw_file, 'w'))

    # Let's load password
    data = json.load(open(passw_file, 'r'))

    sys.stderr.write('Please confirm the action on your device ...\n')
    passw = client.decrypt_keyvalue(
        data['bip32_path'], data['label'],
        binascii.unhexlify(data['password_encrypted_hex']), False, True)

    print(passw)
예제 #19
0
def encrypt(type, domain, secret):
    transport = get_transport()
    client = TrezorClient(transport, ClickUI())
    dom = type.upper() + ": " + domain
    enc = encrypt_keyvalue(client, BIP32_PATH, dom, secret.encode(), False,
                           True)
    client.close()
    return enc.hex()
예제 #20
0
 def __init__(self, w3, index):
     self.w3 = w3
     self.client = TrezorClient(HidTransport.enumerate()[0])
     self.index = index
     self.address = self.w3.toChecksumAddress("0x" + bytes(
         self.client.ethereum_get_address(
             [44 + BIP32_HARDEN, 60 +
              BIP32_HARDEN, BIP32_HARDEN, 0, index])).hex())
예제 #21
0
    def __init__(self, transport, handler, plugin):
        self.client = TrezorClient(transport, ui=self)
        self.plugin = plugin
        self.device = plugin.device
        self.handler = handler

        self.msg = None
        self.creating_wallet = False

        self.in_flow = False

        self.used()
예제 #22
0
    def __init__(self, transport, handler, plugin):
        if plugin.is_outdated_fw_ignored():
            TrezorClient.is_outdated = lambda *args, **kwargs: False
        self.client = TrezorClient(transport, ui=self)
        self.plugin = plugin
        self.device = plugin.device
        self.handler = handler

        self.msg = None
        self.creating_wallet = False

        self.in_flow = False

        self.used()
예제 #23
0
def main():

    if not 'encfs_root' in os.environ:
        sys.stderr.write('\nThis is not a standalone script and is not meant to be run independently.\n')
        sys.stderr.write('\nUsage: encfs --standard --extpass=./encfs_aes_getpass.py ~/.crypt ~/crypt\n')
        sys.exit(1)

    devices = wait_for_devices()
    transport = choose_device(devices)
    client = TrezorClient(transport)

    rootdir = os.environ['encfs_root']  # Read "man encfs" for more
    passw_file = os.path.join(rootdir, 'password.dat')

    if not os.path.exists(passw_file):
        # New encfs drive, let's generate password

        sys.stderr.write('Please provide label for new drive: ')
        label = input()

        sys.stderr.write('Computer asked TREZOR for new strong password.\n')
        sys.stderr.write('Please confirm action on your device.\n')

        # 32 bytes, good for AES
        trezor_entropy = client.get_entropy(32)
        urandom_entropy = os.urandom(32)
        passw = hashlib.sha256(trezor_entropy + urandom_entropy).digest()

        if len(passw) != 32:
            raise Exception("32 bytes password expected")

        bip32_path = [10, 0]
        passw_encrypted = client.encrypt_keyvalue(bip32_path, label, passw, False, True)

        data = {'label': label,
                'bip32_path': bip32_path,
                'password_encrypted_hex': binascii.hexlify(passw_encrypted)}

        json.dump(data, open(passw_file, 'wb'))

    # Let's load password
    data = json.load(open(passw_file, 'r'))

    sys.stderr.write('Please confirm action on your device.\n')
    passw = client.decrypt_keyvalue(data['bip32_path'],
                                    data['label'],
                                    binascii.unhexlify(data['password_encrypted_hex']),
                                    False, True)

    print(passw)
예제 #24
0
def main():
    # List all connected TREZORs on USB
    devices = HidTransport.enumerate()

    # Check whether we found any
    if len(devices) == 0:
        print('No TREZOR found')
        return

    # Use first connected device
    transport = HidTransport(devices[0])

    # Creates object for manipulating TREZOR
    client = TrezorClient(transport)

    # Print out TREZOR's features and settings
    print(client.features)

    # Get the first address of first BIP44 account
    # (should be the same address as shown in wallet.trezor.io)
    bip32_path = client.expand_path("44'/42'/0'/0/0")
    address = client.get_address('Decred', bip32_path)
    print('Decred address:', address)

    address_n = client.expand_path("0")
    xpub = client.get_public_node('Decred', address_n)
    print('xpub: ', xpub)

    client.close()
예제 #25
0
def client():
    # pylint: disable=import-error
    from trezorlib.client import TrezorClient
    from trezorlib.transport_hid import HidTransport
    from trezorlib.messages_pb2 import PassphraseAck

    devices = list(HidTransport.enumerate())
    if len(devices) != 1:
        msg = '{:d} Trezor devices found'.format(len(devices))
        raise IOError(msg)

    t = TrezorClient(HidTransport(devices[0]))
    t.callback_PassphraseRequest = lambda msg: PassphraseAck(passphrase='')
    return t
예제 #26
0
    def __init__(self, path, password=''):
        super(TrezorClient, self).__init__(path, password)
        if path.startswith('udp'):
            logging.debug('Simulator found, using DebugLink')
            transport = get_transport(path)
            self.client = TrezorClientDebugLink(transport=transport)
        else:
            self.client = Trezor(transport=get_transport(path), ui=ClickUI())

        # if it wasn't able to find a client, throw an error
        if not self.client:
            raise IOError("no Device")

        self.password = password
        os.environ['PASSPHRASE'] = password
예제 #27
0
    def setUp(self):
        self.debug_transport = config.DEBUG_TRANSPORT(*config.DEBUG_TRANSPORT_ARGS, **config.DEBUG_TRANSPORT_KWARGS)
        self.transport = config.TRANSPORT(*config.TRANSPORT_ARGS, **config.TRANSPORT_KWARGS)
        self.client = TrezorClient(self.transport, DebugLink(self.debug_transport), debug=True)
        # self.client = TrezorClient(self.transport, debug=False)

        self.mnemonic1 = 'alcohol woman abuse must during monitor noble actual mixed trade anger aisle'
        self.mnemonic2 = 'owner little vague addict embark decide pink prosper true fork panda embody mixture exchange choose canoe electric jewel'
        self.pin1 = '1234'
        self.pin2 = '43211'

        self.client.setup_debuglink(button=True, pin_correct=True)
        
        self.client.wipe_device()
        self.client.load_device_by_mnemonic(
            mnemonic=self.mnemonic1,
            pin=self.pin1,
            passphrase_protection=False,
            label='test',
            language='english',
        )

        # self.client.apply_settings(label='unit testing', coin_shortcut='BTC', language='english')

        print "Setup finished"
        print "--------------"
예제 #28
0
def main():
    args = parse_args(Commands)

    if args.cmd == 'list':
        devices = list_usb()
        if args.json:
            print json.dumps(devices)
        else:
            for dev in devices:
                if dev[1] != None:
                    print "%s - debuglink enabled" % dev[0]
                else:
                    print dev[0]
        return

    transport = get_transport(args.transport, args.path)
    if args.verbose:
        client = TrezorClientDebug(transport)
    else:
        client = TrezorClient(transport)

    client.set_tx_api(TXAPIBitcoin())
    cmds = Commands(client)

    res = args.func(cmds, args)

    if args.json:
        print json.dumps(res, sort_keys=True, indent=4)
    else:
        print res
예제 #29
0
def get_all_clients(ui_factory=None):
    if ui_factory is None:
        ui_factory = ClickUI

    return [
        TrezorClient(device, ui_factory()) for device in enumerate_devices()
    ]
예제 #30
0
def main():
    client = TrezorClient(UdpTransport())

    masterKey = getMasterKey(client)
    # print('master key:', masterKey)

    fileName = getFileEncKey(masterKey)[0]
    # print('file name:', fileName)

    path = os.path.expanduser('~/Dropbox/Apps/TREZOR Password Manager/')
    # print('path to file:', path)

    encKey = getFileEncKey(masterKey)[2]
    # print('enckey:', encKey)

    jsonraw = decryptStorageRaw(sys.stdin, encKey)

    #sys.stdout.write(jsonraw)
    #return

    parsed_json = json.loads(jsonraw)
    entries = parsed_json['entries']
    decodeEntries(entries, client)
    sys.stdout.write(json.dumps(parsed_json, separators=(',', ':')))

    return
예제 #31
0
 def _connect(self):
     self.wirelink = get_transport(self.path)
     self.client = (
         TrezorClientDebugLink(self.wirelink)
         if self.debug
         else TrezorClient(self.wirelink, ui=ui.ClickUI())
     )
def main():

    if "encfs_root" not in os.environ:
        sys.stderr.write(
            "\nThis is not a standalone script and is not meant to be run independently.\n"
        )
        sys.stderr.write(
            "\nUsage: encfs --standard --extpass=./encfs_aes_getpass.py ~/.crypt ~/crypt\n"
        )
        sys.exit(1)

    devices = wait_for_devices()
    transport = choose_device(devices)
    client = TrezorClient(transport, ui=ClickUI())

    rootdir = os.environ["encfs_root"]  # Read "man encfs" for more
    passw_file = os.path.join(rootdir, "password.dat")

    if not os.path.exists(passw_file):
        # New encfs drive, let's generate password

        sys.stderr.write("Please provide label for new drive: ")
        label = input()

        sys.stderr.write("Computer asked Trezor for new strong password.\n")

        # 32 bytes, good for AES
        trezor_entropy = trezorlib.misc.get_entropy(client, 32)
        urandom_entropy = os.urandom(32)
        passw = hashlib.sha256(trezor_entropy + urandom_entropy).digest()

        if len(passw) != 32:
            raise ValueError("32 bytes password expected")

        bip32_path = [10, 0]
        passw_encrypted = trezorlib.misc.encrypt_keyvalue(
            client, bip32_path, label, passw, False, True
        )

        data = {
            "label": label,
            "bip32_path": bip32_path,
            "password_encrypted_hex": passw_encrypted.hex(),
        }

        json.dump(data, open(passw_file, "w"))

    # Let's load password
    data = json.load(open(passw_file, "r"))

    passw = trezorlib.misc.decrypt_keyvalue(
        client,
        data["bip32_path"],
        data["label"],
        bytes.fromhex(data["password_encrypted_hex"]),
        False,
        True,
    )

    print(passw)
예제 #33
0
 def initDevice(self):
     printDbg("Initializing Trezor")
     with self.lock:
         self.status = 0
         devices = enumerate_devices()
         if not len(devices):
             # No device connected
             return
         # Use the first device for now
         d = devices[0]
         ui = TrezorUi()
         try:
             self.client = TrezorClient(d, ui)
         except IOError:
             raise Exception("TREZOR device is currently in use")
         printOK("Trezor HW device connected [v. %s.%s.%s]" %
                 (self.client.features.major_version,
                  self.client.features.minor_version,
                  self.client.features.patch_version))
         self.status = 1
         model = self.client.features.model or "1"
         if not self.checkModel(model):
             self.status = 3
             self.messages[
                 3] = "Wrong device model (%s) detected.\nLooking for model %s." % (
                     HW_devices[self.model][0], model)
             return
         required_version = MINIMUM_FIRMWARE_VERSION[model]
         printDbg("Current version is %s (minimum required: %s)" %
                  (str(self.client.version), str(required_version)))
         # Check device is unlocked
         bip32_path = parse_path(MPATH + "%d'/0/%d" % (0, 0))
         _ = btc.get_address(self.client, 'PIVX', bip32_path, False)
         self.status = 2
예제 #34
0
def main():
    client = TrezorClient(UdpTransport())

    print()
    print('Confirm operation on TREZOR')
    print()

    masterKey = getMasterKey(client)
    # print('master key:', masterKey)

    fileName = getFileEncKey(masterKey)[0]
    # print('file name:', fileName)

    path = os.path.expanduser('~/Dropbox/Apps/TREZOR Password Manager/')
    # print('path to file:', path)

    encKey = getFileEncKey(masterKey)[2]
    # print('enckey:', encKey)

    full_path = path + fileName
    parsed_json = decryptStorage(full_path, encKey)

    # list entries
    entries = parsed_json['entries']
    printEntries(entries, client)

    return
def get_trezor_client() -> TrezorClient:
    """
    Wrapper to open connection to Trezor One

    Returns: 
        TrezorClient object
    """

    # List all connected TREZORs on USB
    devices = enumerate_devices()

    # Check whether we found any
    if len(devices) == 0:
        raise ConnectionError('No TREZOR found')

    # Use first connected device
    #transport = devices[0]

    transport = get_transport()

    ui = ClickUI()
    # Creates object for manipulating TREZOR
    client = TrezorClient(transport, ui)

    return client
예제 #36
0
def get_client():
    devices = HidTransport.enumerate()  # list all connected TREZORs on USB
    if len(devices) == 0:  # check whether we found any
        return None
    transport = HidTransport(devices[0])  # use first connected device
    return TrezorClient(
        transport)  # creates object for communicating with TREZOR
예제 #37
0
    def __init__(self, device, path):
        super(TrezorClient, self).__init__(device)
        device.close()
        self.client = Trezor(transport=get_transport("hid:" + path.decode()))

        # if it wasn't able to find a client, throw an error
        if not self.client:
            raise IOError("no Device")
예제 #38
0
def main():
    try:
        client = TrezorClient(get_transport(), ui=ui.ClickUI())
    except Exception as e:
        print(e)
        return

    arg1 = sys.argv[1]                     # output file
    arg2 = int(sys.argv[2], 10)            # total number of how many bytes of entropy to read
    step = 1024 if arg2 >= 1024 else arg2  # trezor will only return 1KB at a time

    with io.open(arg1, 'wb') as f:
        for i in range(0, arg2, step):
            entropy = misc.get_entropy(client, step)
            f.write(entropy)

    client.close()
예제 #39
0
 def __init__(self, w3, index):
     self.w3 = w3
     self.client = TrezorClient(HidTransport.enumerate()[0])
     self.index = index
     self.address = self.w3.toChecksumAddress(
         "0x" + bytes(self.client.ethereum_get_address([44 + BIP32_HARDEN,
                                                        60 + BIP32_HARDEN,
                                                        BIP32_HARDEN, 0,
                                                        index])).hex())
예제 #40
0
def main():
    # List all connected TREZORs on USB
    devices = HidTransport.enumerate()

    # Check whether we found any
    if len(devices) == 0:
        print('No TREZOR found')
        return

    # Use first connected device
    transport = HidTransport(devices[0])

    # Creates object for manipulating TREZOR
    debug_transport = HidTransport(devices[0], **{'debug_link': True})
    client = TrezorClient(transport)
    debug = DebugLink(debug_transport)

    mem = debug.memory_write(int(sys.argv[1],16), binascii.unhexlify(sys.argv[2]), flash=True)
    client.close()
예제 #41
0
class TrezorIdentityProvider(IdentityProvider):
    def __init__(self, w3, index):
        self.w3 = w3
        self.client = TrezorClient(HidTransport.enumerate()[0])
        self.index = index
        self.address = self.w3.toChecksumAddress(
            "0x" + bytes(self.client.ethereum_get_address([44 + BIP32_HARDEN,
                                                           60 + BIP32_HARDEN,
                                                           BIP32_HARDEN, 0,
                                                           index])).hex())

    def get_address(self):
        return self.address

    def transact(self, transaction, out_f):
        print("Sending transaction to trezor for signature...\n", file=out_f)
        signature = self.client.ethereum_sign_tx(n=[44 + BIP32_HARDEN, 60 + BIP32_HARDEN,
                                                    BIP32_HARDEN, 0, self.index],
                                                 nonce=transaction["nonce"],
                                                 gas_price=transaction["gasPrice"],
                                                 gas_limit=transaction["gas"],
                                                 to=bytearray.fromhex(
                                                     transaction["to"][2:]),
                                                 value=transaction["value"],
                                                 data=bytearray.fromhex(transaction["data"][2:]))

        transaction.pop("from")
        unsigned_transaction = serializable_unsigned_transaction_from_dict(
            transaction)
        raw_transaction = encode_transaction(unsigned_transaction,
                                             vrs=(signature[0],
                                                  int(signature[1].hex(), 16),
                                                  int(signature[2].hex(), 16)))
        return send_and_wait_for_transaction(raw_transaction, self.w3, out_f)

    def sign_message_after_soliditySha3(self, message):
        n = self.client._convert_prime([44 + BIP32_HARDEN,
                                        60 + BIP32_HARDEN,
                                        BIP32_HARDEN,
                                        0,
                                        self.index])
        return self.client.call(proto.EthereumSignMessage(address_n=n, message=message)).signature
예제 #42
0
    def __init__(self, transport, handler, plugin):
        self.client = TrezorClient(transport, ui=self)
        self.plugin = plugin
        self.device = plugin.device
        self.handler = handler

        self.msg = None
        self.creating_wallet = False

        self.in_flow = False

        self.used()
예제 #43
0
def main():
    # List all connected TREZORs on USB
    devices = HidTransport.enumerate()

    # Check whether we found any
    if len(devices) == 0:
        print('No TREZOR found')
        return

    # Use first connected device
    transport = HidTransport(devices[0])

    # Creates object for manipulating TREZOR
    debug_transport = HidTransport(devices[0], **{'debug_link': True})
    client = TrezorClient(transport)
    debug = DebugLink(debug_transport)

    mem = debug.memory_read(int(sys.argv[1],16), int(sys.argv[2],16))
    f = open('memory.dat', 'w')
    f.write(mem)
    f.close()

    client.close()
예제 #44
0
def main():
    args = parse_args(Commands)

    if args.cmd == 'list':
        devices = list_usb()
        if args.json:
            print json.dumps(devices)
        else:
            for dev in devices:
                if dev[1] != None:
                    print "%s - debuglink enabled" % dev[0]
                else:
                    print dev[0]
        return

    if args.debug:
        if args.debuglink_transport == 'usb' and args.debuglink_path == '':
            debuglink_transport = get_transport('usb', args.path, debug_link=True)
        else:
            debuglink_transport = get_transport(args.debuglink_transport,
                                        args.debuglink_path, debug_link=True)
        debuglink = DebugLink(debuglink_transport)    
    else:
        debuglink = None

    transport = get_transport(args.transport, args.path)
    client = TrezorClient(transport, pin_func=qt_pin_func, debuglink=debuglink)
    client.setup_debuglink(button=True, pin_correct=True)
    cmds = Commands(client)
    
    res = args.func(cmds, args)
    
    if args.json:
        print json.dumps(res, sort_keys=True, indent=4)
    else:
        print res
shell[len(shell) - 14] = ((getRootNode >> 16) & 0xff)
shell[len(shell) - 13] = ((getRootNode >> 24) & 0xff)

shell = str(shell)

print binascii.hexlify(shell)

DUMMY_SIZE = 500
SEQ = 0x01234567

SIG_DUMMY = shell
SIG_DUMMY += "\x63\xfd\x01\x20" * ((DUMMY_SIZE - len(shell)) / 4) # 1.2.0


devices = HidTransport.enumerate()
client = TrezorClient(HidTransport(devices[0]))

client.transport.session_begin()
tx = proto.SignTx()
tx.inputs_count = 1 
tx.outputs_count = 1 
tx.coin_name = "Bitcoin" 
res = client.call(tx)

if isinstance(res, proto.Failure):
    raise CallException("Signing failed")

if not isinstance(res, proto.TxRequest):
   raise CallException("Unexpected message")

print res
예제 #46
0
#!/usr/bin/env python2

from trezorlib.client import TrezorClient
from trezorlib.transport_hid import HidTransport
from binascii import hexlify, unhexlify

# for more details on this, see python-trezor
client = TrezorClient(HidTransport(HidTransport.enumerate()[0]))

bip32_path = client.expand_path("10015'/0'")
masterkey = client.encrypt_keyvalue(
    bip32_path,
    "Enable labeling?",
    unhexlify("fedcba98765432100123456789abcdeffedcba98765432100123456789abcdef"),
    True,
    True
)

print 'Key:', hexlify(masterkey)

예제 #47
0
class TrezorClientBase(Logger):
    def __init__(self, transport, handler, plugin):
        self.client = TrezorClient(transport, ui=self)
        self.plugin = plugin
        self.device = plugin.device
        self.handler = handler
        Logger.__init__(self)

        self.msg = None
        self.creating_wallet = False

        self.in_flow = False

        self.used()

    def run_flow(self, message=None, creating_wallet=False):
        if self.in_flow:
            raise RuntimeError("Overlapping call to run_flow")

        self.in_flow = True
        self.msg = message
        self.creating_wallet = creating_wallet
        self.prevent_timeouts()
        return self

    def end_flow(self):
        self.in_flow = False
        self.msg = None
        self.creating_wallet = False
        self.handler.finished()
        self.used()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.end_flow()
        if exc_value is not None:
            if issubclass(exc_type, Cancelled):
                raise UserCancelled from exc_value
            elif issubclass(exc_type, TrezorFailure):
                raise RuntimeError(str(exc_value)) from exc_value
            elif issubclass(exc_type, OutdatedFirmwareError):
                raise UserFacingException(exc_value) from exc_value
            else:
                return False
        return True

    @property
    def features(self):
        return self.client.features

    def __str__(self):
        return "%s/%s" % (self.label(), self.features.device_id)

    def label(self):
        '''The name given by the user to the device.'''
        return self.features.label

    def is_initialized(self):
        '''True if initialized, False if wiped.'''
        return self.features.initialized

    def is_pairable(self):
        return not self.features.bootloader_mode

    def has_usable_connection_with_device(self):
        if self.in_flow:
            return True

        try:
            res = self.client.ping("electrum pinging device")
            assert res == "electrum pinging device"
        except BaseException:
            return False
        return True

    def used(self):
        self.last_operation = time.time()

    def prevent_timeouts(self):
        self.last_operation = float('inf')

    def timeout(self, cutoff):
        '''Time out the client if the last operation was before cutoff.'''
        if self.last_operation < cutoff:
            self.logger.info("timed out")
            self.clear_session()

    def i4b(self, x):
        return pack('>I', x)

    def get_xpub(self, bip32_path, xtype, creating=False):
        address_n = parse_path(bip32_path)
        with self.run_flow(creating_wallet=creating):
            node = trezorlib.btc.get_public_node(self.client, address_n).node
        return BIP32Node(xtype=xtype,
                         eckey=ecc.ECPubkey(node.public_key),
                         chaincode=node.chain_code,
                         depth=node.depth,
                         fingerprint=self.i4b(node.fingerprint),
                         child_number=self.i4b(node.child_num)).to_xpub()

    def toggle_passphrase(self):
        if self.features.passphrase_protection:
            msg = _("Confirm on your {} device to disable passphrases")
        else:
            msg = _("Confirm on your {} device to enable passphrases")
        enabled = not self.features.passphrase_protection
        with self.run_flow(msg):
            trezorlib.device.apply_settings(self.client, use_passphrase=enabled)

    def change_label(self, label):
        with self.run_flow(_("Confirm the new label on your {} device")):
            trezorlib.device.apply_settings(self.client, label=label)

    def change_homescreen(self, homescreen):
        with self.run_flow(_("Confirm on your {} device to change your home screen")):
            trezorlib.device.apply_settings(self.client, homescreen=homescreen)

    def set_pin(self, remove):
        if remove:
            msg = _("Confirm on your {} device to disable PIN protection")
        elif self.features.pin_protection:
            msg = _("Confirm on your {} device to change your PIN")
        else:
            msg = _("Confirm on your {} device to set a PIN")
        with self.run_flow(msg):
            trezorlib.device.change_pin(self.client, remove)

    def clear_session(self):
        '''Clear the session to force pin (and passphrase if enabled)
        re-entry.  Does not leak exceptions.'''
        self.logger.info(f"clear session: {self}")
        self.prevent_timeouts()
        try:
            self.client.clear_session()
        except BaseException as e:
            # If the device was removed it has the same effect...
            self.logger.info(f"clear_session: ignoring error {e}")

    def close(self):
        '''Called when Our wallet was closed or the device removed.'''
        self.logger.info("closing client")
        self.clear_session()

    def is_uptodate(self):
        if self.client.is_outdated():
            return False
        return self.client.version >= self.plugin.minimum_firmware

    def get_trezor_model(self):
        """Returns '1' for Trezor One, 'T' for Trezor T."""
        return self.features.model

    def show_address(self, address_str, script_type, multisig=None):
        coin_name = self.plugin.get_coin_name()
        address_n = parse_path(address_str)
        with self.run_flow():
            return trezorlib.btc.get_address(
                self.client,
                coin_name,
                address_n,
                show_display=True,
                script_type=script_type,
                multisig=multisig)

    def sign_message(self, address_str, message):
        coin_name = self.plugin.get_coin_name()
        address_n = parse_path(address_str)
        with self.run_flow():
            return trezorlib.btc.sign_message(
                self.client,
                coin_name,
                address_n,
                message)

    def recover_device(self, recovery_type, *args, **kwargs):
        input_callback = self.mnemonic_callback(recovery_type)
        with self.run_flow():
            return trezorlib.device.recover(
                self.client,
                *args,
                input_callback=input_callback,
                type=recovery_type,
                **kwargs)

    # ========= Unmodified trezorlib methods =========

    def sign_tx(self, *args, **kwargs):
        with self.run_flow():
            return trezorlib.btc.sign_tx(self.client, *args, **kwargs)

    def reset_device(self, *args, **kwargs):
        with self.run_flow():
            return trezorlib.device.reset(self.client, *args, **kwargs)

    def wipe_device(self, *args, **kwargs):
        with self.run_flow():
            return trezorlib.device.wipe(self.client, *args, **kwargs)

    # ========= UI methods ==========

    def button_request(self, code):
        message = self.msg or MESSAGES.get(code) or MESSAGES['default']
        self.handler.show_message(message.format(self.device), self.client.cancel)

    def get_pin(self, code=None):
        if code == 2:
            msg = _("Enter a new PIN for your {}:")
        elif code == 3:
            msg = (_("Re-enter the new PIN for your {}.\n\n"
                     "NOTE: the positions of the numbers have changed!"))
        else:
            msg = _("Enter your current {} PIN:")
        pin = self.handler.get_pin(msg.format(self.device))
        if not pin:
            raise Cancelled
        if len(pin) > 9:
            self.handler.show_error(_('The PIN cannot be longer than 9 characters.'))
            raise Cancelled
        return pin

    def get_passphrase(self):
        if self.creating_wallet:
            msg = _("Enter a passphrase to generate this wallet.  Each time "
                    "you use this wallet your {} will prompt you for the "
                    "passphrase.  If you forget the passphrase you cannot "
                    "access the viacoins in the wallet.").format(self.device)
        else:
            msg = _("Enter the passphrase to unlock this wallet:")
        passphrase = self.handler.get_passphrase(msg, self.creating_wallet)
        if passphrase is None:
            raise Cancelled
        passphrase = bip39_normalize_passphrase(passphrase)
        length = len(passphrase)
        if length > 50:
            self.handler.show_error(_("Too long passphrase ({} > 50 chars).").format(length))
            raise Cancelled
        return passphrase

    def _matrix_char(self, matrix_type):
        num = 9 if matrix_type == WordRequestType.Matrix9 else 6
        char = self.handler.get_matrix(num)
        if char == 'x':
            raise Cancelled
        return char

    def mnemonic_callback(self, recovery_type):
        if recovery_type is None:
            return None

        if recovery_type == RecoveryDeviceType.Matrix:
            return self._matrix_char

        step = 0
        def word_callback(_ignored):
            nonlocal step
            step += 1
            msg = _("Step {}/24.  Enter seed word as explained on your {}:").format(step, self.device)
            word = self.handler.get_word(msg)
            if not word:
                raise Cancelled
            return word
        return word_callback
예제 #48
0
def main():
    numinputs = 600
    sizeinputtx = 10

    # List all connected TREZORs on USB
    devices = HidTransport.enumerate()

    # Check whether we found any
    if len(devices) == 0:
        print('No TREZOR found')
        return

    # Use first connected device
    print(devices[0][0])
#    transport = BridgeTransport(devices[0][0])
    transport = HidTransport(devices[0])

    txstore = MyTXAPIBitcoin()

    # Creates object for manipulating TREZOR
    client = TrezorClient(transport)
#    client.set_tx_api(TXAPITestnet())
    txstore.set_client(client)
    txstore.set_publickey(client.get_public_node(client.expand_path("44'/0'/0'")))
    print("creating input txs")
    txstore.create_inputs(numinputs, sizeinputtx)
    print("go")
    client.set_tx_api(txstore)
#    client.set_tx_api(MyTXAPIBitcoin())

    # Print out TREZOR's features and settings
    print(client.features)

    # Get the first address of first BIP44 account
    # (should be the same address as shown in mytrezor.com)

    outputs = [
        proto_types.TxOutputType(
            amount=0,
            script_type=proto_types.PAYTOADDRESS,
            address='p2xtZoXeX5X8BP8JfFhQK2nD3emtjch7UeFm'
#            op_return_data=binascii.unhexlify('2890770995194662774cd192ee383b805e9a066e6a456be037727649228fb7f6')
#            address_n=client.expand_path("44'/0'/0'/0/35"),
#            address='3PUxV6Cc4udQZQsJhArVUzvvVoKC8ohkAj',
        ),
#        proto_types.TxOutputType(
#            amount=0,
#            script_type=proto_types.PAYTOOPRETURN,
#            op_return_data=binascii.unhexlify('2890770995194662774cd192ee383b805e9a066e6a456be037727649228fb7f6')
#        ),
#        proto_types.TxOutputType(
#            amount= 8120,
#            script_type=proto_types.PAYTOADDRESS,
#            address_n=client.expand_path("44'/1'/0'/1/0"),
#            address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ',
#            address='14KRxYgFc7Se8j7MDdrK5PTNv8meq4GivK',
#        ),
#         proto_types.TxOutputType(
#             amount= 18684 - 2000,
#             script_type=proto_types.PAYTOADDRESS,
#             address_n=client.expand_path("44'/0'/0'/0/7"),
# #            address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ',
# #            address='1s9TSqr3PHZdXGrYws59Uaf5SPqavH43z',
#         ),
#         proto_types.TxOutputType(
#             amount= 1000,
#             script_type=proto_types.PAYTOADDRESS,
# #            address_n=client.expand_path("44'/0'/0'/0/18"),
# #            address='1PtCkQgyN6xHmXWzLmFFrDNA5vYhYLeNFZ',
#             address='1NcMqUvyWv1K3Zxwmx5sqfj7ZEmPCSdJFM',
#         ),
    ]

#    (signatures, serialized_tx) = client.sign_tx('Testnet', inputs, outputs)
    (signatures, serialized_tx) = client.sign_tx('Bitcoin', txstore.get_inputs(), txstore.get_outputs())
    print('Transaction:', binascii.hexlify(serialized_tx))

    client.close()