GnuPG: Make quick-gen-key work for keys on PIV cards
Open, Needs TriagePublic

Description

To create an OpenPGP key from the keys on a PIV card in Kleopatra I need quick-gen-key to work for PIV cards. Currently,

$ gpg --quick-gen-key --yes piv@example.net card

fails with

gpg: Serial number of the card: FF020001008A7796
gpg: Serial number of the card: FF020001008A7796
Key generation failed: No such file or directory

I think that's because quick_generate_keypair() makes the assumption

/* If KEYTIME is set we know that the key has been taken from the
 * card.  Store that flag in the parameters.  */
if (keytime)
  {
    r = xmalloc_clear (sizeof *r);
    r->key = pCARDKEY;
    r->u.abool = 1;
    r->next = para;
    para = r;
  }

For keys on PIV cards this assumption is wrong because those keys do not have a keytime.

After patching the above mentioned if-clause the command fails on the first try, but it succeeds on the second try

$ gpgconf --kill all

$ gpg --quick-gen-key --yes piv@example.net card
gpg: NOTE: THIS IS A DEVELOPMENT VERSION!
gpg: It is only intended for test purposes and should NOT be
gpg: used in a production environment or with production keys!
gpg: Serial number of the card: FF020001008A7796
gpg: Serial number of the card: FF020001008A7796
gpg: signing failed: Not implemented
gpg: make_keysig_packet failed: Not implemented
Key generation failed: Not implemented

$ gpg --quick-gen-key --yes piv@example.net card
gpg: NOTE: THIS IS A DEVELOPMENT VERSION!
gpg: It is only intended for test purposes and should NOT be
gpg: used in a production environment or with production keys!
gpg: Serial number of the card: FF020001008A7796
gpg: Serial number of the card: FF020001008A7796
gpg: key BF29AD0114BC3181 marked as ultimately trusted
gpg: revocation certificate stored as '.../openpgp-revocs.d/891EB64322A32591DB77A37FBF29AD0114BC3181.rev'
public and secret key created and signed.

pub   nistp256 2020-11-17 [SC] [expires: 2022-11-17]
      891EB64322A32591DB77A37FBF29AD0114BC3181
uid                      piv@example.net
sub   rsa2048 2020-11-17 [E]

The generated key is listed as

$ gpg -K --with-fingerprint --with-fingerprint --with-keygrip '&0773CFCB90C043F3A6151B3F2FBF23726F10A48A'
gpg: NOTE: THIS IS A DEVELOPMENT VERSION!
gpg: It is only intended for test purposes and should NOT be
gpg: used in a production environment or with production keys!
gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   8  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 8u
gpg: next trustdb check due at 2022-08-31
sec>  nistp256 2020-11-17 [SC] [expires: 2022-11-17]
      891E B643 22A3 2591 DB77  A37F BF29 AD01 14BC 3181
      Keygrip = 0773CFCB90C043F3A6151B3F2FBF23726F10A48A
      Card serial no. = FF020001008A7796
uid           [ultimate] piv@example.net
ssb#  rsa2048 2020-11-17 [E]
      09A2 2E65 E041 66F5 3F33  F5C4 8EAF B912 17DC CA84
      Keygrip = ED6579C1360100BE92C46ECB1A1826A63614D5AB

I'm not sure, but shouldn't the encryption subkey also be listed as card key instead of as stub?

ikloecker removed ikloecker as the assignee of this task.Wed, Nov 18, 9:37 AM
ikloecker raised the priority of this task from Normal to Needs Triage.

Yes sure. --debug ipc should give you some insight why gpg does not thing the key is on the card.

Output of (unpatched) gpg with --debug ipc:

