Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates for new Trezor and Ledger firmware #340

Merged
merged 17 commits into from
Jun 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions hwilib/cli.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
#! /usr/bin/env python3

from .commands import backup_device, displayaddress, enumerate, find_device, \
get_client, getmasterxpub, getxpub, getkeypool, getdescriptors, prompt_pin, toggle_passphrase, restore_device, send_pin, setup_device, \
signmessage, signtx, wipe_device, install_udev_rules
from .commands import (
backup_device,
displayaddress,
enumerate,
find_device,
get_client,
getmasterxpub,
getxpub,
getkeypool,
getdescriptors,
prompt_pin,
toggle_passphrase,
restore_device,
send_pin,
setup_device,
signmessage,
signtx,
wipe_device,
install_udev_rules,
)
from .errors import (
handle_errors,
DEVICE_CONN_ERROR,
HELP_TEXT,
MISSING_ARGUMENTS,
NO_DEVICE_TYPE,
UNAVAILABLE_ACTION
UNAVAILABLE_ACTION,
)
from . import __version__

Expand Down
6 changes: 5 additions & 1 deletion hwilib/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@

from .serializations import PSBT
from .base58 import xpub_to_pub_hex
from .errors import UnknownDeviceError, BAD_ARGUMENT, NOT_IMPLEMENTED
from .errors import (
UnknownDeviceError,
BAD_ARGUMENT,
NOT_IMPLEMENTED,
)
from .descriptor import Descriptor
from .devices import __all__ as all_devs
from enum import Enum
Expand Down
9 changes: 6 additions & 3 deletions hwilib/devices/btchip/btchip.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,10 @@ def startUntrustedTransaction(self, newTransaction, inputIndex, outputList, rede
apdu = [ self.BTCHIP_CLA, self.BTCHIP_INS_HASH_INPUT_START, 0x80, 0x00 ]
params = []
script = bytearray(redeemScript)
if ('witness' in passedOutput) and passedOutput['witness']:
params.append(0x02)
elif ('trustedInput' in passedOutput) and passedOutput['trustedInput']:
if ('trustedInput' in passedOutput) and passedOutput['trustedInput']:
params.append(0x01)
elif ('witness' in passedOutput) and passedOutput['witness']:
params.append(0x02)
else:
params.append(0x00)
if ('trustedInput' in passedOutput) and passedOutput['trustedInput']:
Expand Down Expand Up @@ -397,5 +397,8 @@ def getFirmwareVersion(self):
raise
result['compressedKeys'] = (response[0] == 0x01)
result['version'] = "%d.%d.%d" % (response[2], response[3], response[4])
result['major_version'] = response[2]
result['minor_version'] = response[3]
result['patch_version'] = response[4]
result['specialVersion'] = response[1]
return result
40 changes: 34 additions & 6 deletions hwilib/devices/coldcard.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,40 @@

from binascii import b2a_hex
from ..hwwclient import HardwareWalletClient
from ..errors import ActionCanceledError, BadArgumentError, DeviceBusyError, DeviceFailureError, UnavailableActionError, common_err_msgs, handle_errors
from .ckcc.client import ColdcardDevice, COINKITE_VID, CKCC_PID
from .ckcc.protocol import CCProtocolPacker, CCBusyError, CCProtoError, CCUserRefused
from .ckcc.constants import MAX_BLK_LEN, AF_P2WPKH, AF_CLASSIC, AF_P2WPKH_P2SH
from ..base58 import get_xpub_fingerprint, xpub_main_2_test
from ..serializations import ExtendedKey, PSBT
from ..errors import (
ActionCanceledError,
BadArgumentError,
DeviceBusyError,
DeviceFailureError,
UnavailableActionError,
common_err_msgs,
handle_errors,
)
from .ckcc.client import (
ColdcardDevice,
COINKITE_VID,
CKCC_PID,
)
from .ckcc.protocol import (
CCProtocolPacker,
CCBusyError,
CCProtoError,
CCUserRefused,
)
from .ckcc.constants import (
MAX_BLK_LEN,
AF_P2WPKH,
AF_CLASSIC,
AF_P2WPKH_P2SH,
)
from ..base58 import (
get_xpub_fingerprint,
xpub_main_2_test,
)
from ..serializations import (
ExtendedKey,
PSBT,
)
from hashlib import sha256

import base64
Expand Down
99 changes: 66 additions & 33 deletions hwilib/devices/digitalbitbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,37 @@
import time

from ..hwwclient import HardwareWalletClient
from ..errors import ActionCanceledError, BadArgumentError, DeviceFailureError, DeviceAlreadyInitError, DEVICE_NOT_INITIALIZED, DeviceNotReadyError, NoPasswordError, UnavailableActionError, common_err_msgs, handle_errors
from ..serializations import CTransaction, ExtendedKey, hash256, ser_sig_der, ser_sig_compact, ser_compact_size
from ..base58 import get_xpub_fingerprint, xpub_main_2_test

from ..errors import (
ActionCanceledError,
BadArgumentError,
DeviceFailureError,
DeviceAlreadyInitError,
DEVICE_NOT_INITIALIZED,
DeviceNotReadyError,
NoPasswordError,
UnavailableActionError,
common_err_msgs,
handle_errors,
)
from ..serializations import (
CTransaction,
ExtendedKey,
hash256,
is_p2pk,
is_p2pkh,
is_p2sh,
is_p2wpkh,
is_p2wsh,
is_witness,
ser_sig_der,
ser_sig_compact,
ser_string,
ser_compact_size,
)
from ..base58 import (
get_xpub_fingerprint,
xpub_main_2_test,
)
applen = 225280 # flash size minus bootloader length
chunksize = 8 * 512
usb_report_size = 64 # firmware > v2.0
Expand Down Expand Up @@ -345,18 +372,39 @@ def sign_tx(self, tx):
sighash_tuples = []
for txin, psbt_in, i_num in zip(blank_tx.vin, tx.inputs, range(len(blank_tx.vin))):
sighash = b""
utxo = None
if psbt_in.witness_utxo:
utxo = psbt_in.witness_utxo
if psbt_in.non_witness_utxo:
if txin.prevout.hash != psbt_in.non_witness_utxo.sha256:
raise BadArgumentError('Input {} has a non_witness_utxo with the wrong hash'.format(i_num))
utxo = psbt_in.non_witness_utxo.vout[txin.prevout.n]
if utxo is None:
continue
scriptcode = utxo.scriptPubKey

# Check if P2SH
p2sh = False
if is_p2sh(scriptcode):
# Look up redeemscript
if len(psbt_in.redeem_script) == 0:
continue
scriptcode = psbt_in.redeem_script
p2sh = True

is_wit, _, _ = is_witness(scriptcode)

# Check if P2WSH
if is_p2wsh(scriptcode):
# Look up witnessscript
if len(psbt_in.witness_script) == 0:
continue
scriptcode = psbt_in.witness_script

# Check if P2SH
if utxo.is_p2sh():
# Look up redeemscript
redeemscript = psbt_in.redeem_script
if not is_wit:
if p2sh or is_p2pkh(scriptcode) or is_p2pk(scriptcode):
# Add to blank_tx
txin.scriptSig = redeemscript
# Check if P2PKH
elif utxo.is_p2pkh() or utxo.is_p2pk():
txin.scriptSig = psbt_in.non_witness_utxo.vout[txin.prevout.n].scriptPubKey
txin.scriptSig = scriptcode
# We don't know what this is, skip it
else:
continue
Expand All @@ -368,7 +416,7 @@ def sign_tx(self, tx):
# Hash it
sighash += hash256(ser_tx)
txin.scriptSig = b""
elif psbt_in.witness_utxo:
else:
# Calculate hashPrevouts and hashSequence
prevouts_preimage = b""
sequence_preimage = b""
Expand All @@ -384,33 +432,18 @@ def sign_tx(self, tx):
outputs_preimage += output.serialize()
hashOutputs = hash256(outputs_preimage)

# Get the scriptCode
scriptCode = b""
witness_program = b""
if psbt_in.witness_utxo.is_p2sh():
# Look up redeemscript
redeemscript = psbt_in.redeem_script
witness_program = redeemscript
else:
witness_program = psbt_in.witness_utxo.scriptPubKey

# Check if witness_program is script hash
if len(witness_program) == 34 and witness_program[0] == 0x00 and witness_program[1] == 0x20:
# look up witnessscript and set as scriptCode
witnessscript = psbt_in.witness_script
scriptCode += ser_compact_size(len(witnessscript)) + witnessscript
else:
scriptCode += b"\x19\x76\xa9\x14"
scriptCode += witness_program[2:]
scriptCode += b"\x88\xac"
# Check if scriptcode is p2wpkh
if is_p2wpkh(scriptcode):
_, _, wit_prog = is_witness(scriptcode)
scriptcode = b"\x76\xa9\x14" + wit_prog + b"\x88\xac"

# Make sighash preimage
preimage = b""
preimage += struct.pack("<i", blank_tx.nVersion)
preimage += hashPrevouts
preimage += hashSequence
preimage += txin.prevout.serialize()
preimage += scriptCode
preimage += ser_string(scriptcode)
preimage += struct.pack("<q", psbt_in.witness_utxo.nValue)
preimage += struct.pack("<I", txin.nSequence)
preimage += hashOutputs
Expand Down
12 changes: 10 additions & 2 deletions hwilib/devices/keepkey.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
# KeepKey interaction script

from ..errors import DEVICE_NOT_INITIALIZED, DeviceNotReadyError, common_err_msgs, handle_errors
from .trezorlib.transport import enumerate_devices, KEEPKEY_VENDOR_IDS
from ..errors import (
DEVICE_NOT_INITIALIZED,
DeviceNotReadyError,
common_err_msgs,
handle_errors,
)
from .trezorlib.transport import (
enumerate_devices,
KEEPKEY_VENDOR_IDS,
)
from .trezor import TrezorClient

py_enumerate = enumerate # Need to use the enumerate built-in but there's another function already named that
Expand Down
Loading