Off-and-on over the last several weeks, I've been spending time trying to learn/understand YubiKeys better, especially from the perspective of ECDSA and signing. π
I had a good mental model for how "slots" work (canonically referenced by their hexadecimal names such as 9C
), but found that it had a gap related to "objects"; while closing that, I was annoyed that the main reference table for this gap lives primarily in either a PDF or inside several implementations, so I figured I should create the reference I want to see in the world, but that it would also be useful to write down some of my understanding for my own (and maybe others') future reference. π
So, to that end, I'm going to start with a bit (β) of background information, with the heavy caveat that this only applies to "PIV" ("FIPS 201") usage of YubiKeys, and that I only actually care about ECDSA, although I've been reassured that it's the same for at least RSA (anything outside this is firmly Here Be Not Tianon; "gl hf dd"). π
(Incidentally, learning all this helped me actually appreciate the simplicity of cloud-based KMS solutions, which was an unexpected side effect. π¬)
At a really high level, ECDSA is like many other (asymmetric) cryptographic solutions β you've got a public key and a private key, the private key can be used to "sign" data (tiny amounts of data, in fact, like P-256 can only reasonably sign 256 bits of data, which is where cryptographic hashes like SHA256 come in as secure analogues for larger data in small bit sizes), and the public key can then be used to verify that the data was indeed signed by the private key, and only someone with the private key could've done so. There's some complex math and RNGs involved, but none of that's actually relevant to this post, so find that information elsewhere. π
Unfortunately, this is where things go off the rails: PIV is X.509 ("x509") heavy, and there's no X.509 in the naΓ―ve view of my use case. π
In a YubiKey (or any other PIV-signing-supporting smart card? do they actually have competitors in this specific niche? π€), a given "slot" can hold one single private key. There are ~24 slots which can hold a private key and be used for signing, although "Slot 9c" is officially designated as the "Digital Signature" slot and is encouraged for signing purposes. πβ
One of the biggest gotchas is that with pure-PIV (and older YubiKey firmware π€¬) the public key for a given slot is only available at the time the key is generated, and the whole point of the device in the first place is that the private key is never, ever available from it (all cryptographic operations happen inside the device), so if you don't save that public key when you first ask the device to generate a private key in a particular slot, the public key is lost forever (asterisk). π
$ # generate a new ECDSA P-256 key in "slot 9c" ("Digital Signature")
$ # WARNING: THIS WILL GLEEFULLY WIPE SLOT 9C WITHOUT PROMPTING
$ yubico-piv-tool --slot 9c --algorithm ECCP256 --action generate
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEtGoWRGyjjUlJFXpu8BL6Rnx8jjKR
5+Mzl2Vepgor+k7N9q7ppOtSMWefjFVR0SEPmXqXINNsCi6LpLtNEigIRg==
-----END PUBLIC KEY-----
Successfully generated a new private key.
$ # this is the only time/place we (officially) get this public key
With that background, now let's get to the second aspect of "slots" and how X.509 fits. For every aforementioned slot, there is a corresponding "object" (read: place to store arbitrary data) which is corresponding only by convention. For all these "key" slots the (again, by convention) corresponding "object" is explicitly supposed to be an X.509 certificate (see also the PDF reference linked above). π
It turns out this is a useful and topical place to store that public key we need to keep handy! It's also an interesting place to shove additional details about what the key in a given slot is being used for, if that's your thing. Converting the raw public key into a (likely self-signed) X.509 certificate is an exercise for the reader, but if you want to follow the conventions, you need some way to convert a given "slot" to the corresponding "object", and that is the lookup table I wish existed in more forms. π³
So, without further ado, here is the anti-climax: π«
Slot | Object | Description |
---|---|---|
0x9A |
0x5FC105 |
X.509 Certificate for PIV Authentication |
0x9E |
0x5FC101 |
X.509 Certificate for Card Authentication |
0x9C |
0x5FC10A |
X.509 Certificate for Digital Signature |
0x9D |
0x5FC10B |
X.509 Certificate for Key Management |
0x82 |
0x5FC10D |
Retired X.509 Certificate for Key Management 1 |
0x83 |
0x5FC10E |
Retired X.509 Certificate for Key Management 2 |
0x84 |
0x5FC10F |
Retired X.509 Certificate for Key Management 3 |
0x85 |
0x5FC110 |
Retired X.509 Certificate for Key Management 4 |
0x86 |
0x5FC111 |
Retired X.509 Certificate for Key Management 5 |
0x87 |
0x5FC112 |
Retired X.509 Certificate for Key Management 6 |
0x88 |
0x5FC113 |
Retired X.509 Certificate for Key Management 7 |
0x89 |
0x5FC114 |
Retired X.509 Certificate for Key Management 8 |
0x8A |
0x5FC115 |
Retired X.509 Certificate for Key Management 9 |
0x8B |
0x5FC116 |
Retired X.509 Certificate for Key Management 10 |
0x8C |
0x5FC117 |
Retired X.509 Certificate for Key Management 11 |
0x8D |
0x5FC118 |
Retired X.509 Certificate for Key Management 12 |
0x8E |
0x5FC119 |
Retired X.509 Certificate for Key Management 13 |
0x8F |
0x5FC11A |
Retired X.509 Certificate for Key Management 14 |
0x90 |
0x5FC11B |
Retired X.509 Certificate for Key Management 15 |
0x91 |
0x5FC11C |
Retired X.509 Certificate for Key Management 16 |
0x92 |
0x5FC11D |
Retired X.509 Certificate for Key Management 17 |
0x93 |
0x5FC11E |
Retired X.509 Certificate for Key Management 18 |
0x94 |
0x5FC11F |
Retired X.509 Certificate for Key Management 19 |
0x95 |
0x5FC120 |
Retired X.509 Certificate for Key Management 20 |
See also "piv-objects.json" for a machine-readable copy of this data. ππ€π»πΎ
(Major thanks to paultag and jon gzip johnson for helping me learn and generally putting up with me, but especially dealing with my live-stream-of-thoughts while I stumble through the dark. π)