Browse Source

ledger: fix compat with hw.1 - signing flow deadlocked

broke in 8a1b46d839ac24f77bfa5e3a1eed0cb7284b59eac5b685854c517f224c98dc44
patch-4
SomberNight 5 years ago
parent
commit
200f547a07
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 8
      electrum/plugins/ledger/auth2fa.py
  2. 16
      electrum/plugins/ledger/ledger.py
  3. 12
      electrum/plugins/ledger/qt.py

8
electrum/plugins/ledger/auth2fa.py

@ -1,4 +1,5 @@
import copy import copy
from typing import TYPE_CHECKING
from PyQt5.QtWidgets import (QDialog, QLineEdit, QTextEdit, QVBoxLayout, QLabel, from PyQt5.QtWidgets import (QDialog, QLineEdit, QTextEdit, QVBoxLayout, QLabel,
QWidget, QHBoxLayout, QComboBox) QWidget, QHBoxLayout, QComboBox)
@ -11,6 +12,9 @@ from electrum.i18n import _
from electrum import constants, bitcoin from electrum import constants, bitcoin
from electrum.logging import get_logger from electrum.logging import get_logger
if TYPE_CHECKING:
from .ledger import Ledger_Client
_logger = get_logger(__name__) _logger = get_logger(__name__)
@ -27,7 +31,7 @@ helpTxt = [_("Your Ledger Wallet wants to tell you a one-time PIN code.<br><br>"
] ]
class LedgerAuthDialog(QDialog): class LedgerAuthDialog(QDialog):
def __init__(self, handler, data): def __init__(self, handler, data, *, client: 'Ledger_Client'):
'''Ask user for 2nd factor authentication. Support text and security card methods. '''Ask user for 2nd factor authentication. Support text and security card methods.
Use last method from settings, but support downgrade. Use last method from settings, but support downgrade.
''' '''
@ -38,7 +42,7 @@ class LedgerAuthDialog(QDialog):
self.setMinimumWidth(650) self.setMinimumWidth(650)
self.setWindowTitle(_("Ledger Wallet Authentication")) self.setWindowTitle(_("Ledger Wallet Authentication"))
self.cfg = copy.deepcopy(self.handler.win.wallet.get_keystore().cfg) self.cfg = copy.deepcopy(self.handler.win.wallet.get_keystore().cfg)
self.dongle = self.handler.win.wallet.get_keystore().get_client().dongle self.dongle = client.dongleObject.dongle
self.pin = '' self.pin = ''
self.devmode = self.getDevice2FAMode() self.devmode = self.getDevice2FAMode()

16
electrum/plugins/ledger/ledger.py

@ -300,18 +300,20 @@ class Ledger_KeyStore(Hardware_KeyStore):
message = message.encode('utf8') message = message.encode('utf8')
message_hash = hashlib.sha256(message).hexdigest().upper() message_hash = hashlib.sha256(message).hexdigest().upper()
# prompt for the PIN before displaying the dialog if necessary # prompt for the PIN before displaying the dialog if necessary
client = self.get_client() client_ledger = self.get_client()
client_electrum = self.get_client_electrum()
address_path = self.get_derivation_prefix()[2:] + "/%d/%d"%sequence address_path = self.get_derivation_prefix()[2:] + "/%d/%d"%sequence
self.handler.show_message("Signing message ...\r\nMessage hash: "+message_hash) self.handler.show_message("Signing message ...\r\nMessage hash: "+message_hash)
try: try:
info = self.get_client().signMessagePrepare(address_path, message) info = client_ledger.signMessagePrepare(address_path, message)
pin = "" pin = ""
if info['confirmationNeeded']: if info['confirmationNeeded']:
pin = self.handler.get_auth( info ) # does the authenticate dialog and returns pin # do the authenticate dialog and get pin:
pin = self.handler.get_auth(info, client=client_electrum)
if not pin: if not pin:
raise UserWarning(_('Cancelled by user')) raise UserWarning(_('Cancelled by user'))
pin = str(pin).encode() pin = str(pin).encode()
signature = self.get_client().signMessageSign(pin) signature = client_ledger.signMessageSign(pin)
except BTChipException as e: except BTChipException as e:
if e.sw == 0x6a80: if e.sw == 0x6a80:
self.give_error("Unfortunately, this message cannot be signed by the Ledger wallet. Only alphanumerical messages shorter than 140 characters are supported. Please remove any extra characters (tab, carriage return) and retry.") self.give_error("Unfortunately, this message cannot be signed by the Ledger wallet. Only alphanumerical messages shorter than 140 characters are supported. Please remove any extra characters (tab, carriage return) and retry.")
@ -484,7 +486,8 @@ class Ledger_KeyStore(Hardware_KeyStore):
if outputData['confirmationNeeded']: if outputData['confirmationNeeded']:
outputData['address'] = output outputData['address'] = output
self.handler.finished() self.handler.finished()
pin = self.handler.get_auth( outputData ) # does the authenticate dialog and returns pin # do the authenticate dialog and get pin:
pin = self.handler.get_auth(outputData, client=client_electrum)
if not pin: if not pin:
raise UserWarning() raise UserWarning()
self.handler.show_message(_("Confirmed. Signing Transaction...")) self.handler.show_message(_("Confirmed. Signing Transaction..."))
@ -510,7 +513,8 @@ class Ledger_KeyStore(Hardware_KeyStore):
if outputData['confirmationNeeded']: if outputData['confirmationNeeded']:
outputData['address'] = output outputData['address'] = output
self.handler.finished() self.handler.finished()
pin = self.handler.get_auth( outputData ) # does the authenticate dialog and returns pin # do the authenticate dialog and get pin:
pin = self.handler.get_auth(outputData, client=client_electrum)
if not pin: if not pin:
raise UserWarning() raise UserWarning()
self.handler.show_message(_("Confirmed. Signing Transaction...")) self.handler.show_message(_("Confirmed. Signing Transaction..."))

12
electrum/plugins/ledger/qt.py

@ -8,7 +8,7 @@ from electrum.plugin import hook
from electrum.wallet import Standard_Wallet from electrum.wallet import Standard_Wallet
from electrum.gui.qt.util import WindowModalDialog from electrum.gui.qt.util import WindowModalDialog
from .ledger import LedgerPlugin from .ledger import LedgerPlugin, Ledger_Client
from ..hw_wallet.qt import QtHandlerBase, QtPluginBase from ..hw_wallet.qt import QtHandlerBase, QtPluginBase
from ..hw_wallet.plugin import only_hook_if_libraries_available from ..hw_wallet.plugin import only_hook_if_libraries_available
@ -33,7 +33,7 @@ class Plugin(LedgerPlugin, QtPluginBase):
class Ledger_Handler(QtHandlerBase): class Ledger_Handler(QtHandlerBase):
setup_signal = pyqtSignal() setup_signal = pyqtSignal()
auth_signal = pyqtSignal(object) auth_signal = pyqtSignal(object, object)
def __init__(self, win): def __init__(self, win):
super(Ledger_Handler, self).__init__(win, 'Ledger') super(Ledger_Handler, self).__init__(win, 'Ledger')
@ -56,20 +56,20 @@ class Ledger_Handler(QtHandlerBase):
vbox.addWidget(l) vbox.addWidget(l)
dialog.show() dialog.show()
def auth_dialog(self, data): def auth_dialog(self, data, client: 'Ledger_Client'):
try: try:
from .auth2fa import LedgerAuthDialog from .auth2fa import LedgerAuthDialog
except ImportError as e: except ImportError as e:
self.message_dialog(repr(e)) self.message_dialog(repr(e))
return return
dialog = LedgerAuthDialog(self, data) dialog = LedgerAuthDialog(self, data, client=client)
dialog.exec_() dialog.exec_()
self.word = dialog.pin self.word = dialog.pin
self.done.set() self.done.set()
def get_auth(self, data): def get_auth(self, data, *, client: 'Ledger_Client'):
self.done.clear() self.done.clear()
self.auth_signal.emit(data) self.auth_signal.emit(data, client)
self.done.wait() self.done.wait()
return self.word return self.word

Loading…
Cancel
Save