Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
gruve-p committed Oct 10, 2024
2 parents 7003486 + 214e04d commit 2e44a08
Show file tree
Hide file tree
Showing 13 changed files with 144 additions and 13 deletions.
2 changes: 1 addition & 1 deletion contrib/android/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ RUN cd /opt \
&& /opt/venv/bin/python3 -m pip install --no-build-isolation --no-dependencies -e .

# install python-for-android
ENV P4A_CHECKOUT_COMMIT="7197c1c28409fbeebd8494093349a2bfd770526a"
ENV P4A_CHECKOUT_COMMIT="d4432ec8d07b8521465d6daddd55046fc0413599"
# ^ from branch electrum_20240930 (note: careful with force-pushing! see #8162)
RUN cd /opt \
&& git clone https://github.com/spesmilo/python-for-android \
Expand Down
8 changes: 8 additions & 0 deletions contrib/android/apkdiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
import sys
from zipfile import ZipFile


# FIXME it is possible to hide data in the apk signing block - and then the application
# can introspect itself at runtime and access that, even execute it as code... :/
# see https://source.android.com/docs/security/features/apksigning/v2#apk-signing-block
# https://android.izzysoft.de/articles/named/iod-scan-apkchecks
# https://github.com/obfusk/sigblock-code-poc
# I think if the app did this kind of introspection, that should be caught by code review,
# but still, note that with this current diff script it is possible to smuggle data in the apk.
class ApkDiff:
IGNORE_FILES = ["META-INF/MANIFEST.MF", "META-INF/CERT.RSA", "META-INF/CERT.SF"]

Expand Down
3 changes: 2 additions & 1 deletion electrum_grs/plugins/bitbox02/bitbox02.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import hid
from typing import TYPE_CHECKING, Dict, Tuple, Optional, List, Any, Callable

import electrum_ecc as ecc

from electrum_grs import bip32, constants
from electrum_grs.i18n import _
from electrum_grs.keystore import Hardware_KeyStore
Expand All @@ -18,7 +20,6 @@
from electrum_grs.bitcoin import OnchainOutputType

import electrum_grs.bitcoin as bitcoin
import electrum_grs.ecc as ecc

from ..hw_wallet import HW_PluginBase, HardwareClientBase, HardwareHandlerBase

Expand Down
3 changes: 2 additions & 1 deletion electrum_grs/plugins/digitalbitbox/digitalbitbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
import copy
from typing import TYPE_CHECKING, Optional

import electrum_ecc as ecc

from electrum_grs.crypto import sha256d, EncodeAES_bytes, DecodeAES_bytes, hmac_oneshot
from electrum_grs.bitcoin import public_key_to_p2pkh, usermessage_magic, verify_usermessage_with_address
from electrum_grs.bip32 import BIP32Node, convert_bip32_intpath_to_strpath, is_all_public_derivation
from electrum_grs.bip32 import normalize_bip32_derivation
from electrum_grs import descriptor
from electrum_grs import ecc
from electrum_grs.wallet import Standard_Wallet
from electrum_grs import constants
from electrum_grs.transaction import Transaction, PartialTransaction, PartialTxInput, Sighash
Expand Down
1 change: 1 addition & 0 deletions electrum_grs/plugins/hw_wallet/cmdline.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def get_passphrase(self, msg, confirm):

def get_pin(self, msg, *, show_strength=True):
t = {'a':'7', 'b':'8', 'c':'9', 'd':'4', 'e':'5', 'f':'6', 'g':'1', 'h':'2', 'i':'3'}
t.update({str(i): str(i) for i in range(1, 10)}) # sneakily also support numpad-conversion
print_stderr(msg)
print_stderr("a b c\nd e f\ng h i\n-----")
o = raw_input()
Expand Down
115 changes: 115 additions & 0 deletions electrum_grs/plugins/hw_wallet/trezor_qt_pinmatrix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# from https://github.com/trezor/trezor-firmware/blob/3f1d2059ca140788dab8726778f05cedbea20bc4/python/src/trezorlib/qt/pinmatrix.py
#
# This file is part of the Trezor project.
#
# Copyright (C) 2012-2022 SatoshiLabs and contributors
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License version 3
# as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the License along with this library.
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.

