[continued from part I]
Returning to the problem of provisioning a PIV card given the PIV administrator key, we can now enlist the help of open source solutions. The venerable OpenSC suite includes a piv-tool utility for performing administrative operations on PIV cards. One cautionary warning: this approach is only suitable for very primitive key-management schemes. In an enterprise-grade credential management system, card keys would typically be diversified using a cryptographic function, where each card has a different administrator key that is computed as a cryptographic function of some master secret and an immutable property of the card, such as its serial ID. In high security applications that master secret is relegated to a hardware-security module, leaving the provisioning system only handling individual card keys. (For an additional level of paranoia, one can implement the entire PIV administrator authentication challenge-response in the HSM itself, with no keys ever relinquished outside the secure execution environment.)
piv-tool takes a slightly more cavalier attitude about where administrator keys come from: a local file. Assuming that one is willing to live with this approach to key management, here is how key generation would work:
- Save the PIV card administrator key to a local file. The format is similar to how GoldKey client UI accepts keys, with one cosmetic difference: each hex byte is separated by a column character.
$ cat admin_key 01:02:03:04:05:06:07:08:01:02:03:04:05:06:07:08:01:02:03:04:05:06:07:08
- Export the name of the file containing the key into a specific environment variable.
$ export PIV_EXT_AUTH_KEY=./admin_key
- Invoke piv-tool with the “-A” option to authenticate as administrator and “-G” option to generate keys:
$ piv-tool -A A:9B:03 -G 9C:07
In this example, the highlighted option indicates generating a new signature-key, identified by key reference 0x9C as defined in NIST 800-78 part 3 of type 2048-bit RSA, which is algorithm reference 07 also defined in the same standard. The first option indicates administrator authentication, using key ID 0x9B of type 3DES; this is a function of the card configuration, which users typically have little control over. Note that contrary to what one might optimistically assume about extensibility, PIV does not allow generating keys over arbitrary named curves or curves with user-defined parameters.
The command will trigger key-generation on the token and then output a binary encoding of the public half. It is easier to make sense of that output by having openssl parse the ASN1. For example, here is another example for generating a new ECDSA signature key over the NIST P256 curve (also known as prime256v1) which happens to be algorithm reference 11:
$ piv-tool -A A:9B:03 -G 9C:11 | openssl asn1parse -inform DER -i -dump Using reader with a card: GoldKey PIV Token 00 00 0:d=0 hl=2 l= 89 cons: SEQUENCE 2:d=1 hl=2 l= 19 cons: SEQUENCE 4:d=2 hl=2 l= 7 prim: OBJECT :id-ecPublicKey 13:d=2 hl=2 l= 8 prim: OBJECT :prime256v1 23:d=1 hl=2 l= 66 prim: BIT STRING 0000 - 00 04 78 95 ac 64 63 7f-9d 4d a8 b5 5d 2f 36 27 ..x..dc..M..]/6' 0010 - bf 73 6e fc ee bf de 29-6f ca 06 ee 85 a9 c5 42 .sn....)o......B 0020 - 83 cf 12 3f eb f6 ff eb-0a a8 78 f4 de 68 40 a4 ...?......x..h@. 0030 - 87 c9 81 2d 06 f0 5b 9b-a5 64 46 b5 12 3e 61 55 ...-..[..dF..>aU 0040 - 99 09
It is helpful to save the public-key because this is one of the few times it will be available directly. There is no APDU to retrieve a public-key in PIV. In steady state, the public-key exists in a certificate already loaded on the card; except that we have not yet obtained that certificate. (In some cases it is possible to indirectly recover the public-key. For example assuming a valid ECDSA signature on a known message, public key can be derived as implemented in Bitcoin libraries.)
Next: generating a certificate-signing request, which runs into an interesting circularity with the OpenSC middleware.