writecert fails for ECC keys on PIV cards
Closed, ResolvedPublic

Description

I basically followed the notes on PIV in the manual page of gpg-card except that I generated a nistp256 key instead of an rsa2048 key for the digital signature key, i.e. PIV.9C.

gpg/card> generate --force --algo=nistp256 PIV.9C                      
PIV card no. yk-9074582 detected
gpg/card> list
Reader ...........: 1050:0407:X:0
Card type ........: yubikey
Card firmware ....: 5.1.2
Serial number ....: FF020001008A7796
Application type .: PIV
Version ..........: 1.0
Displayed s/n ....: yk-9074582
PIN usage policy .: app-pin
PIN retry counter : - [verified] - [?]
PIV authentication: EB6A99D61EF3BC7C7934173CD9833376D773E65D
      keyref .....: PIV.9A  (auth)
      algorithm ..: nistp256
Card authenticat. : 2AD7D08C11E0B8C98FC7BE87A7116427AD589F28
      keyref .....: PIV.9E  (auth)
      algorithm ..: nistp256
Digital signature : 541CF278539F78656A5B0176C75D5CAD58A26736
      keyref .....: PIV.9C  (sign,cert)
      algorithm ..: nistp256
Key management ...: ED6579C1360100BE92C46ECB1A1826A63614D5AB
      keyref .....: PIV.9D  (encr)
      algorithm ..: rsa2048
      used for ...: X.509
        user id ..: CN=Encryption key for yk-9074582,O=example,C=DE
        user id ..: <otto@example.net>
gpg/card>

After generating a self-signed certificate as described on the man page the attempt to write this certificate to the card failed.

$ gpg-card 
Reader ...........: 1050:0407:X:0
Card type ........: yubikey
Card firmware ....: 5.1.2
Serial number ....: FF020001008A7796
Application type .: PIV
Version ..........: 1.0
Displayed s/n ....: yk-9074582
PIN usage policy .: app-pin
PIN retry counter : - [verified] - [?]
PIV authentication: EB6A99D61EF3BC7C7934173CD9833376D773E65D
      keyref .....: PIV.9A  (auth)
      algorithm ..: nistp256
Card authenticat. : 2AD7D08C11E0B8C98FC7BE87A7116427AD589F28
      keyref .....: PIV.9E  (auth)
      algorithm ..: nistp256
Digital signature : 541CF278539F78656A5B0176C75D5CAD58A26736
      keyref .....: PIV.9C  (sign,cert)
      algorithm ..: nistp256
      used for ...: X.509
        user id ..: CN=Signing key for yk-9074582,O=example,C=DE
        user id ..: <otto@example.net>
Key management ...: ED6579C1360100BE92C46ECB1A1826A63614D5AB
      keyref .....: PIV.9D  (encr)
      algorithm ..: rsa2048
      used for ...: X.509
        user id ..: CN=Encryption key for yk-9074582,O=example,C=DE
        user id ..: <otto@example.net>

gpg/card> writecert PIV.9C < /home/ingo/dev/g10/sign-nistp256-541CF278539F78656A5B0176C75D5CAD58A26736.crt
Command 'writecert' failed: Conflicting use
gpg/card> 

I have traced down the problem. In do_writecert() (app-piv.c) the public key in the certificate is compared with the public key on the card. The problem is that the representation of the curve differs in the two S-expressions of the public key:

2020-09-10 15:05:54 scdaemon[12280] DBG: orig_pk: (public-key \n (ecc \n  (curve nistp256)\n  (q #0464ED1D5259833306831FE802E8487F5F5C879ACF671A2DD0A5C134CAC08F66D1429A27BCAFE41042E8A1ECDE2594270CB675D99AF704344ADE9344EA7350A4CD#)\n  )\n )\n
2020-09-10 15:05:54 scdaemon[12280] DBG:      pk: (public-key \n (ecc \n  (curve "1.2.840.10045.3.1.7")\n  (q #0464ED1D5259833306831FE802E8487F5F5C879ACF671A2DD0A5C134CAC08F66D1429A27BCAFE41042E8A1ECDE2594270CB675D99AF704344ADE9344EA7350A4CD#)\n  )\n )\n
2020-09-10 15:05:54 scdaemon[12280] operation writecert result: Conflicting use

I see that genkey_parse_ecc(), that is used via do_readkey() to read the public key from the card, uses "nistp256" for the curve. OTOH, app_help_pubkey_from_cert() (using ksba_cert_get_public_key()) uses the OID for the curve.

werner added a subscriber: werner.Thu, Sep 10, 5:21 PM

Are you using libgcrypt 1.8 or master (to be 1.9)?

werner claimed this task.Fri, Sep 11, 9:11 AM

I had a quite old master of libgcrypt (probably from August 2). I'll update everything to master an retest.

Still reproducible with current master of everything.

werner closed this task as Resolved.Sun, Sep 13, 4:32 PM