The GnuPG blog

Security advisory for GnuPG created smartcard keys

Smartcard generation keeps an unprotected backup key on disk

The standard way to generate keys on a smartcard with GnuPG is to create the encryption subkey with gpg and to move this key to the smartcard. A password protected backup file named sk_<keyid>.gpg is also created so that in the case of a lost or broken smartcard, the key can be restored to a new smartcard to allow decryption of existing data. Unfortunately with some versions of GnuPG an additional unprotected copy of the encryption subkey is also kept on disk.

All possibly affected users should check whether such an unintended copy of a smartcard key exists and delete it.

Who is affected

All users with keys generated by GnuPG on an OpenPGP smartcard might want to check whether they are affected. If the smartcard was created by one of the following software versions, it is highly recommended to check for this flaw and to delete the copy:

  • Gpg4win version 4.2.0
  • GnuPG versions 2.4.2 and 2.4.3 iff the card generation was done with the command gpg --card-edit.
  • GnuPG version 2.2.42 iff the card generation was done with the command gpg --card-edit.
  • GnuPG VS-Desktop version 3.2.0 and 3.2.1 iff the card generation was done with the non-approved command gpg --card-edit. The documented way to create keys on OpenPGP cards and Yubikeys is not affected.

Other versions of GnuPG, Gpg4win, or GnuPG VS-Desktop® are not affected. Further, if the smartcard was created without a backup of the encryption key the problem does not show up either.

How to check with a tool

The best way to check and fix this problem is to use a current GnuPG or Gpg4win version: GnuPG 2.4.4 or Gpg4win 4.3.0.

Insert your smartcard and run

gpg-card checkkeys

If you don't get any output, you are not affected. However, if you get an output like

D27600[...] OpenPGP CDE781[...] OPENPGP.1 shadowed
D27600[...] OpenPGP 3848AF[...] OPENPGP.2 clear
D27600[...] OpenPGP E799F4[...] OPENPGP.3 shadowed

where the second key shows "clear" instead of "shadowed", you are affected and you should delete that unprotected copy of the smartcard key: Run the command

gpg-card checkkeys --delete-clear-copy

which should give you this output

D27600[...] OpenPGP CDE781[...] OPENPGP.1 shadowed
D27600[...] OpenPGP 3848AF[...] OPENPGP.2 clear
D27600[...] OpenPGP E799F4[...] OPENPGP.3 shadowed
gpg-card: Number of deleted key copies: 1

Finally run the first command again to check that the keys are now all "shadowed" (i.e. only the public key and the serial number of the card are stored on disk).

Repeat this procedure for all smartcards.

Note that in certain cases the status "protected" will be shown instead of "clear". This means that the on-disk copy of the smartcard key is protected by a password. If there is no output at all, no keys are stored on the smartcard; either it is a fresh card or a factory reset has been done.

How to manually check

In case the use of the gpg-card tool from GnuPG 2.4.4 is not possible, a manual method can be used to check for the problem.

A quick check can be done by trying to decrypt a file or a mail without having the smartcard inserted. If this works, a copy of the key still exists on disk. This copy should be removed.

With the fingerprint of the smartcard key run:

gpg --with-keygrip -k FINGERPRINT

For example:

$ gpg --with-keygrip -k 0EBCC5BEDA20A62CCAE85DB478A2C4133FE10E98
pub   brainpoolP256r1 2024-01-23 [SC]
      0EBCC5BEDA20A62CCAE85DB478A2C4133FE10E98
      Keygrip = CF6EAB9AA180734AB9E5F282108B8E83D74A28E1
uid           [ultimate] T6944 Test Key
sub   brainpoolP256r1 2024-01-23 [A]
      Keygrip = 47AB5C9128B11E2E44A3BFE00619D64D7F51E4F0
sub   brainpoolP256r1 2024-01-23 [E]
      Keygrip = 98D7F9BC2A20102E26D5A1DD01135A2AE984A922

The encryption key marked with an "[E]" might have a backup key. Take its keygrip and check the actual key file:

cd ~/.gnupg/private-keys-v1.d
cat 98D7F9BC2A20102E26D5A1DD01135A2AE984A922.key

or on Windows

cd %APPDATA%\gnupg\private-keys-v1.d
type 98D7F9BC2A20102E26D5A1DD01135A2AE984A922.key

If this file does not exist or if there is a line commencing with Key: (shadowed-private-key all is fine. However, if there is a line Key: (private-key an unprotected copy of the smartcard key exists. In the latter case move this file away, check whether you can still decrypt with your smartcard, and then overwrite the moved away file with garbage and finally delete it.

Technical details

The actual problem is due to the fact that the gpg-agent creates the key and stores it as usual on disk. After the key has been moved to the smartcard and the protected backup has been written, the original on-disk key is replaced by a shadow-key. Such a shadow-key can always be re-created from a smartcard (for example using gpg-card checkkeys) and is used to prompt the user to insert a certain smartcard.

In the course of fixing a bug in a special smartcard use case (T6386), where a private key was accidentally overwritten by a shadow key, this very bug was introduced. See T6944 for more details.

The manual page for the gpg-card tool can be here: gpg-card.1

Timeline

The first report of this bug was posted to the German GnuPG forum site in March 2023. Unfortunately the real cause of the reported problem was not recognized and thus never made it into our bug tracker or was otherwise brought to our attention. In the course of a review of Kleopatra's smartcard dialog the bug was finally found again in January 2024.

List of all blog entries

Comments

We do not provide a feature to comment on a blog. Instead please send remarks to the gnupg-users mailing list using the blog title for the subject line. This helps to keep the discussion at one place and not to spread it over different media.