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

Add support for Satochip hardware wallet #5523

Closed
wants to merge 25 commits into from

Conversation

Toporin
Copy link
Contributor

@Toporin Toporin commented Jul 23, 2019

This is a pull request to add support for the Satochip hardware wallet.
The (optional) Satochip-2FA plugin allows to confirm transaction requests on a second android device.

The Satochip hardware wallet is based on a jacavard smartcard and is fully open-source.
The wallet is composed of a javacard applet (https://github.com/Toporin/SatochipApplet) that is to be loaded on the smartcard, and an Electrum client plugin (https://github.com/Toporin/electrum-satochip) that acts as the interface between the card and the network.

More info:
https://github.com/Toporin/ (official repository)
https://prezi.com/p/mpq-xhh3mxjl/satochip-gent-meetup/ (Slides from previous meetups in Belgium)

Alcofribas4 and others added 25 commits December 18, 2018 12:17
Basic Satochip plugin functionnal
No SegWit support yet
- parse segwit tx
- sign tx

Electrum-Satochip integration:
- store authentikey in (encrypted) storage
- Device setup: prompt for PIN & Seed
Check Satochip version for support via card_get_status()
* Refactor card_bip32_import_seed() and card_bip32_get_authentikey(): return authentikey instead of (response, sw1, sw2)
* New class UninitializedSeedError(Exception) thrown when device has no seed
…e) directly

remove debug comments and clean code a bit
# Conflicts:
#	contrib/build-osx/make_osx
#	contrib/build-osx/osx.spec
#	contrib/build-osx/package.sh
#	contrib/build-wine/build-electrum-git.sh
#	contrib/build-wine/build-secp256k1.sh
#	contrib/build-wine/build.sh
#	contrib/build-wine/deterministic.spec
#	contrib/build-wine/prepare-wine.sh
#	contrib/build-wine/sign.sh
#	contrib/build-wine/unsign.sh
#	contrib/deterministic-build/check_submodules.sh
#	contrib/deterministic-build/find_restricted_dependencies.py
#	contrib/freeze_packages.sh
#	contrib/make_apk
#	contrib/make_download
#	contrib/make_locale
#	contrib/make_packages
#	contrib/make_tgz
#	contrib/sign_packages
#	contrib/upload
#	electrum
#	electrum-env
#	gui/kivy/data/fonts/tron/License.txt
#	gui/kivy/data/fonts/tron/Readme.txt
#	lib/base_wizard.py
#	lib/crypto.py
#	lib/plugins.py
#	lib/ripemd.py
#	lib/wordlist/portuguese.txt
#	plugins/trezor/trezor.py
#	scripts/bip70
#	scripts/block_headers
#	scripts/estimate_fee
#	scripts/get_history
#	scripts/peers
#	scripts/servers
#	scripts/txradar
#	scripts/watch_address
#	setup.py

Signed-off-by: Baudoin <[email protected]>
various code cleaning,
set random PIN for unused pin/puk code
* card_get_status() returns number of pin/puk tries remaining
* PIN verification is refactored in card_verify_PIN()
Merge commit '87c596fa1d685b9365c26b9dfabe9c566f806ea0' into satochip

# Conflicts:
#	.gitignore
#	README.rst
#	contrib/build-linux/appimage/apprun.sh
#	contrib/build-linux/appimage/build.sh
#	contrib/build-osx/osx.spec
#	contrib/build-wine/build-electrum-git.sh
#	contrib/build-wine/deterministic.spec
#	contrib/build-wine/prepare-wine.sh
#	contrib/build_tools_util.sh
#	contrib/osx/make_osx
#	contrib/sign_version
#	electrum/base_wizard.py
#	electrum/plugin.py
#	icons.qrc
#	lib/crypto.py
In CardConnector.py:
- Encrypt/decrypt 2FA challenge/response for privacy
- erase PIN when card is removed

In Satochip.py:
- pairing with 2FA device using QR code
- if 2FA is enabled, tx signing requires response to challenge using hmac-sha1

New plugin in satochip_2FA folder: exchange challenge-response with 2FA device

Minor changes in TxParser.py, plugin.py
Merge remote-tracking branch 'upstream/master' into satochip

# Conflicts:
#	.gitignore
#	README.rst
#	contrib/build-wine/build-electrum-git.sh
#	contrib/build-wine/prepare-wine.sh
#	electrum/base_wizard.py
#	electrum/plugin.py
- contrib/build-wine/LICENCE
- contrib/build-wine/tmp/electrum/
- contrib/osx/package.sh~HEAD
Copy link
Member

@SomberNight SomberNight left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR.

Please try to clean up your changes. I've highlighted some examples.

GitHub does not let me comment on some files; so further remarks here:

  • electrum/electrum is a symlink; you seem to have removed and then re-added it? please clean history so git sees no change
  • file permissions were changed for several files. please undo these changes

README-electrum.rst Show resolved Hide resolved
.. image:: https://d322cqt584bo4o.cloudfront.net/electrum/localized.svg
:target: https://crowdin.com/project/electrum
:alt: Help translate Electrum online
This is a fork of Electrum modified for use with the Satochip Hardware Wallet. To use it, you need a device with the Satochip Javacard Applet installed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe undo changes in this file?? if you want a readme specific to your plugin, see e.g. https://github.com/spesmilo/electrum/blob/2a80f6a3ad1997762734b157a023f8dcd16f2f7f/electrum/plugins/coldcard/README.md

@@ -121,7 +125,7 @@ exe_standalone = EXE(
strip=None,
upx=False,
icon=home+'electrum/gui/icons/electrum.ico',
console=False)
console=True) #DebugSatochip True
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leftover by mistake??

@@ -134,7 +138,7 @@ exe_portable = EXE(
strip=None,
upx=False,
icon=home+'electrum/gui/icons/electrum.ico',
console=False)
console=True) #DebugSatochip True
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

#PYSCARD_SHA256=c63a87e4e7c87ce4c1299a1d8e0cae4e43f27451ca210f2c54f2dcd7467565c5
PYSCARD_FILENAME=pyscard-1.9.8-cp36-cp36m-win32.whl #python32-bits
PYSCARD_URL=https://ci.appveyor.com/api/buildjobs/j60tkykj6vh0ppiy/artifacts/dist%2Fpyscard-1.9.8-cp36-cp36m-win32.whl
PYSCARD_SHA256=4641b5db53fb3562671b7b7c685ddf8f715180e2809106fb2a9361dfad553b4b
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this not available on pypi/pip? i.e. https://pypi.org/project/pyscard/ ?
is the issue that they do not seem distribute a win32 wheel?
and we cannot build it ourselves?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The maintainer of the project does not provide official releases for Windows 32-bit apparently. Since the project is open-source, it should be possible to build it from sources but it looks quite complex (LudovicRousseau/pyscard#55). The link provided in the script comes from the appveyor account for pyscard (https://ci.appveyor.com/project/LudovicRousseau/pyscard), and is the suggested workaround provided by the maintainer (see LudovicRousseau/pyscard#55 (comment))

@@ -625,5 +625,5 @@ def scan_devices(self):
# Unpair disconnected devices
for id_ in disconnected_ids:
self.unpair_id(id_)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please clean

output is hex string in compact 65-byteformat
http://bitcoin.stackexchange.com/questions/12554/why-the-signature-is-always-65-13232-bytes-long
https://bitcointalk.org/index.php?topic=215205.0
'''
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try not to reimplement existing code. Please do something like this instead:

from electrum.ecc import sig_string_from_der_sig, construct_sig65
from electrum.util import bfh, bh2u

sig_string = sig_string_from_der_sig(bfh(sigin))
return bh2u(construct_sig65(sig_string, recid, compressed))


MSG_USE_2FA= _("Do you want to use 2-Factor-Authentication (2FA)?\n\nWith 2FA, any transaction must be confirmed on a second device such as your smartphone. First you have to install the Satochip-2FA android app on google play. Then you have to pair your 2FA device with your Satochip by scanning the qr-code on the next screen. Warning: be sure to backup a copy of the qr-code in a safe place, in case you have to reinstall the app!")

def bip32path2bytes(bip32path:str) -> (int, bytes):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please try to use existing functions instead of re-implementing them:

def convert_bip32_path_to_list_of_uint32(n: str) -> List[int]:

(and use e.g. int.to_bytes to convert the ints to bytes)

pass

def is_initialized(self):
_logger.info(f"[SatochipClient] is_initialized(): TODO - currently set to true!")#debugSatochip
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this really be logged?

strcmp= 'lower' if (v_applet<v_supported) else 'higher'
_logger.info(f"[SatochipPlugin] setup_device(): Satochip version={hex(v_applet)} Electrum supported version= {hex(v_supported)}")#debugSatochip
if (v_supported!=v_applet):
msg=_('The version of your Satochip (v{v_applet_maj:x}.{v_applet_min:x}) is {strcmp} than supported by Electrum (v{v_supported_maj:x}.{v_supported_min:x}). You should update Electrum to ensure correct function!').format(strcmp=strcmp, v_applet_maj=d["protocol_major_version"], v_applet_min=d["protocol_minor_version"], v_supported_maj=CardConnector.SATOCHIP_PROTOCOL_MAJOR_VERSION, v_supported_min=CardConnector.SATOCHIP_PROTOCOL_MINOR_VERSION)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_() translates/localizes strings
maybe split this up, and remove the named parameters inside the string, as this seems really error-prone to translators
Or alternatively, do not translate it.

@SomberNight SomberNight added the hw-generic related to hardware wallets, irrespective of manufacturer label Jul 23, 2019
@Toporin
Copy link
Contributor Author

Toporin commented Jul 24, 2019 via email

@SomberNight
Copy link
Member

I also noticed that the Travis CI check failed due to the
Test_CardConnector.py file.

The failure is due to the smartcard module not being installed.
Your requirements should be specified in contrib/requirements-hw.txt. This should be done irrespective of whether the test file is kept.

If that test requires the hardware to be present, maybe it should be made conditional somehow, or it can just be excluded from the tests run by travis.

Toporin added a commit to Toporin/electrum-satochip that referenced this pull request Jul 27, 2019
Toporin added a commit to Toporin/electrum-satochip that referenced this pull request Jul 27, 2019
- removed README-electrum.rst
- undo changes to README.rst
- removed debug traces in contrib/build-wine/deterministic.spec
- add pyscard in contrib/requirements/requirements-hw.txt
Toporin added a commit to Toporin/electrum-satochip that referenced this pull request Jul 27, 2019
- removed README-electrum.rst
- undo changes to README.rst
- removed debug traces in contrib/build-wine/deterministic.spec
- add pyscard in contrib/requirements/requirements-hw.txt
@Toporin
Copy link
Contributor Author

Toporin commented Jul 27, 2019

Hello,

I introduced a new pull request from a dedicated branch and incorporating your suggestions: see #5533.

@Toporin Toporin closed this Jul 27, 2019
Toporin added a commit to Toporin/electrum-satochip that referenced this pull request Oct 4, 2019
Merge branch 'Electrum-Satochip-v3.3.8-0.7' into satochip:
    - removed README-electrum.rst
    - undo changes to README.rst
    - removed debug traces in contrib/build-wine/deterministic.spec
    - add pyscard in contrib/requirements/requirements-hw.txt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hw-generic related to hardware wallets, irrespective of manufacturer
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants