Yubico/yubico-piv-tool

Can't delete an object with libykcs11

rvdgracht opened this issue · 4 comments

Hi,

I'm unable to delete an existing private/public key from my Yubikey 5C with the pkcs11-tool.
I can import (and overwrite) a key with the same ID throught the yubico-piv-tool.

The command I used:
pkcs11-tool --module /usr/lib/libykcs11.so.2 -l --delete-object --id 01 -y privkey --login-type so --so-pin 010203040506070801020304050607080102030405060708

I'm using ykcs11 from yubico-piv-tool version 2.3.0

I forgot to mention the command completes without warnings and/or errors and has return code 0 but the key is still listed pkcs11-tool --module /usr/lib/libykcs11.so.2 -l -O

The reason for this is that libykcs11 only deletes the certificate, not the private key. Piv has separate objects for those. The reason for that is that there is no way to delete a private key after it has been imported or generated, The best that can be done is to overwrite the key by importing or generating a new one, which of course still leaves a key in that slot. The only way to make a slot empty again is to reset the whole piv application, thereby erasing all keys.

The ohter part of the equation is that libykcs11, unlike most piv tools (including the status command of yubico-piv-tool), lists private keys via the Yubico extensions attestation or metadata. It does that to accurately present the public key that corresponds to the private key in the slot, not the public key in the certificate, which might be the wrong one if it has been mis-provisioned.

You should notice that any certificate you had provisioned for that slot is gone after the above operation. So while perhaps unexpected it does in fact reflect the real status of piv. You can still technically use the key.

I see. Maybe it's usefull to inform the user about this when deleting a key with explicit type 'privkey' instead of deleting a certificate with the same ID since that's indeed unexpected. I would expect ykcs11 to delete the certificate if type 'cert' is supplied (-y cert).

Partly this is a leftover from earlier versions that didn't use attestation / metadata. Before that was supported by the YubiKey there was no way to determine if there was a key in a key slot (short of trying to use it) so the certificate object was used as an indicator of both private key, public key and certificate (ykcs11 also presents a data object so that the full contents of the data object can be read, the certificate is parsed out of that). Most tools still use that logic, and in many cases there is no distinction made, both key and certificate are called 'the certificate'. With that background the C_DestroyObject implementation, as a best effort, deletes the certificate object whether you delete the private key, public key, certificate or data object. Since the search for objects is now based on attestation / metadata doing this again will fail for certificates or data objects (as they can't be found, not because they can't be deleted) but not for private key or public key.
So in short, this is a best effort to shoehorn piv into the pkcs#11 abstraction.