import math
from typing import Any

from PyQt6.QtCore import QRegularExpression, Qt
from PyQt6.QtGui import QRegularExpressionValidator
from PyQt6.QtWidgets import (
QGridLayout,
QHBoxLayout,
QLabel,
QLineEdit,
QPushButton,
QSizePolicy,
QVBoxLayout,
QWidget,
)



class PinButton(QPushButton):
def __init__(self, password: QLineEdit, encoded_value: int) -> None:
super(PinButton, self).__init__("?")
self.password = password
self.encoded_value = encoded_value

self.clicked.connect(self._pressed)

def _pressed(self) -> None:
self.password.setText(self.password.text() + str(self.encoded_value))
self.password.setFocus()


class PinMatrixWidget(QWidget):
"""
Displays widget with nine blank buttons and password box.
Encodes button clicks into sequence of numbers for passing
into PinAck messages of Trezor.
show_strength=True may be useful for entering new PIN
"""

def __init__(self, show_strength: bool = True, parent: Any = None) -> None:
super(PinMatrixWidget, self).__init__(parent)

self.password = QLineEdit()
self.password.setValidator(QRegularExpressionValidator(QRegularExpression("[1-9]+"), None))
self.password.setEchoMode(QLineEdit.EchoMode.Password)

self.password.textChanged.connect(self._password_changed)

self.strength = QLabel()
self.strength.setMinimumWidth(75)
self.strength.setAlignment(Qt.AlignmentFlag.AlignCenter)
self._set_strength(0)

grid = QGridLayout()
grid.setSpacing(0)
for y in range(3)[::-1]:
for x in range(3):
button = PinButton(self.password, x + y * 3 + 1)
button.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
button.setFocusPolicy(Qt.FocusPolicy.NoFocus)
grid.addWidget(button, 3 - y, x)

hbox = QHBoxLayout()
hbox.addWidget(self.password)
if show_strength:
hbox.addWidget(self.strength)

vbox = QVBoxLayout()
vbox.addLayout(grid)
vbox.addLayout(hbox)
self.setLayout(vbox)

def _set_strength(self, strength: float) -> None:
if strength < 3000:
self.strength.setText("weak")
self.strength.setStyleSheet("QLabel { color : #d00; }")
elif strength < 60000:
self.strength.setText("fine")
self.strength.setStyleSheet("QLabel { color : #db0; }")
elif strength < 360000:
self.strength.setText("strong")
self.strength.setStyleSheet("QLabel { color : #0a0; }")
else:
self.strength.setText("ULTIMATE")
self.strength.setStyleSheet("QLabel { color : #000; font-weight: bold;}")

def _password_changed(self, password: Any) -> None:
self._set_strength(self.get_strength())

def get_strength(self) -> float:
digits = len(set(str(self.password.text())))
strength = math.factorial(9) / math.factorial(9 - digits)
return strength

def get_value(self) -> str:
return self.password.text()
3 changes: 2 additions & 1 deletion electrum_grs/plugins/keepkey/clientbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
from struct import pack
from typing import Optional

from electrum_grs import ecc
import electrum_ecc as ecc

from electrum_grs.i18n import _
from electrum_grs.util import UserCancelled
from electrum_grs.keystore import bip39_normalize_passphrase
Expand Down
7 changes: 4 additions & 3 deletions electrum_grs/plugins/keepkey/qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
from electrum_grs.plugin import hook
from electrum_grs.logging import Logger

from ..hw_wallet.qt import QtHandlerBase, QtPluginBase
from ..hw_wallet.plugin import only_hook_if_libraries_available
from electrum.plugins.hw_wallet.qt import QtHandlerBase, QtPluginBase
from electrum.plugins.hw_wallet.trezor_qt_pinmatrix import PinMatrixWidget
from electrum.plugins.hw_wallet.plugin import only_hook_if_libraries_available

from .keepkey import KeepKeyPlugin, TIM_NEW, TIM_RECOVER, TIM_MNEMONIC, TIM_PRIVKEY

from electrum_grs.gui.qt.wizard.wallet import WCScriptAndDerivation, WCHWUnlock, WCHWXPub, WalletWizardComponent
Expand Down Expand Up @@ -318,7 +320,6 @@ def create_handler(self, window):

@classmethod
def pin_matrix_widget_class(self):
from keepkeylib.qt.pinmatrix import PinMatrixWidget
return PinMatrixWidget

@hook
Expand Down
2 changes: 1 addition & 1 deletion electrum_grs/plugins/ledger/qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def __init__(self, win):
self.auth_signal.connect(self.auth_dialog)

def word_dialog(self, msg):
response = QInputDialog.getText(self.top_level_window(), "Ledger Wallet Authentication", msg, QLineEdit.Password)
response = QInputDialog.getText(self.top_level_window(), "Ledger Wallet Authentication", msg, QLineEdit.EchoMode.Password)
if not response[1]:
self.word = None
else:
Expand Down
3 changes: 2 additions & 1 deletion electrum_grs/plugins/safe_t/clientbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
from struct import pack
from typing import Optional

from electrum_grs import ecc
import electrum_ecc as ecc

from electrum_grs.i18n import _
from electrum_grs.util import UserCancelled
from electrum_grs.keystore import bip39_normalize_passphrase
Expand Down
7 changes: 4 additions & 3 deletions electrum_grs/plugins/safe_t/qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
from electrum_grs.plugin import hook
from electrum_grs.logging import Logger

from ..hw_wallet.qt import QtHandlerBase, QtPluginBase
from ..hw_wallet.plugin import only_hook_if_libraries_available
from electrum.plugins.hw_wallet.qt import QtHandlerBase, QtPluginBase
from electrum.plugins.hw_wallet.trezor_qt_pinmatrix import PinMatrixWidget
from electrum.plugins.hw_wallet.plugin import only_hook_if_libraries_available

from .safe_t import SafeTPlugin, TIM_NEW, TIM_RECOVER, TIM_MNEMONIC, TIM_PRIVKEY

from electrum_grs.gui.qt.wizard.wallet import WCScriptAndDerivation, WCHWUnlock, WCHWXPub, WalletWizardComponent
Expand Down Expand Up @@ -194,7 +196,6 @@ def create_handler(self, window):

@classmethod
def pin_matrix_widget_class(self):
from safetlib.qt.pinmatrix import PinMatrixWidget
return PinMatrixWidget

@hook
Expand Down
2 changes: 1 addition & 1 deletion electrum_grs/plugins/trezor/qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from electrum_grs.keystore import ScriptTypeNotSupported

from electrum_grs.plugins.hw_wallet.qt import QtHandlerBase, QtPluginBase
from electrum_grs.plugins.hw_wallet.trezor_qt_pinmatrix import PinMatrixWidget
from electrum_grs.plugins.hw_wallet.plugin import only_hook_if_libraries_available, OutdatedHwFirmwareException

from electrum_grs.gui.qt.util import (WindowModalDialog, WWLabel, Buttons, CancelButton,
Expand Down Expand Up @@ -462,7 +463,6 @@ def create_handler(self, window):

@classmethod
def pin_matrix_widget_class(self):
from trezorlib.qt.pinmatrix import PinMatrixWidget
return PinMatrixWidget

@hook
Expand Down
1 change: 1 addition & 0 deletions run_electrum_grs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ def get_password_for_hw_device_encrypted_storage(plugins: 'Plugins') -> str:
devmgr = plugins.device_manager
try:
client = devmgr.client_by_id(device_info.device.id_)
client.handler = client.plugin.create_handler(None)
return client.get_password_for_storage_encryption()
except UserCancelled:
sys.exit(0)
Expand Down

0 comments on commit 2e44a08

Please sign in to comment.