LedgerHQ / app-openpgp

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

Seed mode ON generate random keys #8

Closed nyanloutre closed 7 years ago

nyanloutre commented 7 years ago

I tried multiple times on different computers and got random keys instead of seed keys.

They may be a bug in the app (version 1.1.0) which does not generate private keys from the seed.

I will try to rollback to 1.0.1 which worked properly.

cslashm commented 7 years ago

Hi, thanks for reporting. I will check that by the end of week.

cslashm commented 7 years ago

Ok, the problem comes from the fingerprints. The seed mode generate the same key value, I tried with

The RSA pub key is the same, but fingerprints differs. Why? because the fingerprints V4 includes the timestamps key creation (no comment). See https://tools.ietf.org/html/rfc4880#section-12.2

Moreover when you get a new Nanos or reset the application a new serial number is generated. But gpg attachs the deviced-key to the card serial, avoiding changing the card (I think it's a bad design choice).

So what are the solution.

The following step should be done via a script (based on BETA python gpgcard lib provided in pytools/gpgcard/)

A similar procedure is available with backup/restore scripts provided in pytools/gpgcard. After your first generation, make a bakup, only public info are stored. When you want to restore your key make a restore with second parameter set to True to ask regeneration of seeded key. Note those script are beta, in particular you have to mod them to set the correct pin.

A script based on gpg keyring info will be provided with the next version (1.2.0)

Any comments or suggestions are welcome

nyanloutre commented 7 years ago

Thanks ! I didn't know the fingerprint could differ even if you have the same public key.

I will try your scripts today and see if it works

nyanloutre commented 7 years ago

I managed to restore it manually, here is the code for reference :

import binascii

from gpgcard import GPGCard

gpgcard = GPGCard()
gpgcard.connect("pcsc:Ledger")
gpgcard.get_all()

gpgcard.verify_pin(0x81, "123456")
gpgcard.verify_pin(0x83, "12345678")

gpgcard.generate_asym_key_pair(0x80, 0xb600)
gpgcard.generate_asym_key_pair(0x80, 0xb800)
gpgcard.generate_asym_key_pair(0x80, 0xa400)

# Use 'gpg -k --with-subkey-fingerprint' to find fingerprints

sig_fingerprint = b'A3F35A5124D47C3195FF07B7F85D93686A3A9063'
aut_fingerprint = b'9C686F97A39B4A34E0C9D37CDBF45893AB524BBC'
dec_fingerprint = b'E4FE54969060DBF2756FC0EFD8203245E390CAEA'

sig_fingerprint_bin = binascii.unhexlify(sig_fingerprint)
aut_fingerprint_bin = binascii.unhexlify(aut_fingerprint)
dec_fingerprint_bin = binascii.unhexlify(dec_fingerprint)

gpgcard.sig_fingerprints = sig_fingerprint_bin
gpgcard.aut_fingerprints = aut_fingerprint_bin
gpgcard.dec_fingerprints = dec_fingerprint_bin

gpgcard.set_all()
cslashm commented 7 years ago

Thanks for sharing this happy end :) An interactive script and a doc update will be provided.

Mansarde commented 6 years ago

I just played around with the seeded mode and can for the life of me not figure something out.

This is what I tried, multiple times:

  1. Generate keys on the ledger in seeded mode, storing a copy in the gpg keyring.
  2. Make note of all the IDs, keygrips and fingerprints of all keys (incl. subkeys) of the keys on the ledger as well as the copy on disk (which match the ones on the ledger).
  3. Encrypt a simple text file to myself.
  4. Decrypt the file again, which prompts for the PIN, after which the text is successfully deciphered.
  5. Run "python3 ./backup.py" to create a backup.

Now I wipe the keys from the ledger via reset in the ledger's gnupg app, followed by these steps:

  1. Enable seed mode and set the template
  2. Execute "python3 ./restore.py"
  3. Now I list the card status and can see that all the IDs, keygrips and fingerprints, as well as the serial number all match with the values before the reset.
  4. I try to decrypt the previously encrypted text file, but it fails with the message: gpg: decryption failed: No secret key

I don't understand, shouldn't everything be as it was before the reset? I also tried re-plugging the ledger, killing the gpg-agent and retrying the decryption, etc. But it's always as if either the restore-script didn't restore everything, or the backup-script didn't backup everything. Even though the card-status is identical to before the reset.

I then tried the script from @nyanloutre (with adjusted PINs and fingerprints), but to no avail.

What exactly is the procedure to backup and restore the card data in seed mode?

nyanloutre commented 6 years ago

@Mansarde it will not work if you use the 1.2.1 version and the 1.4.2 firmware due to this bug :

https://github.com/LedgerHQ/blue-app-openpgp-card/issues/29