LedgerHQ / app-openpgp

OpenPGP Card Application
Apache License 2.0
122 stars 21 forks source link

It is ledger planning to fix Ed25519 curve? #95

Closed juan-sebastian closed 6 months ago

juan-sebastian commented 7 months ago

Hi, I have been waiting for years, and this is not an understatement, for Ledger to fix Ed25519 key pairs in Ledger version 2 and above. The issue is not in the openpgp app; the issue is in the firmware itself. Sadly, I would love to tackle this problem myself, but it is not possible without the proper internal tooling. The only workaround I have found so far is to keep one of my Ledger Nano S devices under version 2 firmware. Every time there is a new update in firmware 2, I hope that it is fixed. I know this is not under Ledger's priorities. But they need to understand that many people don't use Ledger hardware only as a crypto wallet but also as an authentication device. It would be great if it can be fixed. I don't think it is a big effort. Cedric used to fix this kind of error in a matter of days. Sadly, he does not work for the company anymore

For context:

Backing up my key from my ledger nano S firmware 1.6.1

$ python -m gpgcard.gpgcli --backup --pinpad --backup-keys --file gpg-backup.pickle

GPG Ledger Admin Tool v0.1.
Copyright 2018 Cedric Mesnil <cslashm@gmail.com>, Ledger SAS

Connect to card pcsc:Ledger...OK
Verfify PINs...OK
Select slot 1...OK
Get card info...OK
Backup application...OK

Restoring the key on my ledger nano X firmware 2.2.3

$ python -m gpgcard.gpgcli --restore --pinpad --file gpg-backup.pickle

GPG Ledger Admin Tool v0.1.
Copyright 2018 Cedric Mesnil <cslashm@gmail.com>, Ledger SAS

Connect to card pcsc:Ledger...OK
Verfify PINs...OK
Select slot 1...OK
Get card info...OK
Restore application...Error:
  (b'0000ff88', '6f42')

This only happens with a key pair Ed25519

I link below some of the issues I had opened in the past regarding this issue: https://github.com/LedgerHQ/openpgp-card-app/issues/58 https://github.com/LedgerHQ/openpgp-card-app/issues/61

cedelavergne-ledger commented 6 months ago

Hi, The backup/restore mechanism works with the latest v2.1 (still in develop branch). On ECC, the limitation we have is an error on cd25519 decrypt. Sign/Verify works well.

juan-sebastian commented 6 months ago

Hi @cedelavergne-ledger Thanks for the feed back. The new CLI don't seem to be working for me after following all the steps in the docs I am getting the following error:

$ ./gpgcli.py --help
Traceback (most recent call last):
  File "/Users/juan/perso/app-openpgp/pytools/./gpgcli.py", line 23, in <module>
    from gpgapp.gpgcard import GPGCard, GPGCardExcpetion
  File "/Users/juan/perso/app-openpgp/pytools/gpgapp/gpgcard.py", line 78, in <module>
    @dataclass
     ^^^^^^^^^
  File "/opt/homebrew/Cellar/python@3.11/3.11.7_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/dataclasses.py", line 1230, in dataclass
    return wrap(cls)
           ^^^^^^^^^
  File "/opt/homebrew/Cellar/python@3.11/3.11.7_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/dataclasses.py", line 1220, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/python@3.11/3.11.7_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/dataclasses.py", line 958, in _process_class
    cls_fields.append(_get_field(cls, name, type, kw_only))
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/python@3.11/3.11.7_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/dataclasses.py", line 815, in _get_field
    raise ValueError(f'mutable default {type(f.default)} for field '
ValueError: mutable default <class 'gpgapp.gpgcard.KeyInfo'> for field sig is not allowed: use default_factory
(venv)
$ ./backup.py --help
Traceback (most recent call last):
  File "/Users/juan/perso/app-openpgp/pytools/./backup.py", line 23, in <module>
    from gpgapp.gpgcard import GPGCard, PassWord, GPGCardExcpetion
  File "/Users/juan/perso/app-openpgp/pytools/gpgapp/gpgcard.py", line 78, in <module>
    @dataclass
     ^^^^^^^^^
  File "/opt/homebrew/Cellar/python@3.11/3.11.7_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/dataclasses.py", line 1230, in dataclass
    return wrap(cls)
           ^^^^^^^^^
  File "/opt/homebrew/Cellar/python@3.11/3.11.7_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/dataclasses.py", line 1220, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/python@3.11/3.11.7_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/dataclasses.py", line 958, in _process_class
    cls_fields.append(_get_field(cls, name, type, kw_only))
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/python@3.11/3.11.7_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/dataclasses.py", line 815, in _get_field
    raise ValueError(f'mutable default {type(f.default)} for field '
ValueError: mutable default <class 'gpgapp.gpgcard.KeyInfo'> for field sig is not allowed: use default_factory
(venv)

What I am missing?

juan-sebastian commented 6 months ago

Also my Key is not seeded, This solution will still work for me?

cedelavergne-ledger commented 6 months ago

Hi @juan-sebastian ,

Unfortunately, I never had such issue, and can't even reproduce it. On my side I have this configuration:

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.4 LTS
Release:    22.04
Codename:   jammy
$ uname -a
Linux LPFR0237 6.5.0-21-generic #21~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Feb  9 13:32:52 UTC 2 x86_64 x86_64 x86_64 GNU/Linux

$ python --version
Python 3.10.12

$ pip freeze
aniso8601==9.0.1
asn1crypto==1.5.1
attrs==23.2.0
bip_utils==2.9.2
blinker==1.7.0
cbor2==5.6.2
certifi==2024.2.2
cffi==1.16.0
charset-normalizer==3.3.2
click==8.1.7
coincurve==19.0.1
construct==2.10.70
crcmod==1.7
cryptography==42.0.5
ecdsa==0.18.0
ed25519-blake2b==1.4.1
exceptiongroup==1.2.0
Flask==2.3.3
Flask-RESTful==0.3.10
hidapi==0.14.0
idna==3.6
iniconfig==2.0.0
intelhex==2.3.0
itsdangerous==2.1.2
Jinja2==3.1.3
jsonschema==4.17.3
ledgerwallet==0.4.0
MarkupSafe==2.1.5
mnemonic==0.21
packaging==24.0
pillow==10.2.0
pluggy==1.4.0
protobuf==3.20.3
py-sr25519-bindings==0.2.0
pycparser==2.21
pycryptodome==3.20.0
pyelftools==0.30
PyNaCl==1.5.0
PyQt5==5.15.10
PyQt5-Qt5==5.15.2
PyQt5-sip==12.13.0
pyrsistent==0.20.0
pyscard==2.0.8
pytesseract==0.3.10
pytest==8.1.1
pytz==2024.1
ragger==1.15.0
requests==2.31.0
six==1.16.0
speculos==0.7.1
tabulate==0.9.0
toml==0.10.2
tomli==2.0.1
urllib3==2.2.1
Werkzeug==3.0.1