$ GNUPGHOME=$HOME/.cache/gnupg-master-home gpg --debug ipc --quick-gen-key --yes piv@example.net card
gpg: reading options from '[cmdline]'
gpg: NOTE: THIS IS A DEVELOPMENT VERSION!
gpg: It is only intended for test purposes and should NOT be
gpg: used in a production environment or with production keys!
gpg: enabled debug flags: ipc
gpg: DBG: chan_3 <- OK Pleased to meet you, process 7588
gpg: DBG: connection to the gpg-agent established
gpg: DBG: chan_3 -> RESET
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION ttyname=/dev/pts/7
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION ttytype=xterm-256color
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION display=:0
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION xauthority=/home/ingo/.Xauthority
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION putenv=XMODIFIERS=@im=local
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION putenv=GTK_IM_MODULE=cedilla
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION putenv=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION putenv=QT_IM_MODULE=xim
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION lc-ctype=de_DE.UTF-8
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION lc-messages=de_DE.UTF-8
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> GETINFO version
gpg: DBG: chan_3 <- D 2.3.0-beta1481
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION allow-pinentry-notify
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION agent-awareness=2.1.0
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> SCD SERIALNO
gpg: DBG: chan_3 <- S SERIALNO FF020001008A7796
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> SCD SERIALNO
gpg: DBG: chan_3 <- S SERIALNO FF020001008A7796
gpg: DBG: chan_3 <- OK
gpg: Serial number of the card: FF020001008A7796
gpg: DBG: chan_3 -> SCD LEARN --keypairinfo
gpg: DBG: chan_3 <- S CHV-USAGE 40 00
gpg: DBG: chan_3 <- S CHV-STATUS -2 3 -2
gpg: DBG: chan_3 <- S KEYPAIRINFO EB6A99D61EF3BC7C7934173CD9833376D773E65D PIV.9A a
gpg: DBG: chan_3 <- S KEYPAIRINFO 482BD076054B6950A6FC476C356AF029A5115BBD PIV.9E a
gpg: DBG: chan_3 <- S KEYPAIRINFO 0773CFCB90C043F3A6151B3F2FBF23726F10A48A PIV.9C sc
gpg: DBG: chan_3 <- S KEYPAIRINFO ED6579C1360100BE92C46ECB1A1826A63614D5AB PIV.9D e
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> SCD GETATTR $SIGNKEYID
gpg: DBG: chan_3 <- S $SIGNKEYID PIV.9C
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> SCD READKEY --info -- PIV.9C
gpg: DBG: chan_3 <- S KEYPAIRINFO 0773CFCB90C043F3A6151B3F2FBF23726F10A48A PIV.9C sc - nistp256
gpg: DBG: chan_3 <- [ 44 20 28 31 30 3a 70 75 62 6c 69 63 2d 6b 65 79 ...(118 byte(s) skipped) ]
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> SCD SERIALNO
gpg: DBG: chan_3 <- S SERIALNO FF020001008A7796
gpg: DBG: chan_3 <- OK
gpg: Serial number of the card: FF020001008A7796
gpg: DBG: chan_3 -> SCD LEARN --keypairinfo
gpg: DBG: chan_3 <- S CHV-USAGE 40 00
gpg: DBG: chan_3 <- S CHV-STATUS -2 3 -2
gpg: DBG: chan_3 <- S KEYPAIRINFO EB6A99D61EF3BC7C7934173CD9833376D773E65D PIV.9A a
gpg: DBG: chan_3 <- S KEYPAIRINFO 482BD076054B6950A6FC476C356AF029A5115BBD PIV.9E a
gpg: DBG: chan_3 <- S KEYPAIRINFO 0773CFCB90C043F3A6151B3F2FBF23726F10A48A PIV.9C sc
gpg: DBG: chan_3 <- S KEYPAIRINFO ED6579C1360100BE92C46ECB1A1826A63614D5AB PIV.9D e
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> SCD GETATTR $ENCRKEYID
gpg: DBG: chan_3 <- S $ENCRKEYID PIV.9D
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> SCD READKEY --info -- PIV.9D
gpg: DBG: chan_3 <- S KEYPAIRINFO ED6579C1360100BE92C46ECB1A1826A63614D5AB PIV.9D e - rsa2048
gpg: DBG: chan_3 <- [ 44 20 28 31 30 3a 70 75 62 6c 69 63 2d 6b 65 79 ...(286 byte(s) skipped) ]
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> RESET
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> READKEY -- 0773CFCB90C043F3A6151B3F2FBF23726F10A48A
gpg: DBG: chan_3 <- ERR 67141713 No such file or directory <GPG Agent>
Key generation failed: No such file or directory
gpg: secmem usage: 0/32768 bytes in 0 blocks
werner claimed this task.Fri, Nov 20, 9:27 AM

The same problem occurs for NKS (v3) cards where the keys also do not have a keytime.