Page MenuHome GnuPG

Kleopatra: gpgsk file contains shadowed private key
Closed, DuplicatePublic


When moving a subkey to a token there is the new option to "Create Backup an Delete key". When I choose this a gpgsk file is created.
But instead of a protected key the file contains a shadowed key:

With gpg4win 4.1.0 it works as expected for me.



Event Timeline

ikloecker added a subscriber: ikloecker.

Kleopatra simply copies the content of the corresponding *.key file in the private-keys-v1.d folder. If the *.key file contains a shadowed key after issuing a KEYTOCARD --force [...] command followed by a SCD LEARN --force command (note the SCD!), then gpg-agent is to blame.

werner edited projects, added gnupg22; removed gnupg.

So as I understand this:

  • GnuPG 2.4 and older versions of GnuPG 2.2 left the protected-private-key in the key file after the issued commands by kleopatra
    • When the user (or gpgol / kleopatra) issued a gpgsm --learn-card with these versions the protected-private-key was replaced by the shadow key -> So keeping it was never really an option as the "real" key could be replaced by the shadow key at any time.
  • GnuPG 2.2.41 (at least) now more agressively tries to detect smartcards and replaces the shadow key after the keytocard.

The documentation for keytocard, at least for edit-key says:

Transfer the selected secret subkey (or the primary key if no subkey has been selected) to a smartcard. The secret key in the keyring will be replaced by a stub if the key could be stored successfully  on  the
card  and you use the save command later. Only certain key types may be transferred to the card. A sub menu allows you to select on what card to store the key. Note that it is not possible to get that key back
from the card - if the card gets broken your secret key will be lost unless you have a backup somewhere.

Since the behavior of 2.2.41 is what is documented in the man page it is my understanding that basically the current code in Kleopatra relies on a bug which has been fixed in GnuPG 2.2
So we should fix this in Kleopatra and ask if the user wants a backup before issuing the keytocard and remove the option for the user to delete / keep the private key file because gnupg always deletes it.

Arguing with the documentation of a functionality Kleopatra doesn't make use of makes no sense. Kleopatra uses gpg-agent's "KEYTOCARD" command which, unfortunately, lacks a good documentation.

Moreover, I want to stress that the cited documentation reads if [...] and you use the save command later. So, if you quit without saving the secret key in the keyring shouldn't be replaced by a stub.

Well it makes sense to me in that KEYTOCARD explicitly is not documented but the semantics between keytocard in edit key and KEYTOCARD in agent should be the same IMO. As you can imagine I am also not a fan of the fact that GnuPG changed behavior here, but the "keep / delete" is even with GnuPG 2.3 not really an option as GnuPG might replace the real key with the stub depending on how it is called anyhow. So this is dangerous for us to "suggest" from the UI that the key will be kept and then it might be removed without actions by Kleopatra. So this must be changed.

And if making the backup before issuing keytocard is safer and works across all versions, what is the Problem with that? Even if KEYTOCARD fails, worst case there is another copy of the secret subkey somewhere in the file system.

I have analyzed the problem. It is caused by a serious regression in gpg 2.2:

KEYTOCARD was never intended to move a key to a card and, in fact, it doesn't do so. This can be easily checked by quitting --edit-key without saving after using KEYTOCARD.

I thought about this related to T6386 and I now agree with @ikloecker KEYTOCARD in SCD may not "move" the key. Otherwise it would be impossible to easily transfer a key to multiple smartcards. Since werner agreed in T6486 that this is a Bug and Unintended it can be closed as a duplicate as we do not need to further discuss this.

FWIW:The assuan keytocard does not move the key - what you see is a side effect from unrelated